22
Анализ комбинаторных алгоритмов Лекция №8 Динамическое программирование

Лекция 8 Динамическое программирование

Embed Size (px)

Citation preview

Page 1: Лекция 8 Динамическое программирование

Анализ комбинаторных алгоритмов

Лекция №8Динамическое

программирование

Page 2: Лекция 8 Динамическое программирование

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

Динамическое программирование – это метод построения эффективных алгоритмов, применяемый в задачах, в которых искомый ответ состоит из частей, каждая из которых в свою очередь дает оптимальное решение некоторой подзадачи.

Динамическое программирование полезно, если на разных путях многократно встречаются одни и те же подзадачи.

Page 3: Лекция 8 Динамическое программирование

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

Динамическое программирование часто применяется для решения оптимизационных задач (где есть много возможных решений и нужно выбрать оптимальное, согласно некоторому критерию).

A

A2A1

A11 A12 A21 A22

A

A2A1

A11 A12 A21 A22Динамическое программирование

Разделяй и властвуй

Page 4: Лекция 8 Динамическое программирование

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

Для того чтобы построить алгоритм, основанный на динамическом программировании надо: Описать строение оптимальных решений. Вывести рекуррентное отношение, связывающее

оптимальные значения для подзадач. Двигаясь снизу вверх, вычислить оптимальное

значение параметра для подзадач. Пользуясь полученной информацией построить

оптимальное решение.

Page 5: Лекция 8 Динамическое программирование

Оптимальное перемножение матриц

Дана последовательность из n матриц A1..An заданных размеров (Ai – (pi-1* pi)). Требуется найти такую расстановку скобок в последовательности, чтобы вычисление произведения требовало наименьшего числа умножений (элементов).

Решение этой задачи в лоб (полным перебором с помощью стека) будет работать со экспоненциальной (степенной) скоростью O(4n/n1.5).

Page 6: Лекция 8 Динамическое программирование

Оптимальное перемножение матриц

3107

12

112432

Если взять 3 матрицы размерами A1(10x100), A2(100x5) и A3(5x50), то количество перемножений в случае (A1*A2)*A3 равно 10*100*5 + 10*5*50 = 7500,

а в случае A1*(A2*A3) равно 10*100*50+100*5*50=75000.

Page 7: Лекция 8 Динамическое программирование

Строение оптимального решения.

Оптимальная расстановка скобок в цепочке матриц A1..An, разрывает последовательность на две части A1..Ak и Ak+1..An.

Стоимость решения (количество перемножений) строится из стоимости решения двух подзадач для цепочек A1..Ak и Ak+1..An и стоимости перемножения двух получившихся матриц.

Page 8: Лекция 8 Динамическое программирование

Рекуррентное соотношение

Исходя из строения оптимального решения можно сделать вывод, что стоимость перемножения последовательности матриц от i до j (m[i,j]) можно записать в рекуррентном виде так:m[i,j] = min{m[i,k]+m[k+1,j]+pi-1*pk*pj}

Над единственной матрицей никаких операций производить не надо, т.е. m[i,i]=0

Page 9: Лекция 8 Динамическое программирование

Вычисление оптимальной стоимости

На основе рекуррентного соотношения легко написать алгоритм, но он будет экспоненциально зависеть от n, т.е. он не лучше полного перебора.

Однако всего возможных пар (i,j) n2. Рост времени происходит экспоненциально из-за того, что алгоритм решает подзадачи по нескольку раз.

Page 10: Лекция 8 Динамическое программирование

Вычисление оптимальной стоимости

void MatrixChainOrder(p){ n = length(p)-1; for (i=1; i<=n; i++) m[i,i] = 0; for (l=2; i<=m; l++){ for (i=1;i<n-l+1; i++){

j = i+l-1;m[i,j] = maxint;for (k=i;k<j;k++){ q = m[i,k] + m[k+1, j] + p[i-1]*p[k]*p[j]; if (q<m[i,j]){

m[i,j]=q; s[i,j]=k; }}

} }}

Page 11: Лекция 8 Динамическое программирование

