算法分析--動態規劃--矩陣連乘

動態規劃算法的基本要素:

  1. 最優子結構性質

假設A1*A2*A3*...*An在k處斷開爲最優,那麼只需要保證A1*...*Ak和Ak*..*An兩個子序列的分割也是最優,就能保證該結果是最優。

  1. 子問題重疊性

問題描述:

對於多個矩陣連乘,不同的分割次序會導致計算次數的不同,所以要找到最優化的分割,減少計算量。

 

A1 A2 A3 A4 A5 A6
30*35 35*15 15*5 5*10 10*20 20*25

計算子問題的最優解並保存:

矩陣m保存子問題的最優計算量,矩陣s保存子問題的最優分割方式。

矩陣m:

矩陣s:

舉例說明:

m[0][3]=7875,s[0][3]=1表示對於子問題(分割A1*A2*A3),需要的最少計算量爲7875次,最優分割點在位置1,也就是分割爲A1*(A2*A3)。

 

#include "stdafx.h"
#include<iostream>
#include<cstdlib>
using namespace std;
void MatrixChain(int *p, int n, int m[][6], int s[][6]);
void TraceBack(int i, int j, int s[][6]);

int main()
{
	int n = 6;
	int p[7] = { 30,35,15,5,10,20,25 };
	int m[6][6] = {};
	int s[6][6] = {};
	for (int i = 0; i < 6; i++)
		for (int j = 0; j < 6; j++)
		{
			m[i][j] = 0; s[i][j] = 0;
		}
	MatrixChain(p, n, m, s);
	for (int i = 0; i < 6; i++)
	{
		for (int j = 0; j < 6; j++) cout << s[i][j] << "\t";
		cout << endl;
	}
	//cout << s[0][5]<<endl;
	TraceBack(0, 5, s);
	system("pause");
	return 0;
}
//構造最優解矩陣
void MatrixChain(int *p, int n, int m[][6], int s[][6])
{
	for (int i = 0; i < n; i++) m[i][i] = 0;//將矩陣分割成單個的矩陣,此時計算量爲0
	for (int r = 2; r <= n; r++)//將矩陣分割爲2 - n 個矩陣,計算此時的計算量
		for (int i = 0; i < n-r+1; i++)	
		{
			int j = i + r - 1;
			//將矩陣連乘m[i][j]最優分割點初始化爲第i個矩陣處
			m[i][j] = m[i + 1][j] + p[i] * p[i+1] * p[j+1];
			s[i][j] = i+1;
			//尋找比初始化分割點更優的分割點
			for (int k = i + 1; k <= j; k++)
			{
				int temp = m[i][k] + m[k + 1][j] + p[i] * p[k+1] * p[j+1];
				if (temp < m[i][j]){m[i][j] = temp;s[i][j] = k+1;}
			}
		}
}
//遞歸搜索最優解
void TraceBack(int i, int j, int s[][6])
{
	//查找最優解位置s[i][j]
	if (i == j || i == j-1) return;//已經分出來單個矩陣,或者兩個矩陣相乘的部分,不需要再進行分割
	else
	{
		TraceBack(i, s[i][j] - 1, s);//遞歸分割左邊部分
		cout << s[i][j] << "\t";//輸出分割點位置
		TraceBack(s[i][j], j, s);//遞歸分割右邊部分
	}	
}

 

 

參考資料

  1. 算法設計與分析--王曉東
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章