矩阵连乘问题

来源:互联网 发布:植物生长算法 编辑:程序博客网 时间:2024/05/21 17:51

多个矩阵连乘,给这样的矩阵序列加括号,使乘法的计算次数最小。使用的是动态规划的思想。

#include <iostream>#include <string>#include <sstream>using namespace std;void MatrixChain(int n, int *p, int **m, int **s){    /*    找到矩阵链乘法需要的最小乘法次数,以及划分的方式    :param n: 矩阵A的个数    :param p: 存放矩阵维度的数组,有n+1个元素    :param m: m[i, j]存放矩阵i到矩阵j              这个矩阵序列在最优划分下的乘法次数    :param s: s[i, j]存放矩阵i到矩阵j              这个矩阵序列在最优划分下时,断开的位置k              在位置k断开,代表的是将A_k和A_(k+1)分开    m, s下标从1开始    m[i][j] = 0, i=j    m[i][j] = min{m[i][k], m[k+1][j]+p[i-1]*p[k]p[j]} for k /in [i,j), i<j    */    for(int i = 1; i <= n; ++i) m[i][i] = 0;    for(int r = 1; r < n; ++r){  // r是间隔,计算m[i][i+r]        for(int i = 1; i <= n-r; ++i){            int j = i+r;            m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j]; // 把i, i+1之间断开            s[i][j] = i;            for(int k = i+1; k < j; ++k){  // 划分点从k枚举到j-1                int tmp = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];                if(tmp < m[i][j]) {                    m[i][j] = tmp;                    s[i][j] = k;                }            }        }    }}string int2str(int n){    stringstream ss;    ss << n;    string res;    ss >> res;    return res;}string Traceback(int i, int j, int **s){    if(i == j) return "A"+int2str(i);    string left = Traceback(i, s[i][j], s);    string right = Traceback(s[i][j]+1, j, s);    return '('+left+right+')';}int main(){    const int n = 6;    int *p = new int[n+1];    p[0]=30;p[1]=35;p[2]=15;p[3]=5;p[4]=10;p[5]=20;p[6]=25;    int **m = new int*[n+1], **s = new int*[n+1];    for (int i = 0; i <= n; ++i){        m[i] = new int[n+1]();  // 每个元素初始化为0        s[i] = new int[n+1]();    }    MatrixChain(n, p, m, s);    for(int i = 1; i <= n; ++i){        for(int j = 1; j <= n; ++j){            cout << m[i][j] << ' ';        } cout << endl;    }    cout << "The minimal number of multiply is : " << m[1][n] << endl;    cout << "The order of multiply is :" << Traceback(1, n, s) << endl;    return 0;}
原创粉丝点击