Вычисление оптимальной стоимости

1 2 3 4 5 6

1 0 15750 7875 9375 11875 15125

2 0 2625 4375 7125 10500

3 0 750 2500 5375

4 0 1000 3500

5 0 5000

6 0

A1 30x35

A2 35x15

A3 15x5

A4 5 x 10

A5 10x20

A6 20x25

Page 12: Лекция 8 Динамическое программирование

Вычисление оптимальной стоимости

1 2 3 4 5 6

1 1 1 3 3 3

2 2 3 3 3

3 3 3 3

4 4 5

5 5

6

Page 13: Лекция 8 Динамическое программирование

Вычисление оптимальной стоимости

В приведенном алгоритме «дублирование» исключалось благодаря тому, что решение происходило «снизу вверх» (сначала решались мелкие подзадачи, сохранялись их результаты, потом решались более крупные).

Можно решать ее «сверху вниз». Для этого результаты решенных подзадач заносятся в специальную таблицу, а потом решение этой подзадачи берется прямо из этой таблицы.

Page 14: Лекция 8 Динамическое программирование

Построение оптимального решения

void MatrixChainMultiply(A,s,i,j){ if (j>i){ X = MatrixChainMultiply(A,s,i,s[i,j]); Y = MatrixChainMultiply(A,s,s[i,j]+1,j); return MatrixMultiply(X,Y) } else return A;}

((A1(A2A3)((A4A5)A6))

Page 15: Лекция 8 Динамическое программирование

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

Динамическое программирование применимо, если задача обладает свойством оптималь-ности для подзадач.

Динамическое программирование особенно эффективно, если у оптимизационной задачи есть перекрывающиеся подзадачи.

Page 16: Лекция 8 Динамическое программирование

Триангуляция многоугольника

Многоугольник (полигон) – это замкнутая кривая на плоскости, составленная из отрезков, называемых сторонами.

Точка в которой сходятся две соседние стороны называется вершиной.

Несамопересекающийся многоугольник называется простым.

Множество точек плоскости внутри простого многоугольника, называется внутренностью.

Многоугольник выпуклый, если для любых двух точек внутри или на границе многоугольника, отрезок соединяющий их находится внутри или на границе.

Page 17: Лекция 8 Динамическое программирование

Триангуляция многоугольника

Если vi и vj – две не соседние вершины, то отрезок соединяющий их называется диагональю.

Триангуляция многоугольника – это набор диагоналей, разрезающих многоугольник на треугольники. Сторонами этих треугольников являются стороны многоугольника и его диагонали.

Page 18: Лекция 8 Динамическое программирование

Триангуляция многоугольника

v1

v2

v3 v4

v5

v0

v6v1

v2

v3 v4

v5

v0

v6

Page 19: Лекция 8 Динамическое программирование

Триангуляция многоугольника

Задача об оптимальной триангуляции многоугольника состоит в следующем. Дан выпуклый многоугольник. Требуется найти триангуляцию, для которой сумма весов треугольников будет наименьшей.

Пример весовой функции для треугольника – сумма длин его сторон.

Page 20: Лекция 8 Динамическое программирование

Триангуляция многоугольника

A1

A2

A3

A4

A5

A6

A2A3

A1(A2A3)

A4(A5A6)A5A6

(A1(A2A3))( A4(A5A6))

Page 21: Лекция 8 Динамическое программирование

Триангуляция многоугольника

Нахождение очередной диагонали при оптимальная триангуляция многоугольника vi..vj, разбивает его на два многоугольника vi..vk и vk+1..vj.

Стоимость триангуляции (вес треугольников) может быть вычислена как сумма стоимости триангуляции составных частей плюс вес треугольника с вершинами vi-1vkvj.

Page 22: Лекция 8 Динамическое программирование

Триангуляция многоугольника

Рекуррентное соотношение для задачи оптимальной триангуляции многоугольника можно записать так:m[i,i] = 0;m[i,j] = min { m[i,k] + m[k+1,j]+w(vi-1vkvj) }.

где w(vi-1vkvj) – вес треугольника vi-1vkvj