鱼C论坛

 找回密码
 立即注册
查看: 2736|回复: 0

[技术交流] 矩阵连乘的DP,两种方法(自下至上、自顶至下)

[复制链接]
发表于 2014-3-26 22:41:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 andalousie 于 2014-3-26 22:42 编辑

基本上百度一下都可以搜到矩阵连乘的算法。大家写的都差不多是同一个思路(bottom-up DP,自下而上的动态规划)。这里再提供一个速度相仿的自上而下(top-down)的解法。代码属于C++。
  1. // See the Cormen book for details of the following algorithm
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<climits>

  5. class MatrixChain
  6. {
  7.         int     n;
  8.         int ** m;
  9.         int ** s;
  10. public:
  11.         MatrixChain(int size)
  12.                 :n(size)
  13.         {
  14.                 /* For simplicity of the program, one extra row and one extra column are
  15.        allocated in m[][].  0th row and 0th column of m[][] are not used */
  16.                 m = new int* [n+1];
  17.                 s = new int* [n+1];
  18.                 for (int t = 0; t <= n; ++t)
  19.                 {
  20.                         m[t] = new int[n+1];
  21.                         s[t] = new int[n+1];
  22.                 }
  23.         }
  24.         ~MatrixChain()
  25.         {
  26.                 for (int t = 0; t <= n; ++t)
  27.                 {
  28.                         delete [] m[t];
  29.                         delete [] s[t];
  30.                 }
  31.                 delete [] s;
  32.                 delete [] m;
  33.         }
  34.         int MatrixChainOrder(int p[]);
  35.         int MatrixChainOrderTD(int p[]);
  36.         void traceback(int i, int j);
  37.         int topdown(int p[], int i, int j);
  38. };

  39. // Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
  40. int MatrixChain::MatrixChainOrder(int p[])
  41. {
  42.     int i, j, k, L, q;

  43.     /* m[i,j] = Minimum number of scalar multiplications needed to compute
  44.        the matrix A[i]A[i+1]...A[j] = A[i..j] where dimention of A[i] is
  45.        p[i-1] x p[i] */

  46.     // cost is zero when multiplying one matrix.
  47.     for (i = 1; i <= n; i++)
  48.         m[i][i] = 0;

  49.     // L is chain length.  
  50.     for (L=2; L<=n; L++)   
  51.     {
  52.         for (i=1; i<=n-L+1; i++)
  53.         {
  54.             j = i+L-1;
  55.             m[i][j] = INT_MAX;
  56.             for (k=i; k<=j-1; k++)
  57.             {
  58.                 // q = cost/scalar multiplications
  59.                 q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
  60.                 if (q < m[i][j])
  61.                                 {
  62.                     m[i][j] = q;
  63.                                         s[i][j] = k;
  64.                                 }
  65.             }
  66.         }
  67.     }
  68.     return m[1][n];
  69. }

  70. // Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
  71. int MatrixChain::MatrixChainOrderTD(int p[])
  72. {
  73.     for (int i = 1; i <= n; i++)
  74.         m[i][i] = 0;
  75.         for (int u = 0; u <= n; ++u)
  76.                 for (int v = 0; v <= n; ++v)
  77.                         s[u][v] = 0;

  78.     int result = topdown(p, 1, n);
  79.     return result;
  80. }

  81. void MatrixChain::traceback(int i, int j)
  82. {
  83.         if(i == j) return;
  84.         traceback(i, s[i][j]);
  85.         traceback(s[i][j]+1, j);
  86.         std::cout << "A[" << i << ',' <<s[i][j]
  87.                 << "] * A[" << s[i][j]+1 << ',' << j
  88.                 << "]\n";
  89. }

  90. int MatrixChain::topdown(int p[], int i, int j)
  91. {
  92.         if(i != j)
  93.         {
  94.                 if(s[i][j]) return m[i][j];
  95.                 m[i][j] = INT_MAX;
  96.                 int q;
  97.                 for(int k = i; k < j; ++k)
  98.                 {
  99.                         q = topdown(p, i, k) + topdown(p, k + 1, j) + p[i-1]*p[k]*p[j];
  100.                         if (q < m[i][j])
  101.                         {
  102.                                 m[i][j] = q;
  103.                                 s[i][j] = k;
  104.                         }
  105.                 }
  106.         }
  107.         return m[i][j];
  108. }

  109. int main()
  110. {
  111.         int arr[] = {3023, 3533, 155, 203, 2573, 3093};
  112.         int size = sizeof(arr)/sizeof(arr[0]) - 1;
  113.         MatrixChain mc(size);
  114.         printf("Minimum number of multiplications is %d \n",
  115.                        mc.MatrixChainOrder(arr));
  116.         printf("Minimum number of multiplications is %d \n",
  117.                        mc.MatrixChainOrderTD(arr));
  118.         mc.traceback(1, size);
  119.         return 0;
  120. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 23:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表