矩阵链乘法
来源:互联网 发布:海岸线数据下载 编辑:程序博客网 时间:2024/06/05 11:02
Description
给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。
Input
有N个矩阵连乘,用一行有n+1个数数组表示,表示是n个矩阵的行及第n个矩阵的列,它们之间用空格隔开.
Output
你的输出应该有C行,即每组测试数据的输出占一行,它是计算出的矩阵最少连乘积次数,输出最优全括号结构
Sample Input
10 100 5 50
Sample Output
7500
分析:
矩阵链乘法问题描述:
给定由n个矩阵构成的序列[A1,A2,...,An],对乘积A1A2...An,找到最小化乘法次数的加括号方法。
1)寻找最优子结构
此问题最难的地方在于找到最优子结构。对乘积A1A2...An的任意加括号方法都会将序列在某个地方分成两部分,也就是最后一次乘法计算的地方,我们将这个位置记为k,也就是说首先计算A1...Ak和Ak+1...An,然后再将这两部分的结果相乘。
最优子结构如下:假设A1A2...An的一个最优加括号把乘积在Ak和Ak+1间分开,则前缀子链A1...Ak的加括号方式必定为A1...Ak的一个最优加括号,后缀子链同理。
一开始并不知道k的确切位置,需要遍历所有位置以保证找到合适的k来分割乘积。
2)构造递归解
设m[i,j]为矩阵链Ai...Aj的最优解的代价,则
┌ 0 如果i = j
m[i,j] = │
└ min(i≤k<j) {m[i,k] + m[k+1,j] + Ai.row*Ak.col*Aj.col} 如果i < j
3)构建辅助表,解决重叠子问题
从第二步的递归式可以发现解的过程中会有很多重叠子问题,可以用一个nXn维的辅助表t[n][n]来保存子问题的解,表中每个元素包含2个信息,分别是最优乘积代价及其分割位置k 。
辅助表t[n][n]可以由2种方法构造,一种是自底向上填表构建,该方法要求按照递增的方式逐步填写子问题的解,也就是先计算长度为2的所有矩阵链的解,然后计算长度3的矩阵链,直到长度n;另一种是自顶向下填表的备忘录法,该方法将表的每个元素初始化为某特殊值(本问题中可以将最优乘积代价设置为一极大值),以表示待计算,在递归的过程中逐个填入遇到的子问题的解。
备忘录法会比自底向上法慢一个常数因子,因为前者有递归调用的代价,维护表格的开销也稍大。
转至http://blog.csdn.net/chenwenshi/article/details/6056015
#include<stdlib.h>#include<stdio.h>#include <memory.h>#define N 6void Print_OPTIMAL_PARENS(int s[N+1][N+1],int i,int j) //定义函数打印最优全括号的结果{if(i==j)printf("A%d",i);else{printf("(");Print_OPTIMAL_PARENS(s,i,s[i][j]); //在分裂处进行递归调用Print_OPTIMAL_PARENS(s,s[i][j]+1,j);printf(")");}}int main(){int matrix[N+1]; //matrix中记录矩阵的维数int i,j,k,q;int m[N+1][N+1]; //m中记录矩阵连乘的次数 int s[N+1][N+1]; //s[i][j]中记录了对Ai...Aj进行分裂的最优的k值for(i=0;i<=N;i++)scanf("%d",&matrix[i]);memset(m,0,(N+1)*(N+1)*sizeof(int));for(j=1;j<=N;j++) for (i=j;i>=1;i--) //当i=j时,m[i][j]=0, { //当i<j时,m[i][j]=min{m[i][k]+m[k+1][j]+p(i-1)p(k)p(j)} i=<k<j if (j==i)m[i][j]=0;else{m[i][j]=600000; for (k=i;k<j;k++){q=m[i][k]+m[k+1][j]+matrix[i-1]*matrix[k]*matrix[j];if (q<m[i][j]){m[i][j]=q;s[i][j]=k;}}}}printf("%d/n",m[1][N]);Print_OPTIMAL_PARENS(s,1,N);return 0;}
转至http://blog.csdn.net/chenwenshi/article/details/6056015
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 15.2 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 【DP】矩阵链乘法
- 矩阵链乘法
- 矩阵链乘法
- 链矩阵乘法
- UltraEdit中如何设置Tab键缩进量?
- Google 三大论文中文版之The Google File System 中文版
- Linux下Kill函数用法
- MVC框架比较-struts1、struts2、springMVC
- 分数类中的运算符重载
- 矩阵链乘法
- JSP动作元素
- __asm__ __volatile__ GCC的内嵌汇编语法
- Google 三大论文中文版之Google MapReduce 中文版
- DOCSIS Config file- Ethernet LLC Packet Classification Encodings
- 重学QT,以前只学习框架,而没有认识其内部,从零开始
- 关于SELECTION-SCREEN
- CCNA第二章作业
- 如果让我重做一次研究生--王泛森院士(台湾中央研究院)