动态规划之矩阵链乘法
2017-06-10 00:05
309 查看
问题描述与分析:
给定n个矩阵的序列,(A1,A2…An),我们希望计算他们的乘积A1*A2..*An
例如如果矩阵链为(A1 A2 A3 A4 ) 那么共有五种完全括号化的形式:
运用动态规划方法: 第一步:寻找最优子结构,为了对AiAi+1..Aj 进行括号化,假设最优括号化方案在 Ak,Ak+1之间,则首先计算 Ai..k和Ak+1..Aj 第二步:一个递归求解方案,令m[i,j]为Ai...j所需标量乘法的最小值 即 m[i,j]=m[i,k]+m[k+1,j]+pi-1*pk*pj 矩阵 Ai 的大小 为 pi-1*pi 第三步: 计算最优代价: void matrix_chain_order(int *p, int len, int m[N + 1][N + 1], int s[N + 1][N + 1]) { int i, j, k, t; for (i = 0; i <= N; ++i) m[i][i] = 0; for (t = 2; t <= N; t++) //当前链乘矩阵的长度 { for (i = 1; i <= N - t + 1; i++) //从第一矩阵开始算起,计算长度为t的最少代价 { j = i + t - 1;//长度为t时候的最后一个元素 m[i][j] = MAXVALUE; //初始化为最大代价 for (k = i; k <= j - 1; k++) //寻找最优的k值,使得分成两部分k在i与j-1之间 { int temp = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; if (temp < m[i][j]) { m[i][j] = temp; //记录下当前的最小代价 s[i][j] = k; //记录当前的括号位置,即矩阵的编号 } } } } }
下面实现示例:
p={30*35,35*15,15*5,5*10,10*20,20*25};
N=6;
#include <iostream> using namespace std; #define N 6 #define MAXVALUE 1000000 void matrix_chain_order(int *p, int len, int m[N + 1][N + 1], int s[N + 1][N + 1]); void print_optimal_parents(int s[N + 1][N + 1], int i, int j); int main() { int p[N + 1] = { 30,35,15,5,10,20,25 }; int m[N + 1][N + 1] = { 0 }; int s[N + 1][N + 1] = { 0 }; int i, j; matrix_chain_order(p, N + 1, m, s); cout << "m value is: " << endl; for (i = 1; i <= N; ++i) { for (j = 1; j <= N; ++j) cout << m[i][j] << " "; cout << endl; } cout << "s value is: " << endl; for (i = 1; i <= N; ++i) { for (j = 1; j <= N; ++j) cout << s[i][j] << " "; cout << endl; } cout << "The result is:" << endl; print_optimal_parents(s, 1, N); system("pause"); return 0; } void matrix_chain_order(int *p, int len, int m[N + 1][N + 1], int s[N + 1][N + 1]) { int i, j, k, t; for (i = 0; i <= N; ++i) m[i][i] = 0; for (t = 2; t <= N; t++) //当前链乘矩阵的长度 { for (i = 1; i <= N - t + 1; i++) //从第一矩阵开始算起,计算长度为t的最少代价 { j = i + t - 1;//长度为t时候的最后一个元素 m[i][j] = MAXVALUE; //初始化为最大代价 for (k = i; k <= j - 1; k++) //寻找最优的k值,使得分成两部分k在i与j-1之间 { int temp = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; if (temp < m[i][j]) { m[i][j] = temp; //记录下当前的最小代价 s[i][j] = k; //记录当前的括号位置,即矩阵的编号 } } } } } //s中存放着括号当前的位置 void print_optimal_parents(int s[N + 1][N + 1], int i, int j) { if (i == j) cout << "A" << i; else { cout << "("; print_optimal_parents(s, i, s[i][j]); print_optimal_parents(s, s[i][j] + 1, j); cout << ")"; } }
m value is: 0 15750 7875 9375 11875 15125 0 0 2625 4375 7125 10500 0 0 0 750 2500 5375 0 0 0 0 1000 3500 0 0 0 0 0 5000 0 0 0 0 0 0 s value is: 0 1 1 3 3 3 0 0 2 3 3 3 0 0 0 3 3 3 0 0 0 0 4 5 0 0 0 0 0 5 0 0 0 0 0 0 The result is: ((A1(A2A3))((A4A5)A6))请按任意键继续. . .
相关文章推荐
- 动态规划之矩阵链乘法-matrix-chain muliplication problem(dp)
- 动态规划之矩阵链乘法理解
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 动态规划之矩阵链乘法问题
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 动态规划之矩阵链乘法
- 动态规划之矩阵链乘法
- 动态规划--矩阵连乘的最优乘法顺序
- 动态规划--寻找最佳矩阵乘法次序
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 动态规划 - 之 - 矩阵链式乘法数
- 动态规划之矩阵链乘法(第15章)
- C++实现矩阵链乘法利用动态规划及运行实例结果
- poj1651 最优矩阵乘法动态规划解题
- 矩阵乘法的动态规划解法
- 如何使用矩阵乘法加速动态规划——以[SDOI2009]HH去散步为例
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 动态规划之矩阵链乘法
- C++实现矩阵链乘法利用动态规划及运行实例结果
- 动态规划之矩阵连乘法