Найменша кількість редагувань рухається між двома словами


11

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

  • додайте лист на одній із кінцівок (наприклад, AB -> ABC),
  • дублювати і поєднувати все слово (наприклад, ABC -> ABCABC),
  • розріжте слово навпіл (подвійний хід дублювання, ABCABC -> ABC + ABC),
  • видаліть одну з букв (наприклад, ABC -> AC) та
  • повторіть одну з букв (наприклад, ABC -> ABBC).

Наприклад, мінімальна послідовність переходів від ABC до BCBC - ABC -> BC (видалити A) -> BCBC (дублювання).

Я не маю досвіду в галузі інформатики. Можливо, це добре відома проблема, але мій пошук в Google нічого не дав мені.

Чи знаєте ви якусь пов’язану, чітко визначену проблему?

Редагувати : Як було запропоновано у відповіді Ентоні Лабарре, я прочитав деякі статті про проблему перестановки / компонування набору, подібну до описаної вище проблеми. Хтось знає більше про цю проблему? Це актуально?


1
Імовірно, жодна зі списку на сайті en.wikipedia.org/wiki/String_metric не застосовується, а також немає у sourceforge.net/projects/simmetrics ?
Андраш Саламон

Я не знаю всіх із них, але більшість цілей цих методів - вирівняти рядки, дозволені лише зміни однієї літери, і не допускати складніших кроків.
cz3rk

1
Дублювання застосовується до всього рядка ABC -> ABCABC, так що напрямок не має значення. Але напрям повторення може бути лише в порядку ліворуч праворуч, як штамповка.
cz3rk

2
Чому це важливо, якщо вхідні слова не діляться літерами? (Між Aта Bу послідовності @ reinerpost має бути порожній рядок .)
Jeffε

2
www

Відповіді:


3

Я не знаю, чи вивчена ця конкретна проблема, але Chaudhuri та ін. вивчив пов’язану з ним дублікацію випадкових випадків втрати : ви отримуєте перестановку, і ви хочете перетворити її на перестановку ідентичності шляхом (1) дублювання сегмента будь-якої довжини та додавання копії відразу після оригіналу, потім (2) видалення елементів, щоб ви отримали нову перестановку замість рядка. Зауважте, що застосування (1) і (2) припадає на одну операцію.

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


Дякую, я ознайомлюсь з їх роботою. Я бачу зв’язок між двома проблемами.
cz3rk

2

Як було зазначено, ця проблема схожа на більш відому проблему відстані редагування (що лежить в основі відстані Левенштейна ). Він також має спільні риси, наприклад, з динамічною дистанцією викривлення часу (дублювання або "заїкання" у вашій останній вимозі).

Кроки до динамічного програмування

x=x1xny=y1ymd(x,y)

min{d(x,y1ym1)+1▻ Add letter at endd(x,y2ym)+1▻ Add letter at beginningd(x,y1ym/2)+1if y=y1ym/2y1ym/2▻ Doublingd(x1xn/2,y)+1if x=x1xn/2x1xn/2▻ Halvingd(x1xn,y)+1▻ Deletiond(x1xn1,y1ym1)if yn=ym▻ Ignoring last elt.

Тут останній варіант в основному говорить про те, що перетворення FOOX в BARX еквівалентне перетворенню FOO в BAR. Це означає, що ви могли використовувати параметр «Додати літеру в кінці» для досягнення ефекту заїкання (дублювання) та видалення в точці. Проблема полягає в тому, що вона автоматично дозволяє додавати довільний символ в середині рядка , а , що - то ви , ймовірно , не хочете. (Це «ігнорування однакових останніх елементів» - це стандартний спосіб домогтися видалення та заїкання у довільних позиціях. Це забороняє довільні вставки, дозволяючи додавання в будь-якому кінці, хоч трохи складним, хоча…)

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

(Звичайно, якщо ви могли отримати подібний розрив, який фактично визначив вашу відстань, вам потрібно буде лише додати пам ятку, і ви матимете рішення. Однак, оскільки ви не працюєте лише з префіксами, я не хочу ' не думаю, що ви можете використовувати просто індекси для запам'ятовування; можливо, вам доведеться зберігати фактичні, модифіковані рядки для кожного виклику, які вийдуть величезними, якщо ваші рядки значного розміру.)

Кроки до евристичного рішення

Інший підхід, який може бути простішим для розуміння, і який міг би використовувати трохи менше місця, - це пошук найкоротшого "редагування шляху" від першої рядки до другої, використовуючи алгоритм (в основному, найкращий- перша гілка). Простір пошуку буде визначено безпосередньо вашими операціями редагування. Тепер, для великої струни, ви бAотримати велике сусідство, оскільки ви можете видалити будь-який символ (надаючи вам сусіда для кожного потенційного видалення) або дублювати будь-який символ (знову ж, надаючи лінійну кількість сусідів), а також додавання будь-якого символу в будь-якому кінці, що б дасть вам кількість сусідів, що дорівнює подвоєному розміру алфавіту. (Просто сподіваюсь, що ви не використовуєте повний Unicode ;-) При такому великому вентиляторі ви можете досягти значного прискорення за допомогою двостороннього або якогось родичаA .

Для того, щоб працював, вам знадобиться нижня межа для відстані до вашої мети. Я не впевнений, чи є очевидний вибір тут, але те, що ви можете зробити, це реалізувати динамічне рішення програмування, засноване на рекурсивному розкладі, яке я дав вище (знову ж таки з можливими проблемами з простором, якщо ваші рядки дуже довгі). Незважаючи на те , що розкладання неточно обчислити дистанцію, то це гарантовано буде нижньою межею (бо це більш поблажливими), що означає , що він буде працювати як евристика в . (Наскільки це буде щільно, я не знаю, але це було б правильно.) Звичайно, запам'ятовування вашої зв'язаної функції може бути спільним для всіх обчислень пов'язаних під час вашогоAAAбігати. (Проміжок часу / простір там.)

Тому…

Ефективність мого запропонованого рішення могла б трохи залежати від (1) довжини ваших рядків та (2) від розміру вашого алфавіту. Якщо жодне не є величезним, воно може спрацювати. Це:

  • Реалізуйте нижню межу на відстані, використовуючи моє рекурсивне розкладання та динамічне програмування (наприклад, за допомогою запам’ятовуваної рекурсивної функції).
  • Реалізуйте (або двонаправлений ) за допомогою операцій редагування як "переміщення" у просторі стану та нижню межу на основі динамічного програмування.AA

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

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


0

Деякі пов'язані, чітко визначені проблеми буде проблема вирівнювання послідовності . Він відрізняється тим, що він не використовує операцію дублювання. Визначеними операціями є: вставка символу, видалення символу, перетворення символу. Популярним алгоритмом вирішення цієї проблеми є Needleman-Wunsch .


Я це знаю, але дуже хочу працювати з певними рухами. Єдиний спосіб, який я знайшов це зробити, - це рекурсивний алгоритм грубої сили. Не дуже приємно, і він міг би стати обчислювально інтенсивним, якби збільшився розмір слів.
cz3rk

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.