【问题标题】:Number of ways of length K to get from the first vertex back to itself in an undirected unweighted graph在无向无权图中从第一个顶点返回到自身的长度为 K 的方式数
【发布时间】:2021-09-02 13:39:22
【问题描述】:

我有一个无向无权图,其中有 N 个顶点,编号从 1 到 N。我需要找到从 first 顶点返回到自身的长度 K 的方式数。在这种情况下,允许多次重新访问第一个(或任何其他)顶点。 一种可能的解决方案是采用邻接矩阵,找到该矩阵的 K 次幂,然后结果矩阵的左上角元素将成为问题的答案.该方法的时间复杂度为O(N^3 * log(K))。 但是有没有更快的方法来解决这个问题?

【问题讨论】:

    标签: algorithm matrix graph-theory adjacency-matrix


    【解决方案1】:

    简短回答:是的,你总是可以做得比O(N^3 log K) 更好。

    长答案:最快方法的复杂性确实取决于 K 的大小,并且在较小程度上取决于图的当前表示形式和图中的边数。这个问题的具体术语是“counting closed walks”。

    小K

    使用动态编程。对于给定的初始顶点 x,我们有一个二维 DP 状态。

    令 DP[ y ][ i ] 为从我们初始开始的长度为 i 的游走数 到 y 的顶点。如果 y 与我们的初始值相邻,则 DP[ y ][ 1 ] 为 1 顶点,否则为 0。 i 的递推关系 > 1 是:DP[ y ][ i ] 是 (DP[ w ][ i - 1 ]) 的 y 的所有邻居 w 的总和

    那么你的答案就是 DP[ K ][ 1 ]。

    执行此操作的简短 Python 代码,假设图是邻接表表示:

    dp = [[0 for _ in range(N + 1)] for _ in range(K + 1)]
    
    for neighbor in graph[1]:
        dp[1][neighbor] = 1
    
    for walk_length in range(2, K + 1):
        for vertex in range(1, N + 1):
            for neighbor in graph[vertex]:
                dp[walk_length][neighbor] += dp[walk_length - 1][vertex]
    
    print(dp[K][1])
    

    时间复杂度为O(K * (N + E)),其中 E 是边数。额外的空间复杂度为O(NK),稍加努力即可降为O(N)。如果你的图很密集,它最多有|E| = O(N^2),所以这是O(K * N * N);如果你的图是稀疏的,就像一棵树,这是O(K * N)。邻接矩阵和邻接表之间的转换是O(N^2)的一个加法因子。

    大K

    据我所知,对于大 K 的最佳答案(复杂性)是使用类似于您建议的 adjacency matrix exponentiation 的策略。这种方法是有效的,但我们可以更聪明一点。

    回想一下,未加权、无向图的邻接矩阵是实对称矩阵,因此它是diagonalizable. 设邻接矩阵为 A,谱分解为 A = P * D * (P^- 1),其中 D 是对角矩阵。然后我们找到 A^K = P * (D^K) * (P^-1) 的左上元素,这需要对单个特征值进行 N 次幂运算,然后是 2N 次乘法和加法。

    由于特征值的大小受最大度数或O(N) 的限制,因此主导项由计算具有 O(log N) 位数的数字 x 的 x^K 的成本决定。确定这里的时间复杂度很复杂:我们必须开始讨论计算模型,以及整数乘法的成本。如果我们谈论的是计算的词 RAM 模型,或者机器词足够大以处理输出的模型,那么您的 O(N^3 log K) 绑定就可以工作。如果您只想要以某个固定数字为模的答案,它也可以更普遍地工作。否则,如果 K 任意大,我们的 N 个特征值幂每个可以有 O(K) 位,所以这最后一步可能需要 O( K * N log log N) 时间,这仍然比原始的全矩阵求幂更有效(至少是 @987654336 @ 在这种情况下)。

    矩阵分解的复杂度与矩阵乘法的复杂度密切相关,这是一个开放性问题。介于 N^2 和 N^(2.373) 之间,但理论上最优复杂度的问题是best addressed in math stackexchange questions like this one,通常与实际问题无关。

    【讨论】:

    • 感谢您的详细解答!这让事情有点清楚了。
    猜你喜欢
    • 2015-07-13
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多