矩阵乘法(递归+动态规划+备忘录)C语言实现

题目:
给定n个矩阵{A1,A2,……,An},其中Ai与Ai+1是可乘的,i=1,2,……,n-1.考察这n个矩阵的连乘积A1A2……An,找出计算量最小的计算次序。
算法描述
1 递归
对于每一个i,j区间,有一个变量k表示从第k个数组划分,k的范围是[i,j-1],枚举一个区间的所有划分情况然后求最小值,这两个子情况我们还不知道,所以就要再次递归,求解每一种子情况的答案~:
(1)设一个r(“无限大”)让每个求得的值与它比较
(2)先求一个值,让之后每个求得的值与第一个值比较
2动态规划
自底向上
(1) 先初始化m[i][i]
(2) 依次从链长为[2:n]递增分别计算不同链长的矩阵连乘最优值。
(3) 先令m[i][j]最优值为矩阵链首元素划分下的值,后再进行对比。
(4) 计算k∈[i+1:j-1]递增划分下最优值,并和之前已保存的最优值对比,取小者。
3备忘录
自顶向下的方法又叫备忘录,也就是说,在递归的基础上,我们开个数组存值,当需要的值已经求得,直接返回,不用再重复计算了

递归

#include <stdio.h>
#include <stdlib.h>

int M(int i,int j,int p[6],int s[][7])
{
    if(i==j) 0;
    int r=10000000000;
    int temp,k;
    for(k=i;k<j;k++)
    {
        temp=M(i,k,p,s)+M(k+1,j,p,s)+p[i-1]*p[k]*p[j];
        if(temp<r)
        {
            r=temp;
            s[i][j]=k;
        }
    }
    return r;
}
void ConstructSolution(int i, int j, int s[][7])
{
    if (i == j)
        printf("A%d",i);
    else
    {
        printf("(");
        ConstructSolution(i,s[i][j],s);
        ConstructSolution(s[i][j]+1,j,s);
        printf(")");
    }
}
int main()
{
   int n=6;
   int p[]={30,35,15,5,10,20,25};
   int s[7][7]={0};
   int m[7][7]={0};
   M(1,n,p,s);
   ConstructSolution(1,n,s);
}

动态规划

#include <stdio.h>
#include <stdlib.h>
void MatrixChain(int p[6],int n,int m[][7],int s[][7])
{
int r=0,i=0,j=0,k=0,t=0;
for(i=1;i<=n;i++)
    m[i][i]==0;
for(r=2;r<=n;r++)
for(i=1;i<=n-r+1;i++)//n-r+1表示保证有r个矩阵相乘
{
    j=i+r-1;//当r=3时 有三个矩阵 但j=i+2,所以需要-1
    m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];//默认在初始下标之后断开,得到初始值
    s[i][j]=i;
    for(k=i+1;k<j;k++)
    {
        t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
        if(t<m[i][j]){
            m[i][j]=t;
            s[i][j]=k;
        }

    }
}
}
void TrackBack(int i,int j, int s[][7])
{
    if(i==j) return;
    TrackBack(i,s[i][j],s);//递归第一次断开之前
    TrackBack(s[i][j]+1,j,s);
    printf("A%d",i);
    printf(" and A%d",j);
    printf("\n");

}
int main()
{
   int n=6;
   int p[]={30,35,15,5,10,20,25};
   int s[7][7]={0};
   int m[7][7]={0};
   MatrixChain(p,n,m,s);
   TrackBack(1,n,s);
}

`备忘录

#include <stdio.h>
#include <stdlib.h>

int MemorizedMatrixChain(int n,int p[6],int m[7][7],int s[7][7])
{
    int i,j;
    for(i=0;j<=n;i++)
        for(j=i;j<=n;j++)
        m[i][j]=0;
        return LookupChain(1,n,p,m,s);
    }
int LookupChain(int i,int j,int p[6],int m[][7],int s[][7])
{
    int k;
    if(i==j) return m[i][j]=0;
    if(m[i][j]>0) return m[i][j];
    int u=LookupChain(i,i,p,m,s)+LookupChain(i+1,j,p,m,s)+p[i-1]*p[i]*p[j];
    s[i][j]=i;
    for(k=i+1;k<j;k++){
        int t=LookupChain(i,k,p,m,s)+LookupChain(k+1,j,p,m,s)+p[i-1]*p[k]*p[j];
    if(t<u){u=t;s[i][j]=k;}}
    m[i][j]=u;
    return m[i][j];
}
void ConstructSolution(int i, int j, int s[][7])
{
    if (i == j)
        printf("A%d",i);
    else
    {
        printf("(");
        ConstructSolution(i,s[i][j],s);
        ConstructSolution(s[i][j]+1,j,s);
        printf(")");
    }
}

int main()
{   int n=6;
    int p[]={30,35,15,5,10,20,25};
    int s[7][7]={0};
   int m[7][7]={0};
   MemorizedMatrixChain(n,p,m,s);
    ConstructSolution(1,n,s);

}

  • 6
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值