矩阵连乘问题

分析:

如果一个矩阵连乘积的计算次序已经确定,也就是说该连乘积已经完全加括号,则可依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。完全加括号的矩阵连乘积可递归的定义为:

①单个矩阵是完全加括号的; 

②矩阵连乘积A是完全加括号的,则A可表示为2个完全加括矩阵连乘积B和C的乘积并加括号,即

矩阵连乘问题

下面考虑运用动态规划法解矩阵连乘积的最优计算次序问题。按以下几个步骤进行:

矩阵连乘问题

矩阵连乘问题

矩阵连乘问题

 程序实现

#include <stdio.h>

#include <stdlib.h>

#define N 20

void MatrixChain(int p[N],int n,int m[N][N],int s[N][N])

//m[N][N]是矩阵相乘的最优次数矩阵,n是矩阵数

//s[N][N]是矩阵相乘最优断开位置矩阵,p[N]是默认相乘的矩阵

{

  for(int i=1;i<=n;i++)

    {

    m[i][i]=0;   //m[i][i]只有一个矩阵,所以相乘次数为0,即m[i][i]=0

    }

  for(int r=2;r<=n;r++)//至少是2个矩阵参与连乘,最多有n个

    {

    //公式i<j所以次数矩阵是一个上三角矩阵,遍历所有上三角位置

    for(int i=1;i<=n-r+1;i++)//n-r+1表示保证有r个矩阵相乘

    {

      int j=i+r-1;

      m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; //拿到从i到j矩阵连乘的次数

      s[i][j]=i;                          //拿到矩阵断开的位置值

      //寻找加括号不同,矩阵连乘次数的最小值,修改m[N][N],和断开的位置s[N][N]

      for(int k=i+1;k<j;k++)

      {

//公式i<j时得到的矩阵连乘的次数最优值

        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;//修改m[N][N],和断开的位置s[N][N]

          s[i][j]=k;

        }

      }

    }

 }

}

int main(void)

{

  int n,n1,m1,i,j=2;      //n是矩阵个数,n1 m1是矩阵的行和列

  int p[N]={0};           //存储矩阵的行和列数组

  int m[N][N]={0};        //存储矩阵与矩阵相乘的最小次数

  int s[N][N]={0};        //存储矩阵与矩阵相乘断开的位置

                          //获得矩阵规模

  printf("请输入矩阵个数:");

  scanf("%d",&n);

//依次输入n个矩阵的行列值

  for(i=1;i<=n;i++){

    printf("请输入第%d个矩阵的行和列(n1 m1):",i);

    scanf("%d %d",&n1,&m1);

    //把第一个矩阵行列值依次赋给数组p[0],p[1]

    if(i==1)

    {

      p[0]=n1;

      p[1]=m1;

    }

    //把矩阵的列值依次赋给数组p[n]

    else{

      p[j++]=m1;

    }

  }

  printf("\n记录矩阵行和列:\n");

  for(i=0;i<=n;i++){

    printf("%d ",p[i]);

  }

  printf("\n");

//通过MatrixChain函数得出m[N][N],s[N][N]

  MatrixChain(p,n,m,s);

//遍历输出最优次数矩阵

  printf("\n矩阵相乘的最小次数矩阵为:\n");

  for(i=1;i<=n;i++){

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

      printf("%d\t",m[i][j]);

    }

    printf("\n");

  }

//遍历输出最优断开位置矩阵

  printf("\n矩阵相乘断开的位置矩阵为:\n");

  for(i=1;i<=n;i++){

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

      printf("%d\t",s[i][j]);

    }

    printf("\n");

  }

//输出矩阵最小相乘次数

  printf("矩阵最小相乘次数为:%d\n",m[1][n]);

  return 0;

}

矩阵连乘问题

实验结果分析:

矩阵连乘问题

 

相关文章:

  • 2022-02-07
  • 2022-02-07
  • 2022-02-07
  • 2022-12-23
  • 2022-02-07
  • 2022-02-07
猜你喜欢
  • 2022-02-07
  • 2022-02-07
相关资源
相似解决方案