Вопрос
Учитывая матрицу, полученную по алгоритму Левенштейна, как можно найти " оптимальное решение "?
то есть, как мы можем найти точную последовательность строковых операций: вставки, удаления и подстановки [одной буквы], необходимые для преобразования строки s в строку t?
Во-первых, следует отметить, что во многих случаях существует НЕСКОЛЬКО оптимальных решений .
В то время как алгоритм Левенштейна обеспечивает минимальное количество операций (8 в демократ / республиканец пример) есть много последовательностей (из 8 операций), которые могут произвести это преобразование.
«Декодируя» матрицу Левенштейна, можно перечислить ВСЕ такие оптимальные последовательности.
Общая идея состоит в том, что все оптимальные решения следуют «пути», от верхнего левого угла до нижнего правого угла (или в другом направлении), в результате чего значения ячейки матрицы на этом пути либо остаются неизменными, либо увеличиваются на единицу (или уменьшаются на единицу в обратном направлении), начиная с 0 и заканчивая оптимальным количеством операций для рассматриваемых строк (от 0 до 8 демократов / республиканский случай). Число увеличивается, когда необходима операция, и остается тем же, когда буквы в соответствующих позициях в строках совпадают.
Легко создать алгоритм, который создает такой путь (немного сложнее, чтобы получить все возможные пути), и из такого пути вывести последовательность операций.
Этот алгоритм поиска пути должен начинаться с нижнего правого угла и двигаться назад. Причина такого подхода состоит в том, что мы знаем, что для оптимального решения оно должно заканчиваться в этом углу, и чтобы оно заканчивалось в этом углу, оно должно исходить из одной из трех ячеек, либо непосредственно слева от нее, непосредственно над это или сразу по диагонали. Выбирая ячейку из этих трех ячеек, которая удовлетворяет нашему требованию «одинаковое значение или уменьшение на единицу», мы эффективно выбираем ячейку на одном из оптимальных путей. Повторяя операцию до тех пор, пока мы не окажемся в верхнем левом углу (или даже до тех пор, пока не достигнем ячейки со значением 0), мы эффективно вернем наш путь по оптимальному пути.
Иллюстрация с демократом - республиканский пример
Следует также отметить, что матрицу можно построить одним из двух способов: с «демократом» по горизонтали или по вертикали. Это не меняет вычисления расстояния Левенштейна и не меняет список необходимых операций; это только изменяет способ интерпретации матрицы, например, горизонтальное перемещение по «пути» означает либо вставку символа [из строки t], либо удаление символа [из строки s] в зависимости от того, является ли строка «s» «горизонтальной» или "вертикаль" в матрице.
Я буду использовать следующую матрицу. Следовательно, условные обозначения (только в направлениях слева направо и / или сверху вниз)
- горизонтальное перемещение - это ВСТАВКА буквы из 't string'
- вертикальное движение - это DELETION буквы из строки '
- диагональный ход:
- бездействие (обе буквы в соответствующих позициях одинаковы); номер не меняется
- a ЗАМЕНА (буквы на соответствующих позициях различны); число увеличивается на единицу.
Матрица Левенштейна для s = "демократ", t = "республиканец"
r e p u b l i c a n
0 1 2 3 4 5 6 7 8 9 10
d 1 1 2 3 4 5 6 7 8 9 10
e 2 2 1 2 3 4 5 6 7 8 9
m 3 3 2 2 3 4 5 6 7 8 9
o 4 4 3 3 3 4 5 6 7 8 9
c 5 5 4 4 4 4 5 6 6 7 8
r 6 5 5 5 5 5 5 6 7 7 8
a 7 6 6 6 6 6 6 6 7 7 8
t 8 7 7 7 7 7 7 7 7 8 8
Подход произвольный , который я использую для выбора одного пути из нескольких возможных оптимальных путей, в общих чертах описан ниже:
Starting at the bottom-rightmost cell, and working our way backward toward
the top left.
For each "backward" step, consider the 3 cells directly adjacent to the current
cell (in the left, top or left+top directions)
if the value in the diagonal cell (going up+left) is smaller or equal to the
values found in the other two cells
AND
if this is same or 1 minus the value of the current cell
then "take the diagonal cell"
if the value of the diagonal cell is one less than the current cell:
Add a SUBSTITUTION operation (from the letters corresponding to
the _current_ cell)
otherwise: do not add an operation this was a no-operation.
elseif the value in the cell to the left is smaller of equal to the value of
the of the cell above current cell
AND
if this value is same or 1 minus the value of the current cell
then "take the cell to left", and
add an INSERTION of the letter corresponding to the cell
else
take the cell above, add
Add a DELETION operation of the letter in 's string'
Следуя этому неформальному псевдокоду, мы получаем следующее:
Начните с ячейки «n», «t» внизу справа.
Выберите ячейку [diagonal] «a», «a» в качестве следующего пункта назначения, поскольку она меньше двух других (и удовлетворяет тому же условию или условию -1).
Обратите внимание, что новая ячейка на единицу меньше текущей ячейки
, поэтому шаг 8 заменяет «t» на «n»: Democra N
Продолжить с «a», «a"cell,
Выберите ячейку [diagonal]" c "," r "в качестве следующего пункта назначения ...
Обратите внимание, что новая ячейка имеет то же значение, что и текущая ячейка ==> операция не требуется .
Продолжить с ячейки "c", "r",
Выбрать ячейку [diagonal] "i", "c" в качестве следующего пункта назначения ...
Обратите внимание, что новая ячейкана единицу меньше текущей ячейки
, поэтому шаг 7 заменяет «r» на «c»: democ C an
Продолжить с ячейки «i», «c»,
Выберите ячейку [diagonal] "l", "o" в качестве следующего пункта назначения ...
Обратите внимание, что новая ячейка на единицу меньше текущей ячейки
, поэтому шаг 6 заменяет "c" на "i": demo I can
Продолжить с ячейки "l", "o",
Выбрать ячейку [диагональ] "b", "m" в качестве следующего пункта назначения ...
Обратите внимание, что новая ячейка на 1 меньше текущей ячейки
, поэтому шаг5 заменяет "o" на "l": dem L ican
Продолжить с ячейки "b", "m",
Выбрать [диагональ] "u", "e "ячейка как следующий пункт назначения ...
Обратите внимание, что новая ячейка на единицу меньше текущей ячейки
, поэтому шаг 4 заменяет" m "на" b ": de B lican
Продолжите с ячейки «u», «e»,
Обратите внимание, что диагональная ячейка не подходит, потому что «левая» ячейка меньше ее.В качестве следующего пункта назначения выберите [слева] ячейку «p», «e» ...
, поэтому на шаге 3 после «e» вставляется «u»: de U blican
Продолжить с «p», «e»,
снова «диагональная» ячейка не подходит. Выберите [left] «e», «e» в качестве следующего пункта назначения ...
поэтому шаг2 - «p» после «e»: de P ublican
Продолжить с ячейки «e», «e»,
Выбрать [диагональ] «r», «d "ячейка как следующий пункт назначения ...
Обратите внимание, что новая ячейка имеет то же значение, что и текущая ячейка ==> операция не требуется .
Продолжите с" r "," d"cell,
Выберите ячейку [diagonal]" start "в качестве следующего пункта назначения ...
Обратите внимание, что новая ячейка на единицу меньше текущей ячейки
, поэтому шаг 1 заменяет" d "на" r ".": R epublican
Вы попали в ячейку со значением 0: ваша работа выполнена !