Вопрос в следующем
Как можно найти "оптимальное решение", учитывая матрицу, созданную алгоритмом Левенштейна?
т.е. как мы можем найти точную последовательность строковых операций: вставки, удаления и замены [одной буквы], необходимые для преобразования «строки» в «t-строку»?
Во-первых, следует отметить, что во многих случаях существует НЕСКОЛЬКО оптимальных решений.
В то время как алгоритм Левенштейна обеспечивает минимальное количество операций (8 в демократическом/республиканском примере ) есть много последовательностей (из 8 операций), которые могут произвести это преобразование.
"Расшифровав" матрицу Левенштейна, можно перечислить ВСЕ такие оптимальные последовательности.
Общая идея состоит в том, что все оптимальные решения следуют "пути", из верхнего левого угла в нижний правый угол em> (или в другую сторону), при этом значения ячеек матрицы на этом пути либо остаются прежними, либо увеличиваются на единицу (или уменьшаются на единицу в обратном направлении), начиная с 0 и заканчивая оптимальным числом операций для рассматриваемых строк (от 0 до 8 в демократическом/республиканском случае). Число увеличивается, когда операция необходима, оно остается прежним, когда буквы в соответствующих позициях в строках совпадают.
Легко составить алгоритм, который выдает такой путь (немного сложнее создать все возможные пути), и из такого пути вывести последовательность операций.
Этот алгоритм поиска пути должен начинаться в правом нижнем углу и работать в обратном направлении. Причина такого подхода в том, что мы точно знаем, что для того, чтобы быть оптимальным решением, оно должно заканчиваться в этом углу, а чтобы заканчиваться в этом углу, оно должно исходить из одной из 3-х ячеек либо сразу слева от нее, либо сразу над ней. это или сразу по диагонали. Выбирая из этих трех ячеек ячейку, которая удовлетворяет нашему требованию «одинаковое значение или уменьшение на единицу», мы фактически выбираем ячейку на одном из оптимальных путей. Повторяя операцию до тех пор, пока мы не попадем в верхний левый угол (или даже пока мы не достигнем ячейки со значением 0), мы эффективно возвращаемся назад по оптимальному пути.
Иллюстрация с демократом - республиканский пример
Следует также отметить, что построить матрицу можно одним из двух способов: с «демократом» по горизонтали или по вертикали. Это не меняет ни вычисления расстояния Левенштейна, ни списка необходимых операций; это только меняет то, как мы интерпретируем матрицу, например, горизонтальное перемещение по «пути» означает либо вставку символа [из строки t], либо удаление символа [из строки s] в зависимости от того, является ли «строка s» «горизонтальной» или "вертикаль" в матрице.
Я буду использовать следующую матрицу. Таким образом, соглашения (только в направлении слева направо и/или сверху вниз)
- перемещение по горизонтали — это ВСТАВКА буквы из 't string'
- перемещение по вертикали - это УДАЛЕНИЕ буквы из "строки"
- a diagonal move is either:
- a no-operation (both letters at respective positions are the same); the number doesn't change
- ЗАМЕНА (буквы на соответствующих позициях различны); число увеличивается на единицу.
Матрица Левенштейна для 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" в правом нижнем углу.
Выберите ячейку [диагональ] "a", "a" в качестве следующего пункта назначения, так как она меньше двух других (и удовлетворяет тому же или -1 условие).
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
, поэтому шаг 8 заменяет "t" на "n": democra N
Продолжайте с ячейкой "a", "a",
Выберите ячейку [диагональ] "c", "r" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка имеет то же значение, что и текущая ячейка ==> операция не требуется.
Продолжайте с ячейкой "c", "r",
Выберите ячейку [диагональ] "i", "c" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
поэтому шаг 7 заменяет "r" на "c": democ C an
Продолжите с ячейкой "i", "c",
Выберите ячейку [диагональ] "l", "o" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
поэтому шаг 6 заменяет "c" на "i": демо I может
Продолжайте с ячейкой "l", "o",
Выберите ячейку [диагональ] "b", "m" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
поэтому на шаге 5 замените "o" на "l": dem L ican
Продолжите с ячейкой "b", "m",
Выберите ячейку [диагональ] "u", "e" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
поэтому на шаге 4 замените "m" на "b": de B lican
Продолжайте с ячейкой "u", "e".
Обратите внимание, что "диагональная" ячейка не подходит, потому что "левая" ячейка меньше ее. Выберите ячейку [слева] "p", "e" в качестве следующего пункта назначения...
поэтому шаг 3 вставляет "u" после "e": de U blican
Продолжайте с ячейкой "p", "e",
снова ячейка "диагональ" не подходит Выберите [левую] ячейку "e", "e" в качестве следующего пункта назначения...
поэтому шаг 2 вставляется "p" после "e": de P ublican
Продолжайте с ячейкой "e", "e",
Выберите ячейку [диагональ] "r", "d" в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка имеет то же значение, что и текущая ячейка ==> операция не требуется.
Продолжайте с ячейкой "r", "d",
Выберите [диагональную] "начальную" ячейку в качестве следующего пункта назначения...
Обратите внимание, что новая ячейка на единицу меньше, чем текущая ячейка
, поэтому шаг 1 заменяет "d" на "r": R epublican
Вы попали в ячейку со значением 0: ваша работа выполнена!
person
mjv
schedule
02.05.2011