矩阵求幂,用于计算可能的路线数量

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&lt;std::vector&lt;int&gt; &gt;retMatrix(n,std::vector&lt;int&gt;(n)); for(int i=0;i&lt;n;i++) retMatrix[i][i] = 1; 甚至不影响答案的原因 根据能力,在递归中甚至可能不会遇到这种情况。但这绝对是一个错误,需要修复。我现在看不到任何其他错误 @KuntalMajumder,没错,单位矩阵是生产的中性元素,所以这个答案有效地指出了一个错误。

以上是关于矩阵求幂,用于计算可能的路线数量的主要内容,如果未能解决你的问题,请参考以下文章

找到遍历图中所有顶点的路线的更好算法是啥?

01迷宫

这可能是全网Java学习路线最完整,最详细的版本了,没有之一Java基础Java框架Java+云数据Java学习总路线

同一路线的角力载荷

Python科学计算为目标学习路线应该怎么走

云计算学习路线图素材课件,msyql中CASE WHEN语法