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

时间:2017-01-08 17:15:49

标签: 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

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])

例如,如果我使用上述程序来解决以下网络:

graph with a cycle

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

更新

我忘了跟踪上面代码中深度优先搜索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)

然而它仍然无限循环。

0 个答案:

没有答案