Задача о наименьшей суперпоследовательности — различия между версиями
Motyaspr (обсуждение | вклад) |
Motyaspr (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
{{Определение | {{Определение | ||
|definition= | |definition= | ||
− | Последовательность <tex> Z = \left \langle z_1, z_2, \dots, z_k \right \rangle </tex> является '''суперпоследовательностью''' (англ. ''supersequence'') последовательности <tex> X = \left \langle x_1, x_2, \dots, x_m \right \rangle </tex>, если существует строго возрастающая последовательность <tex> \left \langle i_1, i_2, \dots, i_m \right \rangle </tex> индексов <tex> Z </tex> таких, что для всех <tex> j = 1, 2, \dots, m </tex> выполняется соотношение <tex> z_{i_j} = x_j </tex>. | + | Последовательность <tex> Z = \left \langle z_1, z_2, \dots, z_k \right \rangle </tex> является '''суперпоследовательностью''' (англ. ''supersequence'') последовательности <tex> X = \left \langle x_1, x_2, \dots, x_m \right \rangle </tex>, если существует ''строго возрастающая'' последовательность <tex> \left \langle i_1, i_2, \dots, i_m \right \rangle </tex> индексов <tex> Z </tex> таких, что для всех <tex> j = 1, 2, \dots, m </tex> выполняется соотношение <tex> z_{i_j} = x_j </tex>. |
}} | }} | ||
{{Определение | {{Определение | ||
|definition= | |definition= | ||
− | Последовательность <tex> Z </tex> является '''общей суперпоследовательностью''' (англ. ''common supersequence'') последовательностей <tex> X </tex> и <tex> Y </tex>, если <tex> | + | Последовательность <tex> Z </tex> является '''общей суперпоследовательностью''' (англ. ''common supersequence'') последовательностей <tex> X </tex> и <tex> Y </tex>, если <tex> Z </tex> является суперпоследовательностью как для <tex> X </tex>, так для и <tex> Y </tex>. |
}} | }} | ||
Строка 15: | Строка 15: | ||
== Наивное решение == | == Наивное решение == | ||
− | Заметим, что если приписать к одной из | + | Пусть даны две последовательности длины <tex>n</tex> и <tex>m</tex> соответственно. Заметим, что если приписать к одной из данных последовательностей другую, то полученная последовательность будет их суперпоследовательностью с длиной <tex> n + m </tex>. Запомним все элементы обеих последовательностей и из них построим все возможные последовательности. Тогда искомая <tex>SCS</tex> гарантированно найдётся, однако время работы алгоритма будет экспоненциально зависеть от длины исходных последовательностей. |
Версия 22:25, 23 декабря 2017
Определение: |
Последовательность | является суперпоследовательностью (англ. supersequence) последовательности , если существует строго возрастающая последовательность индексов таких, что для всех выполняется соотношение .
Определение: |
Последовательность | является общей суперпоследовательностью (англ. common supersequence) последовательностей и , если является суперпоследовательностью как для , так для и .
Задача: |
Пусть имеются последовательности | и . Необходимо найти
Содержание
Наивное решение
Пусть даны две последовательности длины
и соответственно. Заметим, что если приписать к одной из данных последовательностей другую, то полученная последовательность будет их суперпоследовательностью с длиной . Запомним все элементы обеих последовательностей и из них построим все возможные последовательности. Тогда искомая гарантированно найдётся, однако время работы алгоритма будет экспоненциально зависеть от длины исходных последовательностей.
Динамическое программирование
Решение
Обозначим за
SCS префиксов данных последовательностей и , заканчивающихся в элементах с номерами и соответственно. Наименьшая общая суперпоследовательность и должна содержать каждый символ обеих последовательностей, поэтому если , то это просто последовательность . Аналогичен случай, когда . Если и , то возможны два случая. Если , то SCS должна включать оба этих элемента. Значит нужно выбрать оптимальный из ответов для префиксов, включающих один элемент и не включающих второй, и выбрать из них минимальный. Если же , то SCS для последовательностей и должна заканчиваться этим элементом, так как он общий для них. Получается следующее рекуррентное соотношение:
Очевидно, что сложность алгоритма составит
, где и — длины последовательностей.Восстановление ответа
В
помимо длины последовательности хранятся и символ, добавленный последним. Таким образом, зная длину SCS, можно восстановить и саму последовательность.Псевдокод
x, y — данные последовательности;
— SCS для префикса длины i последовательности x и префикса длины j последовательности y; prev[i][j] — пара индексов элемента таблицы, которые предшествовали .fun SCS(x: int, y: int): // аналог void m = x.size n = y.size for i = 1 to m scs[i][0] = i for j = 0 to n scs[0][j] = j for i = 1 to m for j = 1 to n if x[i] == y[j] scs[i][j] = 1 + scs[i - 1][j - 1] prev[i][j] = pair(i - 1, j - 1) else if scs[i - 1][j] <= lcs[i][j - 1] scs[i][j] = 1 + scs[i - 1][j] prev[i][j] = pair(i - 1, j) else scs[i][j] = 1 + scs[i][j - 1] prev[i][j] = pair(i, j - 1) fun printLCS(m: int, n: int): // вывод SCS i = m j = n ans = [] // массив ответа while i > 0 and j > 0 if prev[i][j] == pair(i - 1, j - 1) ans.append(x[i]) i -= 1 j -= 1 else if prev[i][j] == pair(i - 1, j) 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я подпоследовательностью , то можно представить так: Мы должны поставить на место некоторых пропусков поставить элементы , так чтобы суммарная длина была минимальна, и был подпоследовательностью . Заметим, что если найдется подпоследовательность такая, что является подпоследовательностью , то все элементы этой подпоследовательности уже находятся в , а значит их не нужно вставлять. Поэтому мы добавим не меньше чем . Длину нужно минимизировать, значит имеет место равенство: . |