• 矩阵连乘问题_动态规划


    1)问题引导

    一个demo

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int array1[3][4]={{1,1,1,2},{2,2,3,3},{3,4,4,4}};
     8     int array2[4][3]={{1,1,1},{2,2,2},{3,3,3},{4,4,4}};
     9     int array3[3][3];
    10     for(int i=0;i<3;i++){
    11         for(int j=0;j<3;j++)
    12         {
    13             for(int k=0;k<4;k++)
    14             {
    15                 array3[i][j]=array1[i][k]*array2[k][j];
    16             }
    17         }
    18     }
    19     for(int i=0;i<3;i++){
    20         for(int j=0;j<3;j++)
    21         {
    22             cout << array3[i][j] << " ";
    23         }
    24         cout << endl;
    25     }
    26 
    27     return 0;
    28 }

    从上面我们可以知道不同的结合方式,矩阵计算的次序数不一样,那么如何求这个最小次序数的划分,即如何结合。这就是矩阵连乘问题

    使用动态规划可以解决

    如下图,如果我们使用递归,则会产生大量的重复计算,复杂度太高,当然使用备忘录降低复杂度。不过更好的是使用递推

    递推算法分析如下:

     

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 void matrixChain(int n,int p[],int m[][100],int s[][100])//递推
     4 {
     5    for(int i=1;i<=n;i++){//对角线先为0
     6     m[i][i]=0;
     7    }
     8    for(int r=2;r<=n;r++){//一共n-1个对角线
     9     for(int i=1;i<=n-r+1;i++){//第i行
    10         int j=i+r-1;//在该行的对角线上的点对应的j值
    11         m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];//初始化此时在i处取得最优解
    12         s[i][j]=i;
    13         for(int k=i+1;k<j;k++){//如果有更小的则被替换
    14             int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
    15             if(t<m[i][j])
    16             {
    17                 m[i][j]=t;
    18                 s[i][j]=k;
    19             }
    20         }
    21     }
    22    }
    23 }
    24 void print_optimal_parents(int s[100][100],int i,int j)//打印划分的结果
    25  {
    26      if( i == j)
    27          cout<<"A"<<i;
    28      else
    29      {
    30          cout<<"(";
    31          print_optimal_parents(s,i,s[i][j]);
    32          print_optimal_parents(s,s[i][j]+1,j);
    33          cout<<")";
    34      }
    35 
    36  }
    37 int main()
    38 {
    39     int p[1000];//每个矩阵的行数和最后一个的列数
    40     int m[100][100];//存储最优子结构
    41     int s[100][100];//存储当前结构的最优断点
    42     memset(p,0,sizeof(p));
    43     memset(m,0,sizeof(m));
    44     memset(s,0,sizeof(s));
    45     cout << "请输入矩阵的个数"<< endl;
    46     int n;
    47     cin >> n;
    48     cout << "请依次输入每个矩阵的行数和最后一个矩阵的列数"<< endl;
    49     for(int i=0;i<=n;i++){
    50         cin >> p[i];
    51     }
    52     matrixChain(n,p,m,s);
    53     cout <<"这些矩阵相乘的最少次数是"<<m[1][n]<<endl;
    54 
    55      cout<<"结果是:"<<endl;
    56      print_optimal_parents(s,1,n);
    57     return 0;
    58 }

  • 相关阅读:
    spring-boot 访问时,加与不加项目名分析
    关于文章
    随笔
    工作小结五
    《文章翻译》PCA&SVD
    工作小结四
    工作小结三
    从零开始实现SSD目标检测(pytorch)(一)
    工作小结二
    《论文翻译》 GIOU
  • 原文地址:https://www.cnblogs.com/henuliulei/p/10074465.html
Copyright © 2020-2023  润新知