动态规划——矩阵链乘法
2008-02-01 14:22
281 查看
矩阵链乘法
问题描述:给定n个矩阵构成的一个链<A[1], A[2], ... , A
>,其中i = 1, 2, ... , n,矩阵A[i]的维数为p[i-1]*p[i],对乘积A[1]A[2]...A
以一种最小化标量乘法次数的方式进行加全部括号。
步骤1:最优加全部括号的结构
用记号A[i..j]表示乘积A[i]A[i+1]...A[j]求值的结果,其中i <= j。假设A[i]A[i+1]...A[j]的一个最优加全部括号把乘积在A[k]和A[k+1]之间分开,则对A[i]A[i+1]...A[j]最优加全部括号的“前缀”子链A[i]A[i+1]...A[k]的加全部括号必须是A[i]A[i+1]...A[k]的一个最优加全部括号。
步骤2:一个递归解
设m[i][j]为计算矩阵A[i..j]所需的标量乘法运算次数的最小值;对整个问题,计算A[1..n]的最小代价就是m[1]
。
假设最优加全部括号将乘积A[i]A[i+1]...A[j]从A[k]和A[k+1]之间分开,i <= k < j。则:
m[i][j] = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
关于对乘积A[i]A[i+1]...A[j]加全部括号的最小代价的递归定义为:
m[i][j] = 0 if i == j
m[i][j] = min(i<=k<j){m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]} if i < j
步骤3:计算最优代价
用迭代自底向上的表格法来计算最优代价。
步骤4:构造一个最优解
利用保存在表格s
内的、经过计算的信息来构造一个最优解。按最优方式计算A[1..n]时,最终矩阵相乘次序是A[1..s[1]
]A[a[1]
+1..n]。之前的乘法可以递归地进行。
MatrixChainMain.c
#include <stdio.h>
#include <limits.h>
#define LENGTH 6
/**//*
*p[i]:矩阵Ai的列数或Ai-1的行数
*m[i][j]:纪录Ai - Aj的矩阵连乘的最小代价
*s[i][j]:纪录Ai - Aj之间得到最小连乘代价时的分割点
*/
void MatrixChainOrder(int p[], int m[][LENGTH], int s[][LENGTH])
...{
int i, j, k, len, q;
for(i=0; i<LENGTH; i++)
m[i][i] = 0;
for(len=2; len<=LENGTH; len++) //len为矩阵链的长度
...{
for(i=0; i<(LENGTH-len+1); i++)
...{
j = i + len - 1;
m[i][j] = INT_MAX;
//计算Ai - Aj最优代价
for(k=i; k<j; k++)
...{
q = m[i][k] + m[k+1][j] +p[i]*p[k+1]*p[j+1];
if(q < m[i][j])
...{
m[i][j] = q;
s[i][j] = k;
}
}
}
}
}
void PrintOptimalParens(int s[][LENGTH], int i, int j)
...{
if(i == j)
printf("A%d", i);
else
...{
printf("(");
PrintOptimalParens(s, i, s[i][j]);
PrintOptimalParens(s, s[i][j]+1, j);
printf(")");
}
}
int main(int argc, char **argv)
...{
int p[LENGTH+1] = ...{30, 35, 15, 5, 10, 20, 25};
int m[LENGTH][LENGTH];
int s[LENGTH][LENGTH];
MatrixChainOrder(p, m, s);
PrintOptimalParens(s, 0, LENGTH-1);
printf(" ");
return 0;
}
问题描述:给定n个矩阵构成的一个链<A[1], A[2], ... , A
>,其中i = 1, 2, ... , n,矩阵A[i]的维数为p[i-1]*p[i],对乘积A[1]A[2]...A
以一种最小化标量乘法次数的方式进行加全部括号。
步骤1:最优加全部括号的结构
用记号A[i..j]表示乘积A[i]A[i+1]...A[j]求值的结果,其中i <= j。假设A[i]A[i+1]...A[j]的一个最优加全部括号把乘积在A[k]和A[k+1]之间分开,则对A[i]A[i+1]...A[j]最优加全部括号的“前缀”子链A[i]A[i+1]...A[k]的加全部括号必须是A[i]A[i+1]...A[k]的一个最优加全部括号。
步骤2:一个递归解
设m[i][j]为计算矩阵A[i..j]所需的标量乘法运算次数的最小值;对整个问题,计算A[1..n]的最小代价就是m[1]
。
假设最优加全部括号将乘积A[i]A[i+1]...A[j]从A[k]和A[k+1]之间分开,i <= k < j。则:
m[i][j] = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
关于对乘积A[i]A[i+1]...A[j]加全部括号的最小代价的递归定义为:
m[i][j] = 0 if i == j
m[i][j] = min(i<=k<j){m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]} if i < j
步骤3:计算最优代价
用迭代自底向上的表格法来计算最优代价。
步骤4:构造一个最优解
利用保存在表格s
内的、经过计算的信息来构造一个最优解。按最优方式计算A[1..n]时,最终矩阵相乘次序是A[1..s[1]
]A[a[1]
+1..n]。之前的乘法可以递归地进行。
MatrixChainMain.c
#include <stdio.h>
#include <limits.h>
#define LENGTH 6
/**//*
*p[i]:矩阵Ai的列数或Ai-1的行数
*m[i][j]:纪录Ai - Aj的矩阵连乘的最小代价
*s[i][j]:纪录Ai - Aj之间得到最小连乘代价时的分割点
*/
void MatrixChainOrder(int p[], int m[][LENGTH], int s[][LENGTH])
...{
int i, j, k, len, q;
for(i=0; i<LENGTH; i++)
m[i][i] = 0;
for(len=2; len<=LENGTH; len++) //len为矩阵链的长度
...{
for(i=0; i<(LENGTH-len+1); i++)
...{
j = i + len - 1;
m[i][j] = INT_MAX;
//计算Ai - Aj最优代价
for(k=i; k<j; k++)
...{
q = m[i][k] + m[k+1][j] +p[i]*p[k+1]*p[j+1];
if(q < m[i][j])
...{
m[i][j] = q;
s[i][j] = k;
}
}
}
}
}
void PrintOptimalParens(int s[][LENGTH], int i, int j)
...{
if(i == j)
printf("A%d", i);
else
...{
printf("(");
PrintOptimalParens(s, i, s[i][j]);
PrintOptimalParens(s, s[i][j]+1, j);
printf(")");
}
}
int main(int argc, char **argv)
...{
int p[LENGTH+1] = ...{30, 35, 15, 5, 10, 20, 25};
int m[LENGTH][LENGTH];
int s[LENGTH][LENGTH];
MatrixChainOrder(p, m, s);
PrintOptimalParens(s, 0, LENGTH-1);
printf(" ");
return 0;
}
相关文章推荐
- 动态规划~~矩阵链乘法
- 动态规划总结
- 超级台阶 分类: 算法 动态规划 2014-10-28 08:20 77人阅读 评论(0) 收藏
- 动态规划
- HDU1421 搬寝室 动态规划
- UVa10259 - Hippity Hopscotch(动态规划)
- 动态规划第五讲——leetcode上的题目动态规划汇总(上)
- 动态规划 - 拦截导弹
- 动态规划:从新手到专家(关于动态规划算法最精彩的中文描述,没有之一)
- hdoj preoblem 1598 find the most comfortable road (并查集&&动态规划)
- A*、Dijkstra、动态规划、红黑树、优先搜索、KMP
- HDOJ题目1231最大连续子序列(动态规划)
- POJ1080 Human Gene Functions 动态规划 LCS的变形
- n个骰子各点数和出现的概率--动态规划
- uvaoj 357 - Let Me Count The Ways 动态规划
- zoj 2604 Little Brackets(动态规划+递推+java)
- poj 3635 Full Tank 动态规划思想在spfa算法中的应用
- Best Time to Buy and Sell Stock I,II,III 动态规划
- 最长公共子序列(动态规划) nyoj36
- 【动态规划】【记忆化搜索】【dfs】bzoj2748 [HAOI2012]音量调节