1. 程式人生 > >計算矩陣連乘積——動態規劃

計算矩陣連乘積——動態規劃

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

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

遞迴公式:

//2.動態規劃解決計算矩陣連乘積

#include<stdio.h>

#include<string.h>

#define MaxNum 100

void MatrixChain(int p[MaxNum],int n,int m[MaxNum][MaxNum],int s[MaxNum][MaxNum]);

void traceback(int i,int j,int s[MaxNum][MaxNum]);

int main()

{

      int P[MaxNum];

      int N;

      int r;

      int M[MaxNum][MaxNum];

      int S[MaxNum][MaxNum];

      while(scanf("%d",&N) && N!=0)

      {

             for(r=0;r<=N;r++)

             {

                    scanf("%d",&P[r]);

             }

             MatrixChain(P,N,M,S);

             traceback(1,N,S);

      }

      return 0;

}

void MatrixChain(int p[MaxNum],int n,int m[MaxNum][MaxNum],int s[MaxNum][MaxNum])

{       

      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[MaxNum][MaxNum])

{

   if(i==j)

         printf("A%d",i);

   else if (i==j-1)

         printf("(A%dA%d)",i,j);

   else

   {

         printf("(");

         traceback(i,s[i][j],s);

         traceback(s[i][j]+1,j,s);

         printf(")");

      }

}