美文网首页
矩阵连乘(DP+递归+备忘录)

矩阵连乘(DP+递归+备忘录)

作者: Super_邓帅 | 来源:发表于2017-01-02 22:41 被阅读0次


动态规划+递归+备忘录 解决矩阵连乘

问题描述:

给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘的,i=1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。

矩阵之间相乘的公式:


矩阵相乘公式

为什么会有矩阵连乘这个问题呢?

看下面一个例子,计算三个矩阵连乘{A1,A2,A3};维数分别为10*100 , 100*5 , 5*50 按此顺序计算需要的次数((A1*A2)*A3):10X100X5+10X5X50=7500次,按此顺序计算需要的次数(A1*(A2*A3)):10*5*50+10*100*50=75000次
  所以,确定一个最优的运算顺序,可以使计算量达到最小化。

动态规划解决:
#include<stdio.h>
#define N 6

void RecurMatrixChain(int* p,int** m){
    for(int r=2;r<N+1;r++){
        for(int i=1;i<=N-r+1;i++){
            int j=i+r-1;
            m[i][j]=m[i][i]+m[i+1][j]+p[i-1]*p[i]*p[j];                  //先设个初始值,在i和i+1间分开
            for(int k=i+1;k<j;k++){
                int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
                if(t<m[i][j]){
                    m[i][j]=t;
                }   
            }
        }
    }
}

int main(){
    int p[N+1]={30,35,15,5,10,20,25};
    
    int **m=new int*[N+1];       //m数组记录i到j的最优(最少)计算次数 
    for(int i=0;i<N+1;i++){
        m[i]=new int[N+1];
    }
    for(int i=1;i<N+1;i++){
        m[i][i]=0;
    }
    RecurMatrixChain(p,m);
    printf("少次数%d\n",m[1][N]);
    return 0;
} 
递归:
#include<stdio.h>
#define N 6

int RecurMatrixChain(int* p,int** s,int i,int j){
    if(i==j){
        return 0;
    }
    int u=32767;//代表从i到j的最少数乘次数
    for(int k=i;k<j;k++){
        int t=RecurMatrixChain(p,s,i,k)+RecurMatrixChain(p,s,k+1,j)+p[i-1]*p[k]*p[j];
        if(t<u){
            u=t;
            s[i][j]=k;
        }
    } 
    return u;
}

int main(){
    int p[N+1]={30,35,15,5,10,20,25};
    int **s=new int*[N+1];
    for(int i=0;i<N+1;i++){
        s[i]=new int[N+1];
    } 
    
    printf("最少次数%d\n",RecurMatrixChain(p,s,1,N));
    for(int i=0;i<N+1;i++){
        for(int j=0;j<N+1;j++){
            printf("%10d",s[i][j]);
        }
        printf("\n");
    } 
    
    return 0;
} 
备忘录:
#include<stdio.h>
#define N 6

int MemoMatrixChain(int* p,int** s,int** m,int i,int j){
    if(m[i][j]!=-1){
        return m[i][j];
    }
    if(i==j){
        return 0;
    }
    int u=32767;//u代表从i到j的最少数乘次数
    for(int k=i;k<j;k++){
        int t=MemoMatrixChain(p,s,m,i,k)+MemoMatrixChain(p,s,m,k+1,j)+p[i-1]*p[k]*p[j];
        s[i][j]=k;
        if(t<u){
            u=t;
            s[i][j]=k;
        }
        m[i][j]=u;
    } 
    return u;
}

int main(){
    int p[N+1]={30,35,15,5,10,20,25};
    
    int **s=new int*[N+1];        //s数组记录i到j的最优断开位置 
    for(int i=0;i<N+1;i++){
        s[i]=new int[N+1];
    }
    int **m=new int*[N+1];       //m数组记录i到j的最优(最少)计算次数 
    for(int i=0;i<N+1;i++){
        m[i]=new int[N+1];
    } 
    
    for(int i=1;i<N+1;i++){     //m数组的初始值为-1,表示问题都还没有解决 
        for(int j=1;j<N+1;j++){
            if(i==j){
                m[i][j]=0;
            }else{
                m[i][j]=-1;
            }
        }
    }
    
    printf("最少次数%d\n",MemoMatrixChain(p,s,m,1,N));
    return 0;
} 
运行截图

相关文章

  • 矩阵连乘(DP+递归+备忘录)

    动态规划+递归+备忘录 解决矩阵连乘 问题描述: 给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘...

  • 矩阵连乘

    给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积...

  • 矩阵连乘

    题目描述:给定n个矩阵{A1,A2,…,An},其中,Ai与Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括...

  • 算法代码

    递归与分治 二分搜索: 归并排序: 快速排序: 循环赛日程表: 动态规划 矩阵连乘: 最长公共子序列 贪心算法 活...

  • 矩阵连乘问题

    运行结果示例 理解:

  • 动态规划---矩阵连乘

    引言:马上期末考试了,最近在复习计算机算法分析与程序设计;动态规划,这门课程中最难的几个部分之一,上课老师讲时自己...

  • 斐波那契数列(Fibonacci)的几种实现

    斐波那契数列,定义: 递归求解 普通递归 尾递归 非递归递推解 利用矩阵计算 通过矩阵的快速幂实现 Matrix....

  • 第3章 动态规划——矩阵连乘最优计算方式查找

      问题:如何得到n个矩阵连乘的最少计算次数的计算顺序?先计算,还是先计算?其中,为矩阵的维度。 1、两个矩阵相乘...

  • 【算法笔记】动态规划:矩阵连乘问题

    连乘次数 是一个矩阵,是一个矩阵,相乘,得到的矩阵元素个数为,每个元素由次乘法得到,因此所需乘法次数为。 问题描述...

  • 动态规划之矩阵连乘

    动态规划: 将大问题划分为具有相同特征的小问题; 小问题之间往往相互联系; 从小问题一步步求解大问题。适合求解最优...

网友评论

      本文标题:矩阵连乘(DP+递归+备忘录)

      本文链接:https://www.haomeiwen.com/subject/qeupvttx.html