Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何计算包含循环的有向图中的最大流量_Python_Algorithm_Graph_Network Flow - Fatal编程技术网

Python 如何计算包含循环的有向图中的最大流量

Python 如何计算包含循环的有向图中的最大流量,python,algorithm,graph,network-flow,Python,Algorithm,Graph,Network Flow,我试图用Ford Fulkerson算法来寻找网络中的最大流量,它对非循环图非常有效,但是如果有一个循环,它将永远循环。下面是我用来查找最大流量的代码: class Edge (object): reverse = None def __init__ (self, u, v, w): self.source = u self.sink = v self.capacity = w self.flow = 0 cl

我试图用Ford Fulkerson算法来寻找网络中的最大流量,它对非循环图非常有效,但是如果有一个循环,它将永远循环。下面是我用来查找最大流量的代码:

class Edge (object):
    reverse = None
    def __init__ (self, u, v, w):
        self.source = u
        self.sink = v  
        self.capacity = w
        self.flow = 0

class FlowNetwork (object):
    def __init__ (self, path):
        rows = len (path)
        cols = len (path[0])
        self.graph = {self.vname (x, rows): [] for x in range (rows)}
        for r in range (rows):
            for c in range (cols):
                if path[r][c] > 0:
                    u = self.vname (r, rows)
                    v = self.vname (c, rows)
                    edge = Edge (u, v, path[r][c])
                    reverse = Edge (v, u, 0)
                    edge.reverse = reverse
                    reverse.reverse = edge
                    self.graph[u].append (edge)
                    self.graph[v].append (reverse)

    def vname (self, x, t):
        return 's' if x == 0 else 't' if x == t - 1 else 'v' + str (x)

    def dfs (self, source, sink):
        queue = [[x] for x in self.graph[source]]
        while queue:
            path = queue.pop (0)
            vertex = path[-1]
            if vertex.sink == sink: return path
            for edge in self.graph[vertex.sink]:
                if edge.capacity - edge.flow > 0:
                    if edge not in path and edge.reverse not in path:
                        queue.append ([x for x in path] + [edge])

    def maxFlow (self, source, sink):
        path = self.dfs (source, sink)
        while path != None:
            flow = min ([edge.capacity - edge.flow for edge in path])
            for edge in path:
                edge.flow += flow
                edge.reverse.flow -= flow
            path = self.dfs (source, sink)
        return sum (edge.flow for edge in self.graph[source])
例如,如果我使用上述程序求解以下网络:

它将无限期地运行,如何在这样的网络中找到最大流量

更新: 在上面的代码中,我忘记了在深度优先搜索dfs函数中跟踪访问的边,因此我将其修复如下:

def dfs (self, source, sink):
    queue = [[x] for x in self.graph[source]]
    visited = []
    while queue:
        path = queue.pop (0)
        vertex = path[-1]
        if vertex.sink == sink: return path
        for edge in self.graph[vertex.sink]:
            if edge not in visited and edge.capacity - edge.flow > 0:
                if edge not in path and edge.reverse not in path:
                    queue.append ([x for x in path] + [edge])
                    visited.append (edge)

然而,它仍然无限期地循环。

我还没有详细研究您的代码,但一下子看起来您的DFS不是一个合适的DFS。它需要一个“已访问集”以避免循环。您应该看看FF的一个变体(如Edmons Karp),它详细说明了用于查找扩充路径的方法。@Gene I修复了dfs函数,但由于某种原因,它仍然在反向边(s,t)上永远循环,这是为什么?可能是因为您没有考虑反向边列表?还要注意,为了避免增加渐进运行时间,您应该为访问集使用实数集,而不是列表。访问集应该包含顶点,而不是边。通常,您的代码看起来很奇怪,因为它们的边和顶点之间没有明确的区别(应该有)。这可能是错误的根源。我还没有详细研究过你的代码,但马上看来你的DFS不是一个合适的DFS。它需要一个“已访问集”以避免循环。您应该看看FF的一个变体(如Edmons Karp),它详细说明了用于查找扩充路径的方法。@Gene I修复了dfs函数,但由于某种原因,它仍然在反向边(s,t)上永远循环,这是为什么?可能是因为您没有考虑反向边列表?还要注意,为了避免增加渐进运行时间,您应该为访问集使用实数集,而不是列表。访问集应该包含顶点,而不是边。通常,您的代码看起来很奇怪,因为它们的边和顶点之间没有明确的区别(应该有)。这可能是错误的根源。