【问题标题】: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,正如您在代码中假设的那样。你能用调试器检查一下吗?

标签: c++ algorithm vector matrix-multiplication


【解决方案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,没错,单位矩阵是生产的中性元素,所以这个答案有效地指出了一个错误。
猜你喜欢
  • 2019-03-14
  • 1970-01-01
  • 2011-07-23
  • 2013-01-24
  • 1970-01-01
  • 2021-05-09
  • 1970-01-01
  • 2017-10-05
  • 2016-05-30
相关资源
最近更新 更多