Ефективне введення в список, зберігаючи кількість інверсій мінімальною


15

Припустимо два списки порівняних предметів: u та s. Нехай INV (u) - кількість перетворень u.

Я шукаю ефективний алгоритм для вставки елементів s в u з мінімальним збільшенням INV (u).

В основному я хотів би вставити об'єкти до списку, зберігаючи його "якомога більше сортованим", зберігаючи порядок першого списку.

Приклад:

u = [4,6,2,9,7]
INV(u) = 3 ((4, 2), (6, 2) and (9, 7)

s = [8,3,10]

one optimal solution u' = [3, 4, 6, 2, 8, 9, 7, 10]
INV(u') = 5 ((4, 2), (7, 2) and (9, 7) + (3,2), (8,7))

different optimal solution u' = [3, 4, 6, 2, 9, 7, 8, 10]
INV(u') = 5 ((4, 2), (7, 2) and (9, 7) + (3,2), (9,8))

Як бачите, не існує єдиного оптимального рішення.

Я буду радий будь-яким ідеям чи напрямкам, які слід вивчити.


Їжа для роздумів: Наївний підхід був би: Візьміть один елемент з s, порівняйте його з кожним елементом u u зліва направо, збільшуючи, якщо це інверсія, і перенесіть раніше обчислене число. Потім перейдіть список праворуч наліво тим самим елементом, збільшуючи кількість підрахунків для кожної позиції. Це працює в O (| s | * | u |) з пробілом = O (| u |)
trevore

1
Перевірка всіх максимально зростаючих послідовностей може десь призвести.
Рафаель

Відповіді:


2

Це розробка відповіді тревор. Це занадто довго, щоб вмістити коментар і містить докази його рішення (або принаймні, як я це розумію).

Ви можете показати, що в будь-якому оптимальному рішенні елементи з'являться впорядкованими. sЯкщо ні, припустимо, що і вони відображаються в зворотному порядку в оптимальному рішенні. Нехай σ 1 - кількість елементів між s 1 і s 2 , меншими ніж s 1, і β 1 - число тих, що більше s 1 . Визначте σ 2 і β 2 аналогічно для s 2 . Зауважимо, що σ 1 σs1<s2σ1s1s2s1β1s1σ2β2s2 і β 2β 1 . Перестановка з 1 і їв 2 буде змінити кількість інверсій по - р 1 + β 2 - σ 2 + σ 1 - 1 , який є не більше-1.σ1σ2β2β1s1s2β1+β2σ2+σ11

sssss менші від медіани зліва від медіани та елементи, більші за медіану праворуч.

kT(|s|,|u|)=T(|s|/2,|u|k)+T(|s|/2,k)+|u|+|s||s|sT(|s|,|u|)=O(|s|log|s|+|u|log|s|)

|s|us|u|su


Дякуємо за детальну розробку. Саме це я і мав на увазі рішення.
trevore

1

Гаразд, ось моє рішення:

Спостереження (яке я більш-менш довів) полягає в тому, що оптимальним рішенням завжди буде те, в якому s сортується за зростанням. Це породжує алгоритм O ((| u | + | s |) * log (| s |)).

Щоб знайти оптимальне рішення для одного елемента, виконайте, як я вже говорив у коментарі: Візьміть один елемент з s, порівняйте його з кожним елементом u u зліва направо, збільшення лічильника є інверсією та перенесіть раніше обчислене число. Потім перейдіть список праворуч наліво тим самим елементом, збільшуючи кількість підрахунків для кожної позиції.

Це О (| u |).

Сортувати s.

Для середнього елемента s у положенні m: Знайдіть найкраще положення b in u (використовуючи метод зверху).

Розділіть s на m і u на b і рекурсивно дзвоніть лівою та правою частинами, з'єднуючи результати з m у правильному порядку.

Зупиніться, як тільки u або s порожні.


Я цього не розумію. s - вхід. Ви не можете припустити, що s впорядкованому порядку. Ваш алгоритм повинен працювати для всіх можливих значень s.
DW

Так, але в будь-якому оптимальному рішенні елементи s завжди будуть відсортовані за зростанням у новому масиві. Зверніть увагу на крок "Сортувати s". Дивіться приклад вище. Що я довів до цього, це те, що: a, b in s, a <b, якщо a оптимально розміщено в u, то оптимальне місце для b знаходиться праворуч від a.
trevore
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.