- •1Динамическое программирование
- •1.1Введение
- •1.2Поиск максимальной суммы
- •1.3 Перемножение нескольких матриц
- •1.3.1Количество расстановок скобок
- •1.3.2Шаг 1: строение оптимальной расстановки скобок
- •1.3.3Шаг 2: рекуррентное соотношение
- •1.3.4Шаг 3: вычисление оптимальной стоимости
- •1.4Когда применимо динамическое программирование
- •1.4.1Оптимальность для подзадач
- •1.4.2Перекрывающиеся подзадачи
- •1.5Задача о замене оборудования
- •2Жадные алгоритмы
- •2.1Задача о выборе заявок
- •2.1.1Правильность алгоритма
- •2.2Когда применим жадный алгоритм
- •2.2.1Принцип жадного выбора
- •2.2.2Оптимальность для подзадач
- •2.2.3Жадный алгоритм или динамическое программирование?
1.3 Перемножение нескольких матриц
Пусть
нужно найти произведение
последовательности
матриц. Для перемножения двух матриц
будем пользоваться стандартным
алгоритмом, рассчитывая произведение
«строки на столбец». Но прежде надо
расставить скобки в произведении
,
чтобы указать порядок умножений. Будем
говорить, что в произведении матриц
полностью расставлены скобки, если это
произведение либо состоит из
одной-единственной матрицы, либо является
заключенным в скобки произведением
двух произведений с полностью
расставленными скобками. Поскольку
умножение матриц ассоциативно, конечный
результат вычислений не зависит от
расстановки скобок. Например, в
произведении
можно полностью расставить скобки пятью
разными способами:
,
во всех случаях ответ будет один и тот же.
Не влияя на ответ, способ расстановки скобок может сильно повлиять на стоимость перемножения матриц.
Если
нужно перемножить матрицы размерностей
и
,
то стандартный алгоритм потребует
умножений и примерно столько же сложений.
Далее будем оценивать стоимость
перемножения двух матриц числом
умножений.
Чтобы
увидеть, как расстановка скобок может
влиять на стоимость, рассмотрим
последовательность из трех матриц
размеров 10x100, 100х5 и 5х50 соответственно.
При вычислении
нужно
умножений, чтобы найти (10х5)-матрицу
,
а затем
умножений, чтобы умножить эту матрицу
на
.
Всего 7500 умножений. При расстановке
скобок
мы делаем
умножений для нахождения (100х50)-матрицы
,
плюс ещё
умножений, итого 75000 умножений. Тем
самым, первый способ расстановки скобок
в 10 раз выгоднее.
Задача
об умножении последовательности матриц
может быть сформулирована следующим
образом: дана последовательность из
матриц
заданных размеров (матрица
имеет размер
);
требуется найти такую (полную) расстановку
скобок в произведении
,
чтобы вычисление произведения требовало
наименьшего числа умножений.
1.3.1Количество расстановок скобок
Прежде
чем применять динамическое программирование
к задаче об умножении последовательности
матриц, стоит убедиться, что простой
перебор всех возможных расстановок
скобок не даст эффективного алгоритма.
Разобьём матрицы на группы по три;
произведение для каждой группы можно
вычислить двумя способами, так что для
матриц есть не менее
вариантов. Следовательно, алгоритм
полного перебора всевозможных вариантов
не будет эффективным (полиномиальным).
1.3.2Шаг 1: строение оптимальной расстановки скобок
Если мы собираемся воспользоваться динамическим программированием, то для начала должны описать строение оптимальных решений. Для задачи об умножении последовательности матриц это выглядит следующим образом.
Обозначим
для удобства через
матрицу, являющуюся произведением
.
Оптимальная расстановка скобок в
произведении
разрывает последовательность между
и
для некоторого
,
удовлетворяющего неравенству
.
Иными словами, при вычислении произведения,
диктуемом этой расстановкой скобок, мы
сначала вычисляем произведения
и
,
а затем перемножаем их и получаем
окончательный ответ
.
Стало быть, стоимость этой оптимальной
расстановки равна стоимости вычисления
матрицы
плюс стоимость вычисления матрицы
плюс стоимость перемножения этих двух
матриц.
Чем меньше умножений нам потребуется для вычисления и , тем меньше будет общее число умножений. Стало быть, оптимальное решение задачи о перемножении последовательности матриц содержит оптимальные решения задач о перемножении её частей. Это и позволяет применить динамическое программирование.
