【动态规划】矩阵连乘问题

这篇具有很好参考价值的文章主要介绍了【动态规划】矩阵连乘问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 两个矩阵相乘:

【动态规划】矩阵连乘问题
代码如下:

void MatrixMutiply(int** a, int** b, int** c, int ra, int ca, int rb, int cb)
{
	if (ca != rb) return;
	for (int i = 0; i < ra; ++i)   //a的行
	{ 
		int sum = 0;
		for (int j = 0; i < cb; ++j)  //b的列
		{
			for (int k = 0; k < ca; ++k)  //a的列 
			{
				sum = a[i][k] * b[k][j];
			}
			c[i][j] = sum;
		}
	}
}

2. 三个矩阵相乘:

【动态规划】矩阵连乘问题
矩阵相乘,只有结合律没有交换律
显而易见,三个矩阵相乘,有两种结合方式,(AB)C 比 A(BC)的值小的多。

3. 多个矩阵连乘,有多种结合方式

因此我们把它们进行划分,假设从第k个矩阵开始划分。如下图:就有
【动态规划】矩阵连乘问题
j个矩阵连乘的积 = R(第 i 个到第k矩阵的积 ) + U(第k+1到最后一个矩阵的积) + R*U 。

举个例子:

有6个矩阵如下图:
使 k = 2 ,则从第二个矩阵开始划分 ,得到如下:
【动态规划】矩阵连乘问题
使 k = 4 ,则从第二个矩阵开始划分 ,得到如下:
【动态规划】矩阵连乘问题

根据上面两幅图可以看出,红色 绿色 黄色 ,所对应得数组p下标所对应的值正好是R,U相乘需要的行和列。得示例可以得到如下关系:
【动态规划】矩阵连乘问题
代码如下:

int MaxtrixMut(int* dp, int i, int j)
{
	if (i == j) return 0;
	else
	{  
		//int t = MaxtrixMut(dp, i, i)+MaxtrixMut(dp,i+1,j)+dp[i-1]*dp[i]*dp[j];  
	    //k == i时
		int t = 0 + MaxtrixMut(dp,i+1,j)+dp[i-1]*dp[i]*dp[j];    
		//从i+1开始划分	
		for (int k = i+1; k < j; ++k)
			{
				int v = MaxtrixMut(dp,i,k)+MaxtrixMut(dp,k+1,j)+ dp[i - 1] * dp[k] * dp[j];	
			    if (t > v)
		   	    {
				  t = v;
		     	}
		     }
		return t;
	}
}

示例:

如果是从第一个到第四个矩阵的乘积,则可以划分为如下:其中红色均为重复划分。
【动态规划】矩阵连乘问题
去重以后的代码:

int MaxtrixMut_2(int* dp, int i, int j, vector<vector<int> >& vec)
{
	if (i == j) return 0;
	else if (vec[i][j] > 0)   //判断vec中是否有值
	{
		return vec[i][j];
	}
	else
	{    //k == i时
		 vec[i][j] = 0 + MaxtrixMut_2(dp, i + 1, j,vec) + dp[i - 1] * dp[i] * dp[j];
		//从i+1开始划分	
		for (int k = i + 1; k < j; ++k)
		{
			int v = MaxtrixMut_2(dp, i, k,vec) + MaxtrixMut_2(dp, k + 1, j,vec) + dp[i - 1] * dp[k] * dp[j];
			if (vec[i][j] > v)
			{
				vec[i][j] = v;
			}
		}
		return vec[i][j];
	}
}

运行结果:
【动态规划】矩阵连乘问题
【动态规划】矩阵连乘问题

int NiceMatrixChain_2(int p[], int n, vector<vector<int> >& m, vector<vector<int> >& s)
{
      ....................................
			m[i][j] = m[i][i] + m[i + 1][j] + p[i - 1] * p[i] * p[j];
			s[i][j] = i;  //划分点
			for (int k = i + 1; k < j; ++k)
			{
				int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
				if (m[i][j] > t)
				{
					m[i][j] = t;
					s[i][j] = k;//   划分点
					..............................................
}

【动态规划】矩阵连乘问题

了解如何进行划分:代码如下:

按照
12 23 34 45 56
123 234 345 456
1234 2345 3456
12345 23456
123456 划分

void NiceMatrixChain(int p[],int n ,vector<vector<int> > &m)
{
	for (int i = 1; i <= n; ++i) m[i][i] = 0;  //让其对角线置为0  1,1  2,2  3,3  4,4  5,5  6,6
	for (int r = 2; r < n; ++r)   //循环的行数
	{
		for (int i = 1; i <= n - r + 1; ++i)   //循环的列数
		{
			int j = i + r - 1;
			for (int k = i; k <= j; ++k)
			{
				printf("%d", k);
			}
			printf(" ");
		}
		printf("\n");
	}

运行结果如下:
【动态规划】矩阵连乘问题
根据上面的代码,略加修改可以得到整个划分的过程。

举个例子 开始先是 12 23 34 45 56 进行相乘
而123相乘 可以分为 (12)3 1(23) 则只需要用上面已经得出的12 和 23 分别与矩阵三和矩阵1相乘,并比较处哪个较小。选较小的积。

int NiceMatrixChain_2(int p[], int n, vector<vector<int> >& m)
{
	for (int i = 1; i <= n; ++i) m[i][i] = 0;  //让其对角线置为0  1,1  2,2  3,3  4,4  5,5  6,6
	for (int r = 2; r <= n; ++r)   //循环的行数
	{
		for (int i = 1; i <= n - r + 1; ++i)   //循环的列数
		{
			int j = i + r - 1;
			m[i][j] = m[i][i] + m[i + 1][j] + p[i - 1] * p[i] * p[j];
			for (int k = i+1; k < j; ++k)
			{
				int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
				if (m[i][j] > t)
				{
					m[i][j] = t;
				}
			}
			PrintVector(m);
		}
	}
	return	m[1][n];
}

测试代码如下;文章来源地址https://www.toymoban.com/news/detail-462287.html

int main()
{
	const int n = 6;
	int p[n+1] = { 30,35,15,5,10,20,25 };
//int sum = MaxtrixMut(p, 1, n);
	vector<vector<int> > vec(n+1, vector<int>(n + 1,0));//  int sum = MaxtrixMut_2(p, 1, n, vec);
// PrintVector(vec);
//	cout << sum << endl;
//	NiceMatrixChain(p, n, vec);
	int sum = NiceMatrixChain_2(p, n, vec);
	PrintVector(vec);
}

到了这里,关于【动态规划】矩阵连乘问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划--矩阵链相乘问题

    明确原始问题A[1:n]: 计算矩阵链 所需的 最小乘法次数。 (1)是否满足最优子结构,问题的解是否包含子问题的优化解? 若计算A[1:n]的优化顺序在 k 处断开矩阵链,即A[1:n]=A[1:k]×A[k+1:n],则在A[1:n]的优化顺序中,对应于子问题A[1:k]的解必须是A[1:k]的优化解,对应A[k+1:n]的解必

    2024年01月25日
    浏览(33)
  • 动态规划:矩阵连乘问题(文末附有手写版例题)

    A是一个p × q矩阵,B是一个q × r矩阵,AB相乘,得到的矩阵元素个数为p × r,每个元素由q次乘法得到,因此所需乘法次数为p × q × r。 在计算矩阵连乘积时,加括号的方式对计算量有影响。 例如有三个矩阵A1,A2,Ag连乘,它们的维数分别为 10x100,100×5,5×50。用第一种加括号方

    2024年02月04日
    浏览(33)
  • 动态规划2:算法考试矩阵连乘问题(超详细手写过程)

                                      更多期末复习笔记欢迎访问我的博客: Miuuu · 语雀​​​​​​​ 动态规划理论基础:(6条消息) 动态规划1:动态规划的入门初学理论基础_黑色柳丁Angel的博客-CSDN博客 矩阵连乘问题是我在算法课接触的第一个动态规划问题

    2023年04月08日
    浏览(31)
  • 7-1 矩阵链相乘问题 (20 分)(思路+详解+题目解析) 动态规划做法

    2:关于本题的矩阵乘法和递推方程的得出 3:实例演示 三:思路 =================================================================== 思路:这里在考虑的的时候,因为是多个矩阵相乘,求的最小乘法次数, 比如 A1_A2_A3_A4, 那么根据划分的不同,那么其乘法顺序也会不同,继而所求的乘法次数

    2024年04月09日
    浏览(57)
  • 『动态规划』矩阵连乘

    活动地址:CSDN21天学习挑战赛 👨‍🎓作者简介:一位喜欢写作,计科专业大三菜鸟 🏡个人主页:starry陆离 🕒首发日期:2022年8月16日星期二 🌌上期文章:『动态规划』动态规划概述 📚订阅专栏:『算法分析与设计』 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦

    2024年02月07日
    浏览(54)
  • 矩阵链相乘(动态规划法)

    矩阵链乘法是耳熟能详的问题了,有很多矩阵,排列成矩阵链,矩阵链的要求是相邻的两个是可以相乘的,可以相乘是有条件的,两个矩阵能够相乘的条件就是行、列之间是有关系的,两个矩阵如果能够相乘,就是前面矩阵的列号和后面矩阵的行号是一致的。 如何确定矩阵的

    2024年02月09日
    浏览(35)
  • 矩阵链相乘的乘法次数(动态规划)

    该题是算法动态规划练习题 该题首先要清楚地认识和理解题意 首先,理解一次矩阵乘法会产生多少次乘法运算 例如给定两个矩阵(10 * 5)与(5 * 20) 会产生的乘法次数为 10*5*20=1000次 然后我们要理解当存在多个矩阵相乘时,乘的顺序不同,最终乘法运算的总次数也是不同的

    2024年01月25日
    浏览(30)
  • 动态规划算法学习一:DP的重要知识点、矩阵连乘算法

    三部曲如下三步: 基本原则:“空间换时间” 存储重复子问题的解,减少运算时间 底层运算:“表格操作” 用表格存储子问题的解 实现路线:“子问题划分、自底向上求解” 利用表格中存储的子问题的解,求上一层子问题的解。 矩阵连乘计算次序 可以用 加括号的方式

    2024年02月09日
    浏览(32)
  • 「算法小记」-2:矩阵链相乘的方案数【迭代/递归/动态规划/区域化DP/记忆化搜索】(C++ )

    😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号:程序员洲洲。 🎈 本文专栏:本文收录于洲洲的《算法小记》系列专栏,该专栏记录了许

    2024年02月05日
    浏览(40)
  • C++两个矩阵相乘代码(内附有矩阵相乘的条件与规则,以及对代码的详细解答)

         再复制粘贴代码之前可以先了解学习一下什么是矩阵相乘,矩阵相乘的条件与规则又是什么。 点击一下链接即可进入学习:                       #矩阵相乘的学习链接          以下是两个矩阵相乘的代码块(输入版) 补充①:对于for循环了解还不够透彻的可以进

    2024年02月11日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包