Як за допомогою жадібного алгоритму знайти послідовність, що зменшується, найближчу до заданої?


20

Вам дано n цілих чисел всі від до . Під кожним цілим числом слід записати ціле число між і з вимогою, щоб утворював не спадаючу послідовність. Визначте відхилення такої послідовності як . Створіть алгоритм, який знаходить значення b_i з мінімальним відхиленням у процесі виконання O (n \ sqrt [4] {l}) . 0 l a i b i 0 l b i max ( | a 1 - b 1 | , , | a n - b n | ) b i O ( n 4 a1,,an0laibi0lbimax(|a1b1|,,|anbn|)biO(nl4)

Я, чесно кажучи, не маю поняття, як взагалі почати вирішувати це питання. Для мене це виглядає як питання динамічного програмування, але професор сказав, що це слід вирішити за допомогою жадібного алгоритму. Було б дуже вдячно, якщо хтось може направити мене в правильному напрямку, давши невелику підказку.

Відповіді:


9

Почнемо з наступного спостереження:

Нехай позначає максимум послідовності , а позначає його мінімум. Якщо , то вибір є оптимальним.з 1 , . . . , a n m i n a 1 = m a x b 1 = b 2 = . . . = b n = ( m a x + m i n ) / 2 maxa1,...,anmina1=maxb1=b2=...=bn=(max+min)/2

Чому це так? Отже, оскільки послідовність починається з максимуму, ми або вибираємо великі, і зазнаємо великого відхилення від мінімуму послідовності (оскільки будь-який наступний повинен бути більшим або рівним ), або ми вибираємо малий і страждаємо від відхилення до . Середнє значення мінімізує максимальне відхилення.b i b 1 b 1 m a xb1bib1b1max

Тепер ми можемо спробувати узагальнити це спостереження для використання на загальних послідовностях . Наприклад, ми можемо розділити будь-яку послідовність на послідовності, так що кожна починається з максимуму відповідної послідовності.a1,...,an

Приклад: на , та .( 2 ) ( 6 , 4 , 1 , 5 , 2 ) ( 8 , 7 , 5 , 1 )(2,6,4,1,5,2,8,7,5,1)(2)(6,4,1,5,2)(8,7,5,1)

Враховуючи цей розділ, тепер ми можемо вирішувати кожну ці послідовності окремо і отримувати призначення , що, однак, може порушити умову, що не зменшується. Це можна виправити, не втрачаючи оптимальності.bi

Зауважте, що остання підряд завжди містить максимум всієї послідовності (інакше після неї буде інша послідовність). Нехай - значення, які ми присвоїли послідовностям. Тепер, щоб досягти зменшення в , ми починаємо з тилу і працюємо на фронт. Якщо більше, ніж , ми просто встановлюємо . Якщо вона менша, ми зберігаємо її. Потім переходимо до порівняння з і так далі. Зауважте, що зниження будь-якого до значенняmaxw1,w2,...,wkkw1,...,wkwkwk1wkwk1:=wkwk2wk1wiwi+1ніколи не збільшує відхилення, оскільки значення максимуму в присвоєній , завжди нижче максимального в присвоєній .wiwi+1

Цей алгоритм повинен бути правильним, я думаю. Щодо часу виконання, ключовим кроком є ​​обчислення зростаючих максимумів для підрядів, що можливо в ? Не впевнений, куди вносить свій внесок.O(n)l


2

Я збираюся подумати тут голосно, просто опрацьовуючи наведені вами підказки. Перейдемо до оригінальної підказки сказати, що - це те, що ви повинні спробувати спочатку. Я можу придумати жадібний алгоритм, який є на той час.O(nl)

частину часу складність означає , що ви можете зберегти список підрахунку кожного збігу кожного значення 0 .. л . Це, просто створити множину Count = C 0 , , C l, яка відстежує кількість кожного l у множині. Ви можете створити список ініціалізації, сканувавши послідовність введення один раз.l0..lCount=C0,,Cll

Ви можете сканувати цей список у щоб отримати максимальне та мінімальне значення. Якби ви заповнили весь список b цією середньою точкою, ваша відмінність буде просто різницею від цього значення та max / min. Це в основному ваш найгірший сценарій, давайте назвемо це b w .O(l)bbw

Тож працюй свій шлях до зліва. Ви можете опустити цей елемент із Count та отримати min / max b [ i + 1 ] b [ n ] в O ( l ) . Тепер ми можемо бути жадібними. Ми не обираємо b i > b w, оскільки це змушує залишитися весь список (щоб відповідати вимозі, що не зменшується) і тим самим збільшує дисперсію. Мінімальне значення, яке ми можемо вибрати, є b [ i - 1 ] . Якщо a ibiCountb[i+1]b[n]O(l)bi>bwb[i1]aiзнаходиться у прийнятному діапазоні, ми його вибираємо, якщо нижче діапазону, ніж використовуємо мінімум. Це мінімізує дисперсію при відомими обмеженнями.bi

Це просто ідея, можливо, мені пощастило, і вона вказує на вас у правильному напрямку. Цей алгоритм може не працювати (він працює для моїх декількох простих тестів), але він відповідає наведеним підказкам, тому, можливо, він корисний. Якщо правильно, неважко помітити, що частина точно може бути скинута на O ( log l ) , приблизно ще далі, я не впевнений.O(l)O(logl)


2

Ось рішення професора, яке він називає "скороченням": Для кожного від 0 до l спробуйте побудувати рішення, якщо ми знаємо, що відхилення менше або дорівнює i . Перше i, для якого можна знайти рішення, - це мінімальне відхилення. Ми можемо знайти рішення, враховуючи відхилення в O ( n ) час. Отже, час роботи - O ( n l ) . Тоді, замість лінійного пошуку, ми можемо використовувати двійковий пошук, щоб визначити найменше відхилення, для якого можливе рішення. Це скорочує час роботи до O ( n log li0liiO(n)O(nl) , що задовольняє вимогу O ( n 4 O(nlogl).O(nl4)


4
Отже була хитрість ... Але мене більше заінтригує "Ми можемо знайти рішення, враховуючи відхилення в O (n) час" .. як ценецікава частина? O(nl4)
jmad

@jmad не враховуючи , для кожного J , взяти б J як найменше значення, щонайменше , настільки ж великий , як і всі попередні б до і що ні більше , ніж я від в J . Якщо ми не можемо знайти таку цінність, що це означає? Це означає , що попередній б т більше , ніж я більше , ніж в J . Таким чином, попередня т більше , ніж 2 I більше , ніж в J . Тож значення мені було неможливо. Якщо дістатися через нijbjbkiajbtiajat2iajinЗначення, не зациклюючись на цьому, ви знайшли рішення для без зворотного відстеження, за часом O ( n ) . iO(n)
jwg

O (n log l) був би сильним натяком на те, що вам потрібно виконати деякий двійковий пошук у межах від 0 до l.
gnasher729

0

Я думаю, що це слід зробити в O (n).

Візьміть аналогічну задачу: З огляду на , 1 ≤ i ≤ n та d ≥ 0, знайдіть b i в порядку, що не спадає, таким, що | a i - b i | d для всіх i, або показати, що це неможливо. Це можна зробити в O (n), а за допомогою двійкового пошуку вихідна задача вирішується в O (n log l).aibi|aibi|d

Тепер якщо є i ≤ j такий, що a_i - a_j> 2d, то рішення немає (тому що ).biaid,bjaj+d<ai2d+d=aidbi

Але якщо a_i - a_j ≤ 2d для всіх i ≤ j, я думаю, що рішення завжди знайдеться. Отже, все, що нам потрібно зробити, - знайти m = max (a_i - a_j) для всіх i ≤ j, і вибрати d = пол ((m + 1) / 2). Цей максимум можна знайти в O (n).


Інтригуюча ідея! Я можу повірити, що щось подібне може спрацювати, але здається, що в кінці вашої відповіді великий розрив, і мені важко заповнювати деталі. Чи є у вас доказ того, що якщо для всіх i j, то рішення завжди існує? Що ще важливіше, як ми його знаходимо? Оригінальне запитання говорить, що ми повинні знайти b i 's. Навіть якщо ми припускаємо, що рішення існує, мені важко зрозуміти, як знайти відповідні b i 's. Чи можете ви детальніше розглянути це? aiaj2dijbibi
DW
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.