wizen-coder
10/4/2018 - 11:31 AM

给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘的,i=1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。 例:设要计算矩阵连乘乘

给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘的,i=1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。 例:设要计算矩阵连乘乘积A1A2A3A4A5A6,其中各矩阵的维数分别是: A1:3035; A2:3515; A3:155; A4:510; A5:1020; A6:2025 1、重叠递

//3d1-1 重叠子问题的递归最优解
//A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*25
//p[0-6]={30,35,15,5,10,20,25}
#include "stdafx.h"
#include <iostream> 
using namespace std; 
 
const int L = 7;
 
int RecurMatrixChain(int i,int j,int **s,int *p);//递归求最优解
void Traceback(int i,int j,int **s);//构造最优解
 
int main()
{
	int p[L]={30,35,15,5,10,20,25};
 
    int **s = new int *[L];
	for(int i=0;i<L;i++)  
    {  
		s[i] = new int[L];  
    } 
 
	cout<<"矩阵的最少计算次数为:"<<RecurMatrixChain(1,6,s,p)<<endl;
	cout<<"矩阵最优计算次序为:"<<endl;
	Traceback(1,6,s);
	return 0;
}
 
int RecurMatrixChain(int i,int j,int **s,int *p)
{
	if(i==j) return 0;
	int u = RecurMatrixChain(i,i,s,p)+RecurMatrixChain(i+1,j,s,p)+p[i-1]*p[i]*p[j];
	s[i][j] = i;
 
	for(int k=i+1; k<j; k++)
	{
		int t = RecurMatrixChain(i,k,s,p) + RecurMatrixChain(k+1,j,s,p) + p[i-1]*p[k]*p[j];
		if(t<u)
		{
			u=t;
			s[i][j]=k;
		}
	}
	return u;
}
 
void Traceback(int i,int j,int **s)
{
	if(i==j) return;
	Traceback(i,s[i][j],s);
	Traceback(s[i][j]+1,j,s);
	cout<<"Multiply A"<<i<<","<<s[i][j];
	cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;
}
//3d1-2 矩阵连乘 备忘录递归实现
//A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*25
//p[0-6]={30,35,15,5,10,20,25}
#include "stdafx.h"
#include <iostream> 
using namespace std; 
 
const int L = 7;
 
int LookupChain(int i,int j,int **m,int **s,int *p);
int MemoizedMatrixChain(int n,int **m,int **s,int *p);
 
void Traceback(int i,int j,int **s);//构造最优解
 
int main()
{
	int p[L]={30,35,15,5,10,20,25};
 
    int **s = new int *[L];
	int **m = new int *[L];
	for(int i=0;i<L;i++)  
    {  
		s[i] = new int[L];
		m[i] = new int[L];
    } 
 
	cout<<"矩阵的最少计算次数为:"<<MemoizedMatrixChain(6,m,s,p)<<endl;
	cout<<"矩阵最优计算次序为:"<<endl;
	Traceback(1,6,s);
	return 0;
}
 
int MemoizedMatrixChain(int n,int **m,int **s,int *p)
{
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=n; j++)
		{
			m[i][j]=0;
		}
	}
	return LookupChain(1,n,m,s,p);
}
 
int LookupChain(int i,int j,int **m,int **s,int *p)
{
	if(m[i][j]>0)
	{
		return m[i][j];
	}
	if(i==j)
	{
		return 0;
	}
 
	int u = LookupChain(i,i,m,s,p) + LookupChain(i+1,j,m,s,p)+p[i-1]*p[i]*p[j];
	s[i][j]=i;
	for(int k=i+1; k<j; k++)
	{
		int t = LookupChain(i,k,m,s,p) + LookupChain(k+1,j,m,s,p) + p[i-1]*p[k]*p[j];
		if(t<u)
		{
			u=t;
			s[i][j] = k;
		}
	}
	m[i][j] = u;
	return u;
}
 
void Traceback(int i,int j,int **s)
{
	if(i==j) return;
	Traceback(i,s[i][j],s);
	Traceback(s[i][j]+1,j,s);
	cout<<"Multiply A"<<i<<","<<s[i][j];
	cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;
}
//3d1-2 矩阵连乘 动态规划迭代实现
//A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*25
//p[0-6]={30,35,15,5,10,20,25}
#include "stdafx.h"
#include <iostream> 
using namespace std; 
 
const int L = 7;
 
int MatrixChain(int n,int **m,int **s,int *p); 
void Traceback(int i,int j,int **s);//构造最优解
 
int main()
{
	int p[L]={30,35,15,5,10,20,25};
 
    int **s = new int *[L];
	int **m = new int *[L];
	for(int i=0;i<L;i++)  
    {  
		s[i] = new int[L];
		m[i] = new int[L];
    } 
 
	cout<<"矩阵的最少计算次数为:"<<MatrixChain(6,m,s,p)<<endl;
	cout<<"矩阵最优计算次序为:"<<endl;
	Traceback(1,6,s);
	return 0;
}
 
int MatrixChain(int n,int **m,int **s,int *p)
{
	for(int i=1; i<=n; i++)
	{
		m[i][i] = 0;
	}
	for(int r=2; r<=n; r++) //r为当前计算的链长(子问题规模)  
	{
		for(int i=1; i<=n-r+1; i++)//n-r+1为最后一个r链的前边界  
		{
			int j = i+r-1;//计算前边界为r,链长为r的链的后边界  
 
			m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];//将链ij划分为A(i) * ( A[i+1:j] ) 
 
			s[i][j] = i;
 
			for(int k=i+1; k<j; k++)
			{
				//将链ij划分为( A[i:k] )* (A[k+1:j])   
				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;
				}
			}
		}
	}
	return m[1][L-1];
}
 
void Traceback(int i,int j,int **s)
{
	if(i==j) return;
	Traceback(i,s[i][j],s);
	Traceback(s[i][j]+1,j,s);
	cout<<"Multiply A"<<i<<","<<s[i][j];
	cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;
}