Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

12.2. Динамическое программирование 561

Применение динамического программирования к проблеме LCS

Вспомните, что в проблеме LCS, нам дают две строки символов, X и Y,

длину n и m, соответственно, и просят найти самую длинную последовательность S, который является под - последовательность и X и Y. С тех пор X и Y строки символов, у нас есть естественный набор индексов, с которыми можно определить подпроблемы - индексы в последовательности X и Y. Давайте определим подпроблему, поэтому, как то из вычисления стоимости L [я, j], который мы будем использовать, чтобы обозначить длину самой длинной последовательности, которая является подпоследовательностью оба X [0.. i] = x0x1x2... xi и Y [0.. j] = y0y1y2... y j. Это определение позволяет нам переписывать L [я, j] с точки зрения оптимальных подпроблемных решений. Это определение зависит, на каком из двух случаев мы находимся в. (См. рисунок 12.1.)

Рисунок 12.1: Эти два случая в самом длинном общем алгоритме подпоследовательности: (a) xi = y j; (b) xi = y j. Обратите внимание на то, что алгоритм хранит только L [я, j] ценности, не матчи.

• xi = y j. В этом случае у нас есть матч между последним характером X [0.. i]

и последний характер Y [0.. j]. Мы утверждаем, что этот характер принадлежит a

самая длинная общая подпоследовательность X [0.. i] и Y [0.. j]. Чтобы оправдать это требование, давайте предположим, что это не верно. Должна быть некоторая самая длинная общая подпоследовательность

xi1 xi2... xik = y j1 y j2... y jk. Если xik = xi или y jk = y j, то мы получаем тот же самый se-

айва, устанавливая ik = я и jk = j. Поочередно, если x jk = xi, то мы можем получить еще более длинную общую подпоследовательность, добавив xi до конца. Таким образом, самая длинная общая подпоследовательность X [0.. i] и Y [0.. j] концы с xi. Поэтому, мы устанавливаем

L [я, j] = L [я- 1, j- 1] + 1, если xi = y j.

• xi = y j. В этом случае у нас не может быть общей подпоследовательности, которая включает

и xi и y j. Таким образом, у нас может быть общий конец подпоследовательности с xi или

тот, который заканчивается y j (или возможно ни один), но конечно не оба. Поэтому, мы устанавливаем

L [я, j] = макс. L [я- 1, j], L [я, j- 1], если xi = y j.

Чтобы заставить оба из этих уравнений иметь смысл в граничных случаях когда

i = 0 или j = 0, мы назначаем L [я,-1] = 0 поскольку я =-1, 0, 1..., n- 1 и L [-1, j] = 0 для

j =-1, 0, 1..., m- 1.

562 Глава 12. Последовательности и динамическое программирование

Алгоритм LCS

Определение L [я, j] удовлетворяю оптимизацию подзадач, так как у нас не может быть самой длинной общей подпоследовательности, также не имея самых длинных общих подпоследовательностей для подпроблем. Кроме того, это использует подпроблемное наложение, потому что подпроблема solu-tion L [я, j] могу использоваться в нескольких других проблемах (а именно, проблемы L [я + 1, j], L [я, j + 1], и L [я + 1, j + 1]). Поворачивая это определение L [я, j] в алгоритм

фактически довольно прямое. Мы инициализируем (n + 1) (m + 1) множество, L, для

граничные случаи, когда я = 0 или j = 0. А именно, мы инициализируем L [я,-1] = 0 поскольку я =-1, 0, 1..., n- 1 и L [-1, j] = 0 для j =-1, 0, 1..., m- 1. Затем мы, проход - atively создает ценности в L, пока у нас нет L [n- 1, m- 1], длина самого длинного

общая подпоследовательность X и Y. Мы даем псевдокодовое описание этого algo-

rithm в Кодовом Фрагменте 12.2.

Алгоритм LCS (X, Y):

Вход: Последовательности X и Y с n и m элементами, соответственно

Продукция: Поскольку я = 0..., n- 1, j = 0..., m- 1, длина L [я, j] самого длинного

последовательность, которая является подпоследовательностью обоих последовательность X [0.. i] = x0x1x2 ∙ ∙ ∙ xi и последовательность Y [0.. j] = y0y1y2 ∙ ∙ ∙ y j

поскольку я¬-1 к n- 1 делаю

L [я,-1]¬ 0

для j¬ 0 к m- 1 делают

L [-1, j]¬ 0

поскольку я¬ 0 к n- 1 делаю

для j¬ 0 к m- 1 делают

если xi = y j тогда

L [я, j]¬ L [я- 1, j- 1] + 1

еще

L [я, j]¬ макс. L [я- 1, j], L [я, j- 1]

возвратите множество L

Кодовый Фрагмент 12.2: Динамический программный алгоритм для проблемы LCS.

Продолжительность алгоритма Кодового Фрагмента 12.2 легко проанализировать, потому что это во власти двух вложенных для петель с внешней, повторяющей n времена и внутреннее, повторяющее m времена. Начиная с если-заявления и назначения в петле каждый требует O (1) примитивные операции, этот алгоритм пробеги в O (nm) время. Таким образом динамический программный метод может быть применен к самой долгой общей проблеме подпоследовательности улучшиться значительно по показательно-разовому решению «в лоб» проблемы LCS.