矩阵链乘问题

问题描述:
给定n个矩阵的链 <A1,A2,...,An> <script type="math/tex" id="MathJax-Element-700"> </script>,矩阵 Ai 的规模为 pi×pi+1(1in) ,求完全括号化的方案,使得计算乘积 A1,A2,...,An 所需标量乘法的次数最少。
递推式:

m[i,j]={0,min{m[i,k]+m[k+1,j]+pipk+1pj+1},if i=j if i<j 

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
const int N=6;
const int msize[6][2]={{30,35},{35,15},{15,5},{5,10},{10,20},{20,25}};
const int p[7]={30,35,15,5,10,20,25};//the size of matrix: eg. matrix[0]=30*35; matrix[i]=p[i]*p[i+1]
int m[N][N];//m[i][j]=m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1]
vector< vector<int> > s(N);//store the split position
void matrix_chain_order(const int p[],int n)
{
     n--;//the number of the matrixes
  int i,j,l,k;
  for(i=0;i<n;i++)
  m[i][i]=0;
  for(l=2;l<=n;l++){//l is the chain length, the maximum is n-1
    for(i=0;i<=n-l;i++)//i is the start matrix of the chain,the last start matrix of the l length chain is n-l-1
    {
      j=i+l-1;//if the start of the chain is i,then the end of the chain is j, because j-i+1=l.
      m[i][j]=INT_MAX;  
      for(k=i;k<j;k++)
      {
        int q=m[i][k]+m[k+1][j]+p[i]*p[k+1]*p[j+1];
        if(q<m[i][j])
        {
          m[i][j]=q;
          s[i][j]=k;
        //  cout<<k<<endl;
        }
      }              
    }               
  }   
}
int look_up_chain(vector< vector<int> > &m,vector< vector<int> > &s,const int p[],int i,int j)
{
    int k,q;
    if(m[i][j]<INT_MAX)
    return m[i][j];
    if(i==j)
    {
        m[i][j]=0;
    }else{
        for(k=i;k<j;k++)
        {
            q=look_up_chain(m,s,p,i,k)+look_up_chain(m,s,p,k+1,j)+p[i]*p[k+1]*p[j+1];
            if(q<m[i][j])
            {
                m[i][j]=q;
                s[i][j]=k;
            }


        }
    }
    return m[i][j];
}
//带备忘机制的动态规划
int memorized_matrix_chain(const int p[],int n)
{
    n--;//the total matrixes in the chain
    vector< vector<int> > memo(n);
    for(int i=0;i<n;i++)
    memo[i].resize(n);
    int i,j;
    for(i=0;i<n;i++)
    {
        for(j=i;j<n;j++)
        memo[i][j]=INT_MAX;
    }
    return look_up_chain(memo,s,p,0,n-1);
}
void print_optimal_parens(vector< vector<int> > & s,int i, int j)
{
     if(i==j)
     cout<<"A_"<<i+1;
     else{
          cout<<"(";
      print_optimal_parens(s,i,s[i][j]);
      print_optimal_parens(s,s[i][j]+1,j);
      cout<<")";
     }
}
int main(){
    for(int i=0;i<N;i++)
    s[i].resize(N);
   // matrix_chain_order(p,N+1);
   int ans=memorized_matrix_chain(p,N+1);
    cout<<"the answer: "<<endl;
    cout<<ans<<endl;
    print_optimal_parens(s,0,N-1);
    return 0;
}

用于实验的例子:
这里写图片描述
结果应为: ((A1(A2A3))((A4A5)A6))
运行过程:
这里写图片描述
运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值