算法設計與分析——矩陣連乘問題(動態規划)


一、問題描述

引出問題之前我們先來復習一下矩陣乘積的標准算法。

int ra,ca;//矩陣A的行數和列數
int rb,cb;//矩陣B的行數和列數
void matrixMultiply()
{
    for(int i=0;i<ra;i++)
    {
        for(int j=0;j<cb;j++)
        {
            int sun=0;
            for(int k=0;k<=ca;k++)
            {
                sum+=a[i][k]*b[k][j];
            }
            c[i][j]=sum;
        }
    }
}

 

 

給定n個矩陣{A1,A2,…,An},其中Ai與Ai+1是可乘的,i=1,2…,n-1。如何確定計算矩陣連乘積的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。例如,給定三個連乘矩陣{A1,A2,A3}的維數分別是10*100,100*5和5*50,采用(A1A2)A3,乘法次數為10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次數為100*5*50+10*100*50=75000次乘法,顯然,最好的次序是(A1A2)A3,乘法次數為7500次。

加括號的方式對計算量有很大的影響,於是自然地提出矩陣連乘的最優計算次序問題,即對於給定的相繼n個矩陣,如何確定矩陣連乘的計算次序,使得依此次序計算矩陣連乘積需要的數乘次數最少。

二、問題分析

 矩陣連乘也是Catalan數的一個常用的例子,關於時間復雜度的推算需要參考離散數學關於Catalan的內容。

下面考慮使用動態規划法解矩陣連乘積的最優計算次序問題。

1、分析最優解的結構

 

 問題的最優子結構性質是該問題可以用動態規划求解的顯著特征!!!

2、建立遞歸關系

 

3、計算最優值

public static void matrixChain(int n) {
    for (int i = 1; i <= n; i++) {
        m[i][i] = 0;
    }
    for (int r = 2; r <= n; r++) {//i與j的差值
        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;
                }
            }
        }
    }
}

4、構造最優解

 

   public static void traceback(int i, int j) {
        if (i == j) {
            System.out.printf("A%d", i); // 輸出是第幾個數據
            return;
        }
        System.out.printf("(");
        traceback(i, s[i][j]);// 遞歸下一個數據
        System.out.printf(" x ");
        traceback(s[i][j] + 1, j);
        System.out.printf(")");
    }

三、總結

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM