算法之旅 直奔动态规划 矩阵链

矩阵链

  • 真言

学校今天开暖气了,很暖,怎一个好字了得。
动态规划之关联博客,如下

  • 题目

题目截图来自算法圣经---算法导论



  • 思路

典型的动态规划问题:重叠子问题,最优子结构,无后向性。
举例子吧,比如有八个矩阵
A1(1*7),A2(7*4),A3(4*5),A4(5*9),A5(9*4),A6(4*8),A7(8*8),A8(8*2)
然后让这八个矩阵相乘,求最少的计算次数呗。
初始数据如下

p数组存放这些数据


算法如下,
	for( l = 2 ; l<= n ;l++ )
		for( i = 1;i<= n-l+1;i++ )
		{
			j = i+l-1 ;
			m[i][j] = maxint ;
			for( k = i ; k<=j-1 ; k++ )
			{
				q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j] ;
				if( q < m[i][j] )
				{

					m[i][j] = q ;
					s[i][j] = k ;
					cout<<i<<"\t"<<j<<"\t"<<m[i][j]<<'\t'<<s[i][j]<<endl;
				}
			}
		}

建表过程如下
第一个表 m[i][j]代表Ai···Aj的相乘需要计算的最少次数










第二个表
s[i][j]代表Ai···Aj矩阵相乘断开的位置
例如s[3][5] = 4, 那么 (A3*A4)*A5可以得到最少的计算次数,以此类推。









结果 


  • 实验

程序截图
实验数据 p = 18/21/9/4/10/15/1/10;

  • 代码(代码一年前写的,很水,只供参考演示算法罢了)

test.cpp
#include <iostream>
#include <limits>
#include <fstream>
using namespace std;


// var: size for mutrix 
int const size = 8 ;

int const n = size ;
 
// var: size of tested data
int const plength = n+1 ;



// var: get the max int number
int const maxint = std::numeric_limits<int>::max();



class Mutrix
{
	int  * Aint ;
	int ** m ;
	int ** s ;
	int * p ;
public:
	Mutrix(void) ;
	void dataPrepare( ) ;
	void dataRead( ) ;

	void Matrix_Chain_Order( ) ;
	void Print_optimal_parens(int i,int j) ;
	void Main( ) ;
	~Mutrix(void) ;
};

Mutrix::Mutrix( void )
{
	Aint = new int[ plength ] ;
	p = new int[ plength ] ;
	m = new int*[ plength ] ;
	s = new int*[ plength ] ;
	for( int i = 0 ; i<plength ; i++ )
	{
		m[i] = new int[plength] ;
		s[i] = new int[plength] ;
	}
}

void Mutrix::dataPrepare()
{
	ofstream fileWriter;
	fileWriter.open("data.txt");
	fileWriter.clear();

	int i , j = 0;
	while( j<plength )
	{
		i = rand()%10;
		if( i == 0 )
			i =5;
		fileWriter<<i<<'/';
		j++ ;
	}
	fileWriter.close();
}

void Mutrix::dataRead( )
{
	ifstream fileReader ;
	fileReader.open("data.txt") ;
	int i = 0  ;
	char c ;
	while( i < plength )
	{
		fileReader>>Aint[i]>>c ;
		p[i] = Aint[i] ;
		i++ ;
	}
	fileReader.close() ;
}


void Mutrix::Matrix_Chain_Order( )
{
	int n = plength - 1 ;
	int i ;
	for( i = 1; i<= n ; i ++ )
		m[i][i] = 0 ;
	int l,j,k ,q ;
	for( l = 2 ; l<= n ;l++ )
		for( i = 1;i<= n-l+1;i++ )
		{
			j = i+l-1 ;
			m[i][j] = maxint ;
			for( k = i ; k<=j-1 ; k++ )
			{
				q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j] ;
				if( q < m[i][j] )
				{

					m[i][j] = q ;
					s[i][j] = k ;
					cout<<i<<"\t"<<j<<"\t"<<m[i][j]<<'\t'<<s[i][j]<<endl;
				}
			}
		}
}

void Mutrix::Print_optimal_parens( int i , int j )
{
	if(i == j)
		cout<<"A"<<i;
	else
	{
		cout<<'(';
		this->Print_optimal_parens(i,s[i][j]);
		this->Print_optimal_parens(s[i][j]+1,j);
		cout<<')';
	}


}

void Mutrix::Main( )
{
	this->dataPrepare() ;
	this->dataRead() ;
	this->Matrix_Chain_Order();
	this->Print_optimal_parens(1,n);
}

Mutrix::~Mutrix( void )
{
	delete [] Aint ;
	delete [] p;
	for(int i=0 ;i<plength;i++)
	{
		delete []m[i]  ;
		delete [] s[i]  ;
	}
	delete  [] s;
	delete [] m;
}


int main()
{
	cout<<"maxint = "<<maxint<<endl;
	Mutrix * M = new Mutrix() ;
	M->Main() ;
	delete M ;
	cout<<endl;
	system("pause") ;
	return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值