《算法导论》——矩阵链乘法

本文详细探讨了《算法导论》中的矩阵链乘法问题,通过动态规划方法寻找最优的矩阵乘法顺序,以减少乘法操作次数。文章解释了如何利用p[n+1]、m[i][j]和s[i][j]来存储和计算矩阵链的最短路径,旨在帮助读者理解这一经典算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《算法导论》——矩阵链乘法

一、问题抛出
在这里插入图片描述
在这里插入图片描述
二、何为矩阵链乘法
在这里插入图片描述

三、动态规划法解决
在这里插入图片描述
(PS:这里通俗一点讲就是对于一个长度为n的矩阵链,找到一个中间位置k对其进行划分,使A1…K乘以Ak+1…N的乘法次数最少,要知道前面的最少次数就需要对前面的子链继续进行划分)
在这里插入图片描述
在这里插入图片描述
(对p[n+1]、m[i][j]、s[i][j]的解释)
在这里插入图片描述
当前矩阵的个数为n,那么p[]={30,35,15,5,10,20,25}
m[i][j]为以第i个矩阵开始第j个矩阵结尾的矩阵链的最少乘法次数
s[i][j]则保存这种方案的分割位置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

#include "iostream"
#include "vector"
using namespace std;

void MATRIX_CHAIN_ORDER(int* p, int n, vector<vector<int>>& m, vector<vector<int>>& s)//p为矩阵规模,例如Ai 行为p[i-1],列为p[i],n为链的个数
{
	int j = 0;
	for (int i = 1; i <= n; i++)//都是从1开始,第一个矩阵,第二个。。。
	{
		m[i][i] = 0;            //矩阵长度为1不需要乘
	}
	for (int l = 2; l <= n; l++)  //计算每种长度链的最优分法
	{
		for (int i = 1; i <= n - l + 1; i++)//i在长度为l的链中的每种可能位置
		{
			j = l + i - 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 PRINT_OPTIMAL_PARENS(vector<vector<int>>& s, int i, int j)
{
	if (i == j)
	{
		cout << "A" << i;
	}
	else
	{
		cout << "(";
		PRINT_OPTIMAL_PARENS(s, i, s[i][j]);
		PRINT_OPTIMAL_PARENS(s,s[i][j]+1,j);
		cout << ")";

	}
}
void main()
{
	int n;//矩阵链的规模
	cout << "请输入矩阵链的长度" << endl;
	cin >> n;

	vector<vector<int>> m(n+1);  //vector 构建二维数组
	for (int i = 0; i <=n; i++)
		m[i].resize(n+1);
	vector<vector<int>> s(n+1);
	for (int i = 0; i <=n; i++)
		s[i].resize(n+1);

	cout << "请输入矩阵规模序列" << endl;
	int* p = new int[n+1];
	for (int i = 0; i <= n; i++)//p的长度比矩阵链长度多1
	{
		cin >> p[i];           //p为{1,2,3...},p[0]为A1的行,p[1]为A1的列,A2的行
	}
	MATRIX_CHAIN_ORDER(p,n, m, s);
	cout << "最优解决方案" << endl;
	PRINT_OPTIMAL_PARENS(s, 1, n);
	cout << endl;
	cout << "乘法次数" << m[1][n] << endl;
	system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值