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

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

Определение подпроблем

Конечно, один способ решить матричную проблему продукта цепи только к enu-merate все возможные способы ввести выражение для A, и определите число умножения, выполненного каждым. К сожалению, набор всего различного parenthesizations выражения для A равен в числе к набору всех различных двоичных деревьев, у которых есть n внешние узлы. Это число показательно в n. Таким образом, это прямое («грубая сила») пробеги алгоритма в показательное время, поскольку есть показательное число способов ввести ассоциативное арифметическое выражение.

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

из которых вычисляет лучший parenthesization для некоторого подвыражения Ай Ai+1  j.

Как краткое примечание, мы используем Ni, j, чтобы обозначить минимальное число multipli-

катионы должны были вычислить это подвыражение. Таким образом оригинальная матричная цепь - проблема продукта может быть характеризована как то из вычисления ценности N0, n-1. Это наблюдение важно, но нам нужен еще один, чтобы применить динамический программный метод.

Характеристика оптимальных решений

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

В случае матричной проблемы продукта цепи мы замечаем, что, никакая циновка - трижды, как мы вводим подвыражение, должна быть некоторая заключительная матрица mul-tiplication, что мы выступаем. Таким образом, полный parenthesization подвыражения

Ай Ai+1  j должен иметь форму (Ай Ak) (Ak+1  j), для некоторого kÎя, я +

1..., j-  Ak) и (Ak+1  j) должны также быть решены оптимально. Если это не было так, то там был бы

будьте глобальным оптимальным, у которого была одна из этих подпроблем, решенных подоптимально. Но это

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

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

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

Мы можем поэтому характеризовать оптимальное подпроблемное решение, Ni, j, как

Ni, j = imki <j Ni, k + Nk+1, j + didk+1d j+1, n

£

559

где Ni, я = 0, начиная ни с какой работы необходим для единственной матрицы. Таким образом, Ni, j является минимумом, принятым, все возможные места, чтобы выполнить заключительное умножение, числа умножения должны были вычислить каждое подвыражение плюс число умножения, должен был выполнить заключительное матричное умножение.

Заметьте, что есть разделение подпроблем, продолжающихся, который препятствует тому, чтобы мы делили проблему на абсолютно независимые подпроблемы (как мы должны были бы сделать, чтобы применить технику делить-и-побеждать). Мы можем, тем не менее, использовать уравнение для Ni, j, чтобы получить эффективный алгоритм, вычисляя Ni, j ценности восходящим способом, и храня промежуточные решения в столе Ni, j ценности. Мы

может начаться достаточно просто, назначив Ni, я = 0 поскольку я = 0, 1..., n- 1. Мы можем тогда

примените общее уравнение для Ni, j, чтобы вычислить Ni, i+1 ценности, так как они зависят только

на Ni, мне и Ni+1, i+1 ценности, которые доступны. Учитывая Ni, i+1 ценности, мы можем тогда вычислить Ni, i+2 ценности, и так далее. Поэтому, мы можем построить Ni, j ценности от ранее вычисленных ценностей, пока мы не можем наконец вычислить ценность N0, n-1, который является числом, которое мы ищем. Детали этого динамического программного решения даны в Кодовом Фрагменте 12.1.

Алгоритм MatrixChain (d0..., dn):

Вход: Последовательность d0..., dn Продукции целых чисел: Поскольку я, j = 0..., n- 1, минимальное число умножения Ni, j

должен был вычислить продукт Ай Ai+1  j, где Ak - dk dk+1 матрица

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

Ni, я¬ 0

для b ¬ 1к n- 1 делают

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

j¬ i+b Ni, j¬ + ¥для k¬ i к j- 1 делают

Ni, j¬ минута Ni, j, Ni, k + Nk+1, j + didk+1d j+1. Кодовый Фрагмент 12.1: Динамический программный алгоритм для матричной цепи - проблема продукта.

Таким образом мы можем вычислить N0, n-1 с алгоритмом, который состоит прежде всего из трех вложенных для петель. Внешняя петля выполнена n времена. Петля внутри - exe-cuted в большинство n раз. И в большинство n раз также выполнена самая внутренняя петля. Поэтому, полная продолжительность этого алгоритма - O (n3).

560