- •Структуры и алгоритмы обработки данных
- •230100.62 – Информатика и вычислительная техника
- •Стандартная постановка задачи
- •Пример постановки задачи
- •Пример постановки задачи в стандартной форме
- •Алгоритмы и их сложность
- •Основы анализа программ
- •Пример анализа алгоритмов
- •Выполнение операторов программы
- •Основы доказательства корректности
- •Динамическое программирование
- •Перемножение нескольких матриц
- •Когда применимо динамическое программирование
- •Наибольшая общая подпоследовательность
- •Жадные алгоритмы
- •Задача о выборе заявок
- •Абстрактные типы данных
- •Атд «Список»
- •Атд «Стек»
- •Атд «Очередь»
- •Множества
- •Хеширование
- •Словари, основанные на хеш-таблицах
- •Поиск слова в тексте
- •Сортировка
- •Сортировка вставками
- •Корневая сортировка
- •Пирамидальная сортировка
- •Переформирование пирамиды
- •Построение пирамиды
- •Сортировка слиянием
- •Управление с помощью таблиц
- •Способы представления графа
- •Матрица смежности
- •Матрица инцидентности
- •Список рёбер
- •Алгоритмы обхода графа
- •Поиск в ширину
- •Задача о кратчайшем пути
- •Алгоритм Дейкстры
- •Алгоритм Беллмана-Форда
- •Задача перекресток
- •Максимальный поток
- •Метод Форда-Фалкерсона
- •Минимальные покрывающие деревья
- •Алгоритм Крускала
- •Алгоритм Прима
- •Минимальные покрывающие деревья
- •Поиск в глубину
- •Топологическая сортировка
- •Деревья
Когда применимо динамическое программирование
Для задач, решаемых методом динамического программирования, характерны два признака:
оптимальность для подзадач;
перекрывающиеся подзадачи.
Оптимальность для подзадач
Задача обладает свойством оптимальности для подзадач, если оптимальное решение задачи содержит оптимальные решения ее подзадач.
Перекрывающиеся подзадачи
Свойство задачи, существенное при использовании динамического программирования, – небольшое число различных подзадач. При рекурсивном решении многократно выходим на одни и те же подзадачи. В таком случае говорят, что у оптимизационной задачи имеются перекрывающиеся подзадачи. В типичных случаях количество подзадач полиномиально зависит от размер а исходных данных.
Наибольшая общая подпоследовательность
Последовательность Z
=
z1,z2,…,zk
называется
подпоследовательностью последовательности
X =
x1,x2,…,xn
, если существует строго возрастающая
последовательность индексов
i1,i2,…,ik
,
для которой
при всех j = 1, 2, … k.
Пример
Z = B, C, D, B является подпоследовательностью последовательности
X = A, B, C, B, D, A, B ; cоответствующая последовательность индексов есть 2,3,5,7 .
Последовательность Z является общей подпоследовательностью последовательностей X и Y , если Z является подпоследовательностью как X так и Y .
Задача о наибольшей подпоследовательности (задача НОП)
Найти общую подпоследовательность наибольшей длины для двух данных последовательностей X и Y.
Решение перебором вариантов
Перебираем все подпоследовательности последовательности X и проверяя для каждой из них, не будет ли она подпоследовательностью последовательности Y.
Алгоритм будет работать экспоненциальное время, так как последовательность длины m имеет 2m подпоследовательностей.
Строение наибольшей общей подпоследовательности
Теорема 1.
Пусть Z = z1, z2, . . . zk - одна из наибольших общих подпоследовательностей для X = x1, x2, . . . xm и Y = y1, y2, . . . yn . Тогда:
1) если xm = yn, то zk =xm = yn и Zk-1является НОП для Xm-1 и Yn-1;
2)если xm ≠ yn, и zk ≠ xm , то Z является НОП для Xm-1 и Y.
3)если xm ≠ yn и zk ≠ yn , то Z является НОП для Xm и Yn-1.
НОП двух последовательностей содержит в себе наибольшую общую подпоследовательностей их префиксов. Таким образом задача о НОП обладает свойством оптимальности для подзадач.
Рекуррентная формула
Теорема 1 показывает, что нахождением НОП последовательностей и сводится к решению либо одной, либо двух подзадач. Если , то достаточно найти НОП последовательностей и дописать к ней в конце . Если же , то надо решить две подзадачи: найти НОП для , а затем найти НОП для . Более длинная из них и будет служить НОП для
Видно, что возникает перекрытие подзадач.
Чтобы найти НОП нам может понадобиться найти НОП и НОП ; каждая из этих задач содержит подзадачу нахождения НОП для
Обозначение
C[i, j] – длина НОП для последовательностей
Рекуррентное соотношение для c[i,j]
0, если i = 0 или j =0,
c[i-1,j-1]+1, если i, j >0 и xi = yj
max (c[i,j-1], c[i-1 ,j]), если i, j >0 и xi ≠ yj
Вычисление длины НОП
Так как различных подзадач всего Θ (mn) для решения задачи лучше использовать динамическое программирование.
Исходные данные:
последовательности X = x1, x2, . . . xm
и Y = y1, y2, . . . yn
результат:
таблицы c [0..m,0..n] и b[1..m,1..n]
LCS-LENGTH (X,Y)
1 m length[X]
2 n length[Y]
3 for i 1 to m
4 do c[i,0] 0
5 for j 1 to n
6 do c[0,j] 0
7 for i 1 to m
8 do for j 1 to n
9 do if xi = yj
10 then c[i,j] c[i-1,j-1]+1
1
1 b[i,j]
“ ”
12 else if c[i-1,j] ≥ c[i,j-1]
13 then c[i,j] c[i-1,j]
14 b[i,j] “ ↑ ”
15 else c[i,j] c[i,j-1]
16 b[i,j] “ ← ”
17 return c,b
Построение НОП
PRINT-LCS (b,X,i,j)
1 if i= 0 или j = 0
2 then return
3 if b[i,j] “ ”
4 then PRINT-LCS (b,X, i-1, j-1)
5 напечатать xi
6 elsif b[i,j] =“ ↑ ”
7 then PRINT-LCS (b,X, i-1, j)
8 else PRINT-LCS (b,X, i, j-1)
Время работы процедуры порядка О (m+n)
