I'm trying to find maximum flow in a network using Ford Fulkerson
algorithm, it works great for acyclic graphs however if there's a cycle it'd loop forever. Here's the code I'm using to find the max flow:
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])
For example if I use the above program to solve the following network:
It will run indefinitely, how do I find the maximum flow in such networks?
Update:
I forgot to keep track of visited edges in the depth first search dfs function in the code above, so I fixed it like so:
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)
However it's still looping indefinitely.