c语言计算一个m×n矩阵a和一个n×k矩阵b的乘积,第十五章 动态规划——矩阵链乘法...

#include#include

using namespacestd;#define A_ROWS 3

#define A_COLUMNS 2

#define B_ROWS 2

#define B_COLUMNS 3

void matrix_multiply(int A[A_ROWS][A_COLUMNS],int B[B_ROWS][B_COLUMNS],intC[A_ROWS][B_COLUMNS])

{if(A_COLUMNS!=B_ROWS)

{

cout<

exit(1);

}inti,j,k;for(i=0;i

{

C[i][j]=0;for(k=0;k

C[i][j]+=A[i][k]*B[k][j];

}

}intmain()

{intC[A_ROWS][B_COLUMNS];int A[A_ROWS][A_COLUMNS]={{1,2},{3,4},{5,6}};int B[B_ROWS][B_COLUMNS]={1,2,3,4,5,6};

matrix_multiply(A,B,C);inti,j;for(i=0;i

{for(j=0;j

cout<

cout<

}

}

0a322fbc7b466d9923464f16c822d30d.png

2、矩阵链乘问题描述

给定n个矩阵构成的一个链,其中i=1,2,...n,矩阵A的维数为pi-1pi,对乘积 A1A2...An以一种最小化标量乘法次数的方式进行加全部括号。

注意:在矩阵链乘问题中,实际上并没有把矩阵相乘,目的是确定一个具有最小代价的矩阵相乘顺序。找出这样一个结合顺序使得相乘的代价最低。

3、动态规划分析过程

1)最优加全部括号的结构

动态规划第一步是寻找一个最优的子结构。假设现在要计算AiAi+1....Aj的值,计算Ai...j过程当中肯定会存在某个k值(i<=k

有分析可以到最优子结构为:假设AiAi+1....Aj的一个最优加全括号把乘积在Ak和Ak+1之间分开,则Ai..k和Ak+1..j也都是最优加全括号的。

2)一个递归解

设m[i,j]为计算机矩阵Ai...j所需的标量乘法运算次数的最小值,对此计算A1..n的最小代价就是m[1,n]。现在需要来递归定义m[i,j],分两种情况进行讨论如下:

当i==j时:m[i,j] = 0,(此时只包含一个矩阵)

当i

3)计算最优代价

虽然给出了递归解的过程,但是在实现的时候不采用递归实现,而是借助辅助空间,使用自底向上的表格进行实现。设矩阵Ai的维数为pi-1pi,i=1,2.....n。输入序列为:p=,length[p] = n+1。使用m[n][n]保存m[i,j]的代价,s[n][n]保存计算m[i,j]时取得最优代价处k的值,最后可以用s中的记录构造一个最优解。书中给出了计算过程的伪代码,摘录如下:

MAXTRIX_CHAIN_ORDER(p)

n= length[p]-1;for i=1to ndo m[i][i] = 0;for t = 2 to n //t is the chain length

do for i=1 to n-t+1j=i+t-1;

m[i][j]=MAXLIMIT;for k=i to j-1q= m[i][k] + m[k+1][i] + qi-1qkqj;if q

then m[i][j]=q;

s[i][j]=k;return m and s;

C++代码:

#include

using namespacestd;#define N 6

#define MAXVALUE 100000000

void matrix_chain_order(int *p,int m[N+1][N+1],int s[N+1][N+1])

{inti,j,l,k;for(i=1;i<=N;i++)

m[i][i]=0;for(l=2;l<=N;l++)

{for(i=1;i<=N-l+1;i++)

{

j=i+l-1;

m[i][j]=MAXVALUE;for(k=i;k<=j-1;k++)

{int temp=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];if(temp

{

m[i][j]=temp;

s[i][j]=k;

}

}

}

}

}void print_optimal_parens(int s[N+1][N+1],int i,intj)

{if(i==j)

cout<

cout<

print_optimal_parens(s,i,s[i][j]);

print_optimal_parens(s,s[i][j]+1,j);

cout<

}

}intmain()

{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};inti,j;

matrix_chain_order(p,m,s);

cout<

{for(j=1;j<=N;++j)

cout<

cout<

}

cout<

{for(j=1;j<=N;++j)

cout<

cout<

}

cout<

print_optimal_parens(s,1,N);return 0;

}

deb0f09a832a4c19bd224effd88b9205.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值