Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Дроздов С. Комбинаторные задачи и элементы теории вычислительной сложности.DOC
Скачиваний:
158
Добавлен:
02.05.2014
Размер:
648.7 Кб
Скачать

1.7. Метод динамического программирования

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

Рассмотренный выше метод ветвей и границ является попыткой ограничить перебор при движении по дереву сверху вниз. Метод ДП действует в какой-то мере противоположным образом.

Вспомним дерево перебора, изображенное на рис.1.1. Если корень дерева представляет исходную задачу, то с каждой вершиной обычно можно связать некоторую подзадачу того же типа, но меньшей размерности. Например, вершины на один уровень ниже корня являются корневыми для поддеревьев перебора, решающих задачи с различными фиксированными значениями x1. Листья дерева в таком случае представляют простейшие задачи, решение которых получается сразу, без перебора. В ходе решения исходной задачи выполняется решение всех подзадач. Как мы знаем, основной недостаток решения задач путем полного перебора заключается в астрономически большом количестве решаемых подзадач.

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

Примером ситуации, описанной в предыдущем абзаце, может служить решение задачи о рюкзаке. Допустим, нужно уложить рюкзак объемом 100 единиц, и при этом уже найдена оптимальная укладка для рюкзака объемом 20 единиц. Далее можно пытаться по-разному распорядиться остальными 80 единицами, всякий раз используя готовое решение для 20. В свою очередь, при решении задачи для объема 20 единиц может многократно понадобиться распорядиться меньшим объемом, например, 10 единицами, и если эта подзадача была заранее решена, то ее результат очень пригодится.

Другой пример – задача о коммивояжере. Допустим, мы рассмотрели все варианты проезда из города Aв городBс заездом вC,DиE:ACDEB,ADECB,AEDCBи т.п. При этом найден кратчайший из таких путей. Далее в ходе отыскания полного маршрута можно использовать этот результат всякий раз, когда будет рассматриваться маршрут изBвA, проходящий через все города, кромеC,DиE.

Решение комбинаторной задачи методом ДП выглядит следующим образом:

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

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

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

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

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

Рассмотрим применение метода ДП на примере алгоритма Беллманадля задачи о рюкзаке.

Итак, дано число товаров n, объем единицы каждого товараbi, стоимость единицы товараci, объем рюкзакаB. Требуется максимизировать суммарную стоимостьC(X) = cixiпри ограниченииbixi  B.

Пусть v(k,y)– это максимальное (неизвестное пока) значение, которое может принятьC(X)при условии, чтоbixiyи всеxiприi > kравны0. Постараемся вычислить значенияv(k,y)для всехk,0  k  n, и для всехy,0  y  B. Это означает, что вместо одной конкретной задачи о рюкзаке мы как бы будем решать серию задач с разным объемом рюкзака и разным количеством товаров. На самом деле нас интересует единственное значениеv(n,B), а все остальные значения нужны только как промежуточные.

Для определения v(k,y)будем использовать следующие соотношения:

v(1,y) = entier(y/b1)  c1 ;

v(k,y) = max(ckxk + v(k-1, y - bkxk)) для k > 1.

Максимум берется по всем значениям xk таким, что 0  x entier(y/bk), а функция entier, кто не помнит, означает целую часть числа.

Переведем эти соотношения на русский язык. Первое из них означает, что при единственном виде товара максимальная достижимая стоимость равна стоимости стольких единиц товара, сколько удалось втиснуть в рюкзак объема y.

Второе соотношение чуть посложнее. Мы можем положить в пустой рюкзак объема yлюбое число единицk-того товара от0доentier(y/bk). Пусть это число равноxk, тогда стоимостьk-того товара в рюкзаке будет равнаckxk, объем этого товара составитbkxk, а на все товары с номерами от1доk-1останетсяy bkxkединиц свободного объема. Какую максимальную стоимость можно получить от использования этого объема? По определению функцииv, это есть не что иное, какv(k-1, y bkxk)! Максимум по всем возможным значениямxkпозволяет определить наиболее выгодное количествоk-того товара.

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

Когда уравнения получены, решение задачи сводится к табулированию функции v(k,y)при возрастающих значенияхk.

Рассмотрим конкретный пример задачи о рюкзаке со следующими параметрами: n = 4,bi = (5, 7, 9, 4),ci = (9, 15, 19, 8),B = 20.

