Изменения

Перейти к: навигация, поиск

Задача о наибольшей общей подпоследовательности

986 байт добавлено, 01:54, 23 ноября 2011
Нет описания правки
a[i][j] =
\begin{cases}
0, & i = 0\text{ or }j = 0 \\
a[i - 1][j - 1] + 1, & x[i] = y[j] \\
max(a[i][j - 1], a[i - 1][j]), & x[i] \neq y[j]
</tex>
Очевидно, что сложность алгоритма составит <tex> O(mn) </tex>, где <tex> m </tex> и <tex> n^2) </tex>— длины последовательностей.
=== Доказательство оптимальности ===
ПредположимБаза: при <tex> i = 0 </tex> или <tex> j = 0 </tex> длина одной из последовательностей равна нулю, поэтому и их НОП тоже нулевой длины. Переходы: предположим, что некоторое значение <tex> a[i][j] </tex> посчитано неверно. Однако, в случае различия соответствующих символов, они не могут одновременно участвовать в НОП, а значит ответ действительно равен формуле для случая с различными символами. В случае же равенства, ответ не может быть больше, чем <tex> a[i - 1][j - 1] + 1 </tex>, так как тогда неверно посчитано значение <tex> a[i - 1][j - 1] + 1 </tex>.
=== Построение подпоследовательности ===
Для каждой пары элементов будем хранить не только длину НОП соответствующих префиксов, но и номера последних элементов, участвующих в этой НОП.Таким образом, посчитав ответ, мы сможем восстановить всю наибольшую общую подпоследовательность.
=== Пример реализации на Java Псевдокод === public int lcs(intX, Y — данные последовательности; a[i] s1, int[j] s2) { int— НОП для префикса длины i последовательности X и префикса длины j последовательности Y; b[i][j] — пара индексов элемента таблицы, соответствующего оптимальному решению вспомогательной задачи, выбранной при вычислении a = new int[s1.lengthi][s2j].length]; //Подсчет значенийподсчёт таблиц for LCS(int i X, Y) m = 0; i < s1.length; i++(X) for (int j n = 0; j < s2.length; j++(Y) { if (s1 for i = 1 to m a[i] == s2[j0]) if ((i == 0) || ( for j == 0)) {to n a[i0][j] = 0 for i = 1 to m for j = 1;to n } else { if x[i] = y[i] a[i][j] = a[i - 1][j - 1] + 1; } b[i][j] = pair(i - 1, j - 1) else { if ((i > 0) && (a[i - 1][j] > = a[i][j- 1])) { a[i][j] = a[i - 1][j]; } if ( b[i][j] = pair(i - 1, j > 0) && ( else a[i][j] = a[i][j - 1] > a b[i][j]= pair(i, j - 1) // вывод НОП PrintLCS(b, X, i, j) { if i = 0 or j = 0 // пришли к началу НОП return if b[i][j] = pair(i - 1, j - 1) // если пришли в a[i][j] = из a[i- 1][j - 1];, то X[i] = Y[j], надо вывести этот элемент } PrintLCS(b, X, i - 1, j - 1) } print X[i] } else return aif b[i][s1.length j] = pair(i - 1][s2.length , j) PrintLCS(b, X, i - 1];, j) else } PrintLCS(b, X, i, j - 1)
418
правок

Навигация