算法导论 练习题 15.2-2

本文介绍了一种矩阵链乘法的优化算法,通过动态规划确定最佳的矩阵相乘顺序,以减少不必要的计算开销。文章提供了完整的C语言实现,包括矩阵创建、矩阵相乘、最优顺序打印等功能。
#include <stdio.h>
#include <limits.h>
#include "矩阵栈.h"
#include "字符栈.h"


int m[7][7];
int s[7][7];

pMStack pm=initStackPM(20);
pCStack pc=initStackPC(20);
pMatrix A[4];



pMatrix newMatrix(int row,int col)
{
	pMatrix c=(pMatrix)malloc(sizeof(MatrixNode));
	c->row=row;
	c->col=col;
	c->m=(int**)malloc(c->row*sizeof(int*));
	for(int i=0;i<c->row;i++)
	{
		c->m[i]=(int*)malloc(c->col*sizeof(int));
	}
	return c;
}

void initA()
{
	A[0]=newMatrix(1,3);
	A[0]->m[0][0]=1;
	A[0]->m[0][1]=2;
	A[0]->m[0][2]=3;

	A[1]=newMatrix(3,2);
	A[1]->m[0][0]=1;
	A[1]->m[0][1]=2;
	A[1]->m[1][0]=3;
	A[1]->m[1][1]=4;
	A[1]->m[2][0]=5;
	A[1]->m[2][1]=6;

	A[2]=newMatrix(2,3);
	A[2]->m[0][0]=1;
	A[2]->m[0][1]=2;
	A[2]->m[0][2]=3;
	A[2]->m[1][0]=4;
	A[2]->m[1][1]=5;
	A[2]->m[1][2]=6;

	A[3]=newMatrix(3,1);
	A[3]->m[0][0]=1;
	A[3]->m[1][0]=1;
	A[3]->m[2][0]=1;
}

pMatrix matrixMul(pMatrix a,pMatrix b)
{
	if(a->col != b->row)
	{
		printf("矩阵乘法参数不合法!");
		return NULL;
	}

	pMatrix c=newMatrix(a->row,b->col);
	
	for(int i=0;i<a->row;i++)
	{
		for(int j=0;j<b->col;j++)
		{
			int sum=0;
			for(int k=0;k<a->col;k++)
			{
				sum+=a->m[i][k]*b->m[k][j];
			}
			c->m[i][j]=sum;
		}
	}
	return c;
}

void matrixChainOrder(int p[],int len)
{
	int n=len-1,q;
	for(int i=1;i<=n;i++)
		m[i][i]=0;
	for(int l=2;l<=n;l++)
	{
		for(int i=1;i<=n-l+1;i++)
		{
			int j=i+l-1;
			m[i][j]=INT_MAX;
			for(int k=i;k<j;k++)
			{
				int 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;
				}
			}
		}
	}
}

void printS(int i,int j)
{
	if(i==j)
		printf("A%d",i);
	else
	{
		printf("(");
		printS(i,s[i][j]);
		printS(s[i][j]+1,j);
		printf(")");
	}
}

void printM(pMatrix m)
{
	for(int i=0;i<m->row;i++)
	{
		for(int j=0;j<m->col;j++)
		{
			printf("%d ",m->m[i][j]);
		}
		printf("\n");
	}
}

void matrixChainMultiply(int i,int j)
{
	if(i==j)
		pushPM(pm,A[i-1]);
	else
	{
		pushPC(pc,'(');
		matrixChainMultiply(i,s[i][j]);
		matrixChainMultiply(s[i][j]+1,j);
		char c=popPC(pc);
		if(c=='(')
		{
			pMatrix b=popPM(pm);
			pMatrix a=popPM(pm);
			pMatrix p=matrixMul(a,b);
			pushPM(pm,p);
			//printM(p);
		}
	}
}



void main()
{
	initA();
	int p[5]={1,3,2,3,1};
	matrixChainOrder(p,5);
	printf("%d\n",m[1][4]);
	printS(1,4);
	printf("\n");
	matrixChainMultiply(1,4);
	pMatrix m=popPM(pm);
	printM(m);
	getchar();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值