Прежде всего, можно получить хорошую оценку сверху. Если бы постановка задачи допускала вещественные значения xk, то решение было бы тривиально: подсчитать стоимость единицы объема каждого товара (ck/bk) и заполнить весь рюкзак тем товаром, для которого эта стоимость максимальна. Нетрудно видеть, что в данном примере наиболее выгодным является второй товар, для которого стоимость единицы объема равна 15/7, что при объеме 20 единиц дало бы общую стоимость 300 / 742.86. Очевидно, что дополнительное условие целочисленности может только ухудшить результат, а потому максимальная стоимость товара в рюкзаке не может быть больше 42.

Теперь протабулируем функцию v(k,y)для данного примера. Кроме значений функции, будем запоминать те значенияxk, при которых достигается максимум в уравнении Беллмана. Результаты сведены в табл.1.11.

Таблица 1.11

k = 1

k = 2

k = 3

k = 4

y

x1

v(1,y)

x2

v(2,y)

x3

v(3,y)

x4

v(4,y)

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

0

2

0

0

0

0

0

0

0

0

3

0

0

0

0

0

0

0

0

4

0

0

0

0

0

0

1

8

5

1

9

0

9

0

9

0

9

6

1

9

0

9

0

9

0

9

7

1

9

1

15

0

15

0

15

8

1

9

1

15

0

15

2

16

9

1

9

1

15

1

19

0

19

10

2

18

0

18

1

19

0

19

11

2

18

0

18

1

19

1

23

Продолжение табл. 1.11

k = 1

k = 2

k = 3

k = 4

y

x1

v(1,y)

x2

v(2,y)

x3

v(3,y)

x4

v(4,y)

12

2

18

1

24

0

24

0 (3)

24

13

2

18

1

24

0

24

1

27

14

2

18

2

30

0

30

0

30

15

3

27

2

30

0

30

2

31

16

3

27

2

30

1

34

0

34

17

3

27

1

33

1

34

2

35

18

3

27

1

33

2

38

0 (1)

38

19

3

27

2

39

0

39

0 (3)

39

20

4

36

2

39

0

39

1

42

Заполнение таблицы выполняется согласно приведенным выше уравнениям Беллмана. Для примера рассмотрим заполнение двух ячеек.

При k = 2,y = 7entier(y/bk) = entier(7/7) = 1, поэтому переменнаяxkможет принимать значения 0 и 1. Отсюда имеем:

v(2, 7) = max((150 + v(1, 7–70)), (151 + v(1, 7–71))) =

= max((0+v(1,7)), (15+v(1,0))) = max(0+9, 15+0) = 15.

При k = 4,y = 12entier(y/bk) = entier(12/4) = 3,xkможет принимать значения 0, 1, 2 и 3. Имеем:

v(4, 12) = max((80 + v(3, 12–40)), (81 + v(3, 12–41),

(82 + v(3, 12–42), (83 + v(3, 12–43))) =

= max((0+v(3,12)), (8+v(3,8)), (16+v(3,4)), (24+v(3,0))) =

= max(0+24, 8+15, 16+0, 24+0) = 24.

В данном случае максимум достигается при двух разных значениях xk, что отражено в табл.1.11. Это означает, что имеется несколько разных планов с одинаковым значением целевой функции.

Аналогично заполняются и остальные клетки таблицы.

Отметим следующую деталь. При заполнении k-того столбца таблицы используются только значения параметровbk,ckи значенияv(k-1, y)из предыдущего столбца таблицы. С точки зрения программирования это означает, что в оперативной памяти можно хранить не всю таблицу, а только два столбца, предыдущий и текущий.

Собственно говоря, заполнять все строки таблицы при k = 4было вовсе не обязательно, поскольку важна лишь последняя строка, которая показывает, что максимальная достижимая стоимость товаров 4 видов в рюкзаке объемом 20 составляет 42 единицы. Приятно отметить, что это совпадает с полученной выше верхней оценкой!

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

Из четвертого столбца таблицы видим, что значение v(4,20) = 42достигается приx4 = 1. Отсюда следует, что на первые три вида товаров остается20 – b4x4 = 16единиц объема. Из третьего столбца видно, чтоv(3,16) = 34приx3 = 1. На два первых товара остается16 – b3x3 = 7единиц объема. Из второго столбцаv(2,7) = 15приx2 = 1. На первый товар остается7 – b2x2 = 0единиц объема, и можно уже даже не смотреть в таблицу, чтобы сказать, чтоx1 = 0. Итак, оптимальным будет планX = (0, 1, 1, 1).

Оценим, как зависит трудоемкость алгоритма Беллмана от основных параметров задачи: числа видов товаров nи объема рюкзакаB. Число столбцов таблицы равноn, а число строк –B+1. Трудоемкость вычисления одного значения в таблице пропорциональна количеству членов, из которых выбирается максимум, а это количество пропорциональноB. Таким образом,T(n,B) = O(nB2).