Задача о порядке перемножения матриц
Задача о порядке перемножения матриц — классическая задача динамического программирования, в которой дана последовательность матриц
и требуется минимизировать количество скалярных операций для вычисления их произведения. Матрицы предполагаются совместимыми по отношению к матричному умножению (то есть количество столбцов совпадает с количеством строк матрицы).Подробное описание задачи
Произведение матриц — ассоциативная операция. Когда матрицы велики по одному измерению и малы по другому, количество скалярных операций может серьёзно зависеть от порядка перемножений матриц. Допустим, нам даны 3 матрицы
размерами соответственно и . Существует 2 способа их перемножения (расстановки скобок): и . В первом случае нам потребуется скалярных умножений, а во втором случае умножений — разница налицо. Поэтому может оказаться выгоднее потратить некоторое время на предобработку, решив, в каком порядке лучше всего умножать, чем умножать сразу в лоб. Таким образом, даны матриц: , , …, . Требуется определить, в каком порядке перемножать их, чтобы количество операций умножения было минимальным.Динамическое решение
Сведение задачи к подзадачам
Обозначим результат перемножения матриц
через , где . Если , то при любом способе расстановки скобок, последнее выполненное умножение для вычисления между матрицами и , i<=k<j, то есть чтобы вычислить надо сначала вычислить , потом и затем их перемножить. Заметим, что если способ расстановки скобок оптимален, то расстановка скобок в этих матрицах должна быть оптимальной, иначе если бы существовал более эффективный способ расстановки скобок в матрицах и , то мы могли бы получить за меньшее число умножений, получаем противоречие, что расстановка скобок в оптимальна. Таким образом мы свели задачу к подзадачам. Это означает, что возможно решить задачу, используя динамическое программирование на подотрезке.Рекурсивное решение
Обозначим через
минимальное количество скалярных умножений для вычисления матрицы . Получаем следующее рекуррентное соотношение:Объясняется оно просто: для того, чтобы найти произведение матриц
при i=j не нужно ничего делать — это и есть сама матрица . При нетривиальном случае мы перебираем все точки разбиения матрицы на матрицы и , ищем кол-во операций, необходимое чтобы их получить и затем перемножаем для получения матрицы .(Оно будет равно кол-ву операций, потраченное на решение подзадач + стоимость умножения матриц ). Считаем, что размеры матриц заданы в массиве и размер матрицы равен . В данном случае рекурсивный метод нельзя использовать напрямую — он будет экспоненциальным из-за большого кол-ва перекрывающихся подзадач.Динамическое программирование
Будем запоминать в двумерном массиве
результаты вычислений для подзадач, чтобы избежать пересчета для уже вычислявшихся подзадач. После вычислений ответ будет в (Сколько перемножений требуется для последовательности матриц от до — то есть ответ на поставленную задачу).Сложность алгоритма будет , так как у нас вариантов выбора и точек разделения для каждого варианта.Ссылки
использованы материалы ru.wikipedia.org [1]