📜  warshall 算法传递闭包计算器 (1)

📅  最后修改于: 2023-12-03 15:21:06.331000             🧑  作者: Mango

Warshall算法传递闭包计算器

Warshall算法是一种传递闭包计算的经典算法,用于求解有向图的传递闭包。传递闭包是指有向图上的一个新的图,其中如果存在一条从顶点i到顶点j的路径,则在传递闭包图中i和j之间存在一条有向边。

算法原理

Warshall算法的基本思想是利用矩阵相乘来计算传递闭包。假设传递闭包矩阵为T,邻接矩阵为A,则T和A的元素都是0或1。如果存在一条从i到j的路径,那么A[i][j]的值为1,否则为0;如果i到j的路径存在,那么T[i][j]的值为1,否则为0。矩阵的乘法根据A的定义可以得到T的定义:

T[i][j] = 1 if A[i][j] = 1 or (T[i][k] = 1 and T[k][j] = 1 for some k)
T[i][j] = 0 otherwise

这个定义的意思是,如果A[i][j]本身就是1,或者存在中间顶点k,使得i和k之间存在一条路径且k和j之间也存在一条路径,那么T[i][j]就是1,否则就是0。

为了求解传递闭包,我们需要进行n次矩阵乘法,其中n是图中顶点的个数。我们可以用一个n × n 的矩阵R来保存经过0到n−1次矩阵乘法后的传递闭包。初始时,R等于A,然后对A执行n次矩阵乘法,每次都将结果存入R中。最后得到的R就是传递闭包矩阵。

程序实现

下面是一个Python实现的Warshall算法计算器:

def transitive_closure(adj_matrix):
    n = len(adj_matrix)
    tc = [[adj_matrix[i][j] for j in range(n)] for i in range(n)]
    for k in range(n):
        for i in range(n):
            for j in range(n):
                tc[i][j] = tc[i][j] or (tc[i][k] and tc[k][j])
    return tc

这个函数接受一个邻接矩阵作为参数,返回传递闭包矩阵。它的实现和上面给出的定义是一致的。

使用说明

使用该计算器需要提供有向图的邻接矩阵。邻接矩阵是一个n × n的矩阵,其中A[i][j]表示从i到j是否有一条有向边。如果有则为1,否则为0。

例如,对于如下的有向图:

   1 ---> 2 
   ^      | 
   |      | 
   v      v 
   4 ---> 3 

它的邻接矩阵为:

[[0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1],
 [1, 0, 0, 0]]

我们可以使用上面的计算器来计算传递闭包,得到的结果为:

[[1, 1, 1, 1],
 [1, 1, 1, 1],
 [1, 1, 1, 1],
 [1, 1, 1, 1]]

这个结果表示在该有向图上,任意两个顶点之间都存在一条路径。

总结

Warshall算法是一种经典的传递闭包计算算法,它利用矩阵相乘的方法计算传递闭包。该算法的时间复杂度为O(n^3),但由于该算法的实现非常简单,因此常被用于实际应用中。