如何检查图表是否包含负循环,但无法从源头获得它?

时间:2019-07-18 10:29:13

标签: python-3.x graph shortest-path bellman-ford

我想检查我的加权图是否有负周期。对于使用Bellman-ford算法,我们需要选择一个源节点,将所有其他距离初始化为无穷大,如果顶点数为n,则开始放松n-1次。我的问题是,无法到达的节点将始终具有无限距离,并且在第n次迭代中也不会更改。因此,对于无法到达的负周期,我们将得到错误的输出。

def negative_cycle(adj, cost):
    dist = [float('inf')] * n
    prev = [None] * n
    dist[0] = 0
    for _ in range(n-1):
        for u, edges in enumerate(adj):
            for i, v in enumerate(edges):
                if dist[v]>dist[u]+cost[u][i]:
                    dist[v]=dist[u]+cost[u][i]
                    prev[v]=u
    for u, edges in enumerate(adj):
        for i, v in enumerate(edges):
            if dist[v]>dist[u]+cost[u][i]:
                return 1
    return 0

2 个答案:

答案 0 :(得分:0)

您应该为每个连接的组件运行它。为此,以获取顶点v的方式实现您的函数(在您的函数中,它始终是顶点0),然后实现一个循环,并为距离设置为无穷大的每个顶点调用您在该顶点上的功能。

答案 1 :(得分:0)

如果您不关心最短路径,而只想检测一个负周期,则可以将所有顶点的初始距离设置为0。这与创建假想源 s的效果相同并将 s 连接到权重为0的所有其他顶点。

您的代码将类似于以下代码(可能是我不了解Python,所以我的语法可能不正确)。

def negative_cycle(adj, cost):
    dist = [0] * n
    prev = [None] * n
    for _ in range(n-1):
        for u, edges in enumerate(adj):
            for i, v in enumerate(edges):
                if dist[v]>dist[u]+cost[u][i]:
                    dist[v]=dist[u]+cost[u][i]
                    prev[v]=u
    for u, edges in enumerate(adj):
        for i, v in enumerate(edges):
            if dist[v]>dist[u]+cost[u][i]:
                return 1
    return 0