Задача о наименьшей суперпоследовательности — различия между версиями
Motyaspr (обсуждение | вклад) |
Motyaspr (обсуждение | вклад) (→Восстановление ответа) |
||
| Строка 40: | Строка 40: | ||
\begin{cases} | \begin{cases} | ||
1, & x[i] == y[j] \\ | 1, & x[i] == y[j] \\ | ||
| − | 2, & x[i] \neq y[j], | + | 2, & x[i] \neq y[j], scs[i - 1][j] > scs[i][j - 1] \\ |
| − | 3, & x[i] \neq y[j], | + | 3, & x[i] \neq y[j], scs[i - 1][j] < scs[i][j - 1] \\ |
\end{cases} | \end{cases} | ||
</tex> | </tex> | ||
Версия 23:28, 23 декабря 2017
| Определение: |
| Последовательность является суперпоследовательностью (англ. supersequence) последовательности , если существует строго возрастающая последовательность индексов таких, что для всех выполняется соотношение . |
| Определение: |
| Последовательность является общей суперпоследовательностью (англ. common supersequence) последовательностей и , если является суперпоследовательностью как для , так для и . |
| Задача: |
| Пусть имеются последовательности и . Необходимо найти |
Содержание
Наивное решение
Пусть даны две последовательности длины и соответственно. Заметим, что если приписать к одной из данных последовательностей другую, то полученная последовательность будет их суперпоследовательностью с длиной . Запомним все элементы обеих последовательностей и из них построим все возможные последовательности. Тогда искомая гарантированно найдётся, однако время работы алгоритма будет экспоненциально зависеть от длин исходных последовательностей.
Динамическое программирование
Решение
Обозначим за префиксов данных последовательностей и , заканчивающихся в элементах с номерами и соответственно. Наименьшая общая суперпоследовательность и должна содержать каждый символ обеих последовательностей, поэтому если , то это просто последовательность . Аналогичен случай, когда . Если и , то возможны два случая. Если , то SCS должна включать оба этих элемента. Значит нужно выбрать минимальный из ответов для префиксов, включающих один элемент и не включающих второй. Если же , то для последовательностей и должна заканчиваться этим элементом, так как он общий для них. Получается следующее рекуррентное соотношение:
Cложность алгоритма составит , где и — длины последовательностей.
Восстановление ответа
Для восстановления ответа заведем массив , где будет равняться:
По этим данным можно узнать, какой символ был добавлен в наименьшую общую суперпоследовательность.
Псевдокод
x, y — данные последовательности; — SCS для префикса длины i последовательности x и префикса длины j последовательности y; prev[i][j] — пара индексов элемента таблицы, которые предшествовали .
fun SCS(x: int, y: int): // аналог void
n = x.size
m = y.size
for i = 1 to n
scs[i][0] = i
for j = 0 to m
scs[0][j] = j
for i = 1 to n
for j = 1 to m
if x[i] == y[j]
scs[i][j] = 1 + scs[i - 1][j - 1]
prev[i][j] = 1
else
if scs[i - 1][j] <= lcs[i][j - 1]
scs[i][j] = 1 + scs[i - 1][j]
prev[i][j] = 2
else
scs[i][j] = 1 + scs[i][j - 1]
prev[i][j] = 3
fun printLCS(n: int, m: int): // вывод SCS
i = n
j = m
ans = [] // массив ответа
while i > 0 and j > 0
if prev[i][j] == 1
ans.append(x[i])
i -= 1
j -= 1
else
if prev[i][j] == 2
ans.append(x[i])
i -= 1
else
ans.append(y[j])
j -= 1
while i > 0 // добавляем оставшиеся символы первой последовательности
ans.append(x[i])
i -= 1
while j > 0
ans.append(y[j]) // добавляем оставшиеся символы второй последовательности
j -= 1
reverse(ans) // разворачиваем последовательность, так как шли с конца
return ans
Связь с наибольшей общей подпоследовательностью
| Теорема: |
, где - длина наибольшей общей подпоследовательности, - длина наименьшей общей суперпоследовательности, и - длины последовательностей и соответсвенно. |
| Доказательство: |
|
Пусть , . Обозначим за их SCS и будем ее строить. Так как являетcя суперпоследовательностью , то можно представить так: Мы должны поставить на место некоторых пропусков поставить элементы , так чтобы суммарная длина была минимальна, и был суперпоследовательностью . Рассмотрим любую общую подпоследовательность и .Заметим, что она уже находятся в , а значит все её элементы не нужно добавлять. Поэтому мы добавим не меньше чем . Длину нужно минимизировать, значит имеет место равенство: . Поэтому: |