矩阵求幂,用于计算可能的路线数量
Posted
技术标签:
【中文标题】矩阵求幂,用于计算可能的路线数量【英文标题】:Matrix Exponentiation for calculating number of routes possible 【发布时间】:2016-10-07 18:12:17 【问题描述】:最近我在 Iarcs 网站上遇到了this 问题。这是问题陈述:
众所周知,互联网上使用的路由算法是 高度非最优。用互联网术语来说,“跃点”是一对节点 直接连接 - 通过电缆或微波链路或 任何。数据包从一开始可能需要的跳数 节点到另一个节点可能远远超过所需的最小值。
但是 Siruseri Network 公司使用的路由算法是 更差。在这里,从一个节点发送到另一个节点的数据包甚至可以通过 通过同一个节点两次,甚至之前遍历同一个跃点两次 它最终会找到通往目的地的路。有时一个数据包 甚至不止一次地经过目的地 视为“已交付”。假设 Siruseri 的网络由 以下节点和电缆:图
有 5 个节点和 8 个电缆链路。请注意,一对节点可能是 由多个链接连接。这些被认为是不同的 酒花。所有链接都是双向的。从节点 1 到节点 5 的数据包可能, 例如,旅行如下:1 到 2、2 到 1、1 到 3、3 到 2、2 到 1、1 到 4、4 到 5、5 到 4、4 到 5。此路由的长度为 9( 跳数是给定路由的长度)。我们感兴趣 计算从给定源到某个源的不同路由的数量 给定长度的目标。
例如,长度为 3 的从 1 到 2 的路由数量为 7。 它们如下(用;分隔):1 到 2、2 到 1 和 1 到 2; 1到 3、3对1和1对2; 1比4、4比1和1比2; 1 到 5、5 到 1 和 1 到 2; 1 到 4、4 到 3(通过左侧电缆)和 3 到 2; 1 到 4、4 到 3 (通过正确的电缆)和 3 到 2; 1 到 2、2 到 3 和 3 到 2。
您将获得 Siruseri 网络的描述以及 源、目标和跳数,你的任务是 确定从源到目标的路由数量 有给定的跳数。答案是要报模 42373.
正如this thread 上所讨论的,解决方案是计算给定矩阵的 k 次幂,其中 k 是给定的路由数量。
在这里我做了同样的事情:
#include <iostream>
#include <vector>
std::vector<std::vector<int> >MatrixMultiplication(std::vector<std::vector<int> >matrix1,std::vector<std::vector<int> >matrix2,int n)
std::vector<std::vector<int> >retMatrix(n,std::vector<int>(n));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
retMatrix[i][j] = retMatrix[i][j] + matrix1[i][k] * matrix2[k][j];
return retMatrix;
std::vector<std::vector<int> >MatrixExponentiation(std::vector<std::vector<int> >matrix,int n,int power)
if(power == 0 || power == 1)
return matrix;
if(power%2 == 0)
return MatrixExponentiation(MatrixMultiplication(matrix,matrix,n),n,power/2);
else
return MatrixMultiplication(matrix,MatrixExponentiation(MatrixMultiplication(matrix,matrix,n),n,(power-1)/2),n);
int main (int argc, char const* argv[])
int n;
std::cin >> n;
std::vector<std::vector<int> >matrix(n,std::vector<int>(n));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
std::cin >> matrix[i][j];
int i ,j ,power;
std::cin >> i >> j >> power;
std::vector<std::vector<int> >retMax(n,std::vector<int>(n));
retMax = MatrixExponentiation(matrix,n,power);
std::cout << matrix[i-1][j-1] << std::endl;
return 0;
但是即使对于示例情况,输出也不匹配,我是否在这里遗漏了什么,或者我必须尝试另一种方法来解决这个问题?
编辑:正如@grigor 建议的那样,我更改了 power == 0 的代码以返回单位矩阵,但代码仍然产生错误的输出,
if(power == 0)
std::vector<std::vector<int> >retMatrix(n,std::vector<int>(n));
for(int i=0;i<n;i++)
retMatrix[i][i] = 1;
return retMatrix;
注意:我还没有写模数的代码,你认为它会对示例测试用例产生影响吗?
【问题讨论】:
我想知道未初始化的值是否确实为 0,正如您在代码中假设的那样。你能用调试器检查一下吗? 【参考方案1】:我认为您只是打印出错误的值,更改:
std::cout << matrix[i-1][j-1] << std::endl;
到
std::cout << retMax [i-1][j-1] << std::endl;
【讨论】:
嗯,我需要更多的注意力,谢谢指正【参考方案2】:如果power == 0
应该返回单位矩阵,而不是实际矩阵。
【讨论】:
哦,你的意思是主对角线为 1 的矩阵? 点赞std::vector<std::vector<int> >retMatrix(n,std::vector<int>(n)); for(int i=0;i<n;i++) retMatrix[i][i] = 1;
甚至不影响答案的原因
根据能力,在递归中甚至可能不会遇到这种情况。但这绝对是一个错误,需要修复。我现在看不到任何其他错误
@KuntalMajumder,没错,单位矩阵是生产的中性元素,所以这个答案有效地指出了一个错误。以上是关于矩阵求幂,用于计算可能的路线数量的主要内容,如果未能解决你的问题,请参考以下文章