Matrix-chain product 矩阵链乘积

来源:互联网 发布:安卓怎么伪造mac 编辑:程序博客网 时间:2024/06/03 22:44

1.Matrix-chain product. The following are some instances.

a)      <3, 5, 2, 1,10>

b)     <2, 7, 3, 6, 10>

c)      <10, 3, 15, 12, 7, 2>

d)     <7, 2, 4, 15, 20, 5>

矩阵链乘积是可用动态规划解决的最佳化问题。给定一序列矩阵,期望求出相乘这些矩阵的最有效方法。此问题并不是真的去执行其乘法,而只是决定执行乘法的顺序而已。

因为矩阵乘法具有结合律,所有其运算顺序有很多种选择。换句话说,不论如何括号其乘积,最后结果都会是一样的。例如,若有四个矩阵A、B、C和D,将可以有:

(ABC)D = (AB)(CD) = A(BCD) = A(BC)D =...

但括号其乘积的顺序是会影响到需计算乘积所需简单算术运算的数目,即其效率。例如,设A为一10×30矩阵,B为30×5矩阵与C为5×60矩阵,则

(AB)C 有 (10×30×5) + (10×5×60) =1500 + 3000 = 4500 个运算

A(BC) 有 (30×5×60)+ (10×30×60) = 9000 + 18000 =27000 个运算

明显地,第一种方式要有效多了。既然已确认过此问题了,那要如何决定n个矩阵相乘的最佳顺序呢?可以比较每一顺序的运算量(使用蛮力),但这将需要时间O(2n),是一种非常慢且对大n不实在的方法。那解决方法,如我们将看到的,是将问题分成一套相关的子问题。以解答子问题一次而再使用其解答数次,即可以彻底地得出其所需时间。此一方法称为动态规划。代码如下:

#include<stdio.h>#include<stdlib.h>#define SIZE 10#define MAX 999999int m[SIZE][SIZE],s[SIZE][SIZE];int Matrix_chain_order(int p[]){int n = p[0]- 1;for (int i = 1;i<= n;++i){m[i][i] = 0;}for(int l = 2;l<= n;++l){for(int i = 1,j;i<=n-l+1;++i){j = i+l-1;m[i][j] = MAX;for(int k = i;k<= j-1;++k){int 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;}}}}return 0 ;}int Print_Optimal_Parens(int i,int j){if (i==j)printf("A");else {printf("(");Print_Optimal_Parens(i,s[i][j]);Print_Optimal_Parens(s[i][j]+1,j);printf(")");}return 0;}int main (){int p[SIZE+1];int size;printf("input the size of the chain:\n");scanf("%d",&size);if(size>SIZE){printf("the size is too big!\n");system("pause");return 0;}p[0]= size;printf("please input the chain:");for(int i = 1,j;i<=size;++i){scanf("%d",&j);p[i] = j;}Matrix_chain_order(p); Print_Optimal_Parens(1,size-1);printf("\n");system("pause");return 0;}



0 0
原创粉丝点击