1. 程式人生 > 其它 >2020-12-21 實驗六 動態規劃演算法之計算矩陣連乘積

2020-12-21 實驗六 動態規劃演算法之計算矩陣連乘積

技術標籤:演算法分析

計算矩陣連乘積

在科學計算中經常要計算矩陣的乘積。矩陣A和B可乘的條件是矩陣A的列數等於矩陣B的行數。若A是一個p×q的矩陣,B是一個q×r的矩陣,則其乘積C=AB是一個p×r的矩陣。由該公式知計算C=AB總共需要pqr次的數乘。其標準計算公式為:
1

現在的問題是,給定n個矩陣{A1,A2,…,An}。其中Ai與Ai+1是可乘的,i=1,2,…,n-1。要求計算出這n個矩陣的連乘積A1A2…An,最少的乘法次數。

遞迴公式:
2

請編寫程式實現矩陣連乘問題的動態規劃演算法,自己設計不少於3組的測試資料,要求顯示出最少的乘法次數,以及最優計算次序。

演算法參考如下:

void MatrixChain(int *p,int n,int **m,int **s)
{        for (int i = 1; i <= n; i++) 
               m[i][i] = 0;
        for (int r = 2; r <= n; r++)
           for (int i = 1; i <= n - r+1; i++) {
              int j=i+r-1;
              m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j];
              s[
i][j] = i; for (int k = i+1; k < j; k++) { 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; s[i][j] = k;} } } } void traceback(int i,int j,int **s) { if(i==j) cout<<"A"
<<i; else if (i==j-1) cout<<"(A"<<i<<"A"<<j<<")"; else { cout<<"("; traceback(i,s[i][j],s); traceback(s[i][j]+1,j,s); cout<<")"; } }

原始碼:

#include <iostream>
using namespace std;
int m[100][100],s[100][100];
int sum;
void MatrixChain(int *p,int n,int m[100][100],int s[100][100])
{
 int i,r,k;
 for (i = 1; i <= n; i++)
  m[i][i] = 0;
 for (r = 2; r <= n; r++)
  for (i = 1; i <= n - r+1; i++)
  {
   int j=i+r-1;
   m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j];
   s[i][j] = i;
   for (k = i+1; k < j; k++)
   {
    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; 
     s[i][j] = k;
     sum=m[i][j];
    }
   }
  }
}
void traceback(int i,int j,int s[][100])
{
 if(i==j)
  cout<<"A"<<i;
 else if (i==j-1)
  cout<<"(A"<<i<<"A"<<j<<")";
 else
 {
  cout<<"(";
  traceback(i,s[i][j],s);
  traceback(s[i][j]+1,j,s);
  cout<<")";
 }
 }
int main()
{
 int n,i;
 int a[100];
 cout<<"請輸入矩陣的個數:";
 cin>>n;
 cout<<"請輸入"<<n+1<<"個數字:";
 for(i=0;i<=n;i++)
  cin>>a[i];
 MatrixChain(a,n,m,s);
 cout<<"最優計算次序為:";
 traceback(1,n,s);
 cout<<endl;
 cout<<"最少乘法次數為:"<<sum<<endl;
 return 0;
}

截圖:
1
2
3