1- # Ford-Fulkerson Algorithm for Maximum Flow Problem 
21""" 
2+ Ford-Fulkerson Algorithm for Maximum Flow Problem 
3+ * https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm 
4+ 
35Description: 
4-     (1) Start with initial flow as 0;  
5-     (2) Choose augmenting path from source to sink and add path to flow;  
6+     (1) Start with initial flow as 0 
7+     (2) Choose the  augmenting path from source to sink and add the  path to flow 
68""" 
9+ graph  =  [
10+     [0 , 16 , 13 , 0 , 0 , 0 ],
11+     [0 , 0 , 10 , 12 , 0 , 0 ],
12+     [0 , 4 , 0 , 0 , 14 , 0 ],
13+     [0 , 0 , 9 , 0 , 0 , 20 ],
14+     [0 , 0 , 0 , 7 , 0 , 4 ],
15+     [0 , 0 , 0 , 0 , 0 , 0 ],
16+ ]
17+ 
18+ 
19+ def  breadth_first_search (graph : list , source : int , sink : int , parents : list ) ->  bool :
20+     """ 
21+     This function returns True if there is a node that has not iterated. 
22+ 
23+     Args: 
24+         graph: Adjacency matrix of graph 
25+         source: Source 
26+         sink: Sink 
27+         parents: Parent list 
28+ 
29+     Returns: 
30+         True if there is a node that has not iterated. 
731
32+     >>> breadth_first_search(graph, 0, 5, [-1, -1, -1, -1, -1, -1]) 
33+     True 
34+     >>> breadth_first_search(graph, 0, 6, [-1, -1, -1, -1, -1, -1]) 
35+     Traceback (most recent call last): 
36+         ... 
37+     IndexError: list index out of range 
38+     """ 
39+     visited  =  [False ] *  len (graph )  # Mark all nodes as not visited 
40+     queue  =  []  # breadth-first search queue 
841
9- def  bfs (graph , s , t , parent ):
10-     # Return True if there is node that has not iterated. 
11-     visited  =  [False ] *  len (graph )
12-     queue  =  []
13-     queue .append (s )
14-     visited [s ] =  True 
42+     # Source node 
43+     queue .append (source )
44+     visited [source ] =  True 
1545
1646    while  queue :
17-         u  =  queue .pop (0 )
18-         for  ind  in  range (len (graph [u ])):
19-             if  visited [ind ] is  False  and  graph [u ][ind ] >  0 :
47+         u  =  queue .pop (0 )  # Pop the front node 
48+         # Traverse all adjacent nodes of u 
49+         for  ind , node  in  enumerate (graph [u ]):
50+             if  visited [ind ] is  False  and  node  >  0 :
2051                queue .append (ind )
2152                visited [ind ] =  True 
22-                 parent [ind ] =  u 
53+                 parents [ind ] =  u 
54+     return  visited [sink ]
2355
24-     return  visited [t ]
2556
57+ def  ford_fulkerson (graph : list , source : int , sink : int ) ->  int :
58+     """ 
59+     This function returns the maximum flow from source to sink in the given graph. 
2660
27- def  ford_fulkerson (graph , source , sink ):
28-     # This array is filled by BFS and to store path 
61+     CAUTION: This function changes the given graph. 
62+ 
63+     Args: 
64+         graph: Adjacency matrix of graph 
65+         source: Source 
66+         sink: Sink 
67+ 
68+     Returns: 
69+         Maximum flow 
70+ 
71+     >>> test_graph = [ 
72+     ...     [0, 16, 13, 0, 0, 0], 
73+     ...     [0, 0, 10, 12, 0, 0], 
74+     ...     [0, 4, 0, 0, 14, 0], 
75+     ...     [0, 0, 9, 0, 0, 20], 
76+     ...     [0, 0, 0, 7, 0, 4], 
77+     ...     [0, 0, 0, 0, 0, 0], 
78+     ... ] 
79+     >>> ford_fulkerson(test_graph, 0, 5) 
80+     23 
81+     """ 
82+     # This array is filled by breadth-first search and to store path 
2983    parent  =  [- 1 ] *  (len (graph ))
3084    max_flow  =  0 
31-     while  bfs (graph , source , sink , parent ):
32-         path_flow  =  float ("Inf" )
85+ 
86+     # While there is a path from source to sink 
87+     while  breadth_first_search (graph , source , sink , parent ):
88+         path_flow  =  int (1e9 )  # Infinite value 
3389        s  =  sink 
3490
3591        while  s  !=  source :
36-             # Find the minimum value in select  path 
92+             # Find the minimum value in the selected  path 
3793            path_flow  =  min (path_flow , graph [parent [s ]][s ])
3894            s  =  parent [s ]
3995
@@ -45,17 +101,12 @@ def ford_fulkerson(graph, source, sink):
45101            graph [u ][v ] -=  path_flow 
46102            graph [v ][u ] +=  path_flow 
47103            v  =  parent [v ]
104+ 
48105    return  max_flow 
49106
50107
51- graph  =  [
52-     [0 , 16 , 13 , 0 , 0 , 0 ],
53-     [0 , 0 , 10 , 12 , 0 , 0 ],
54-     [0 , 4 , 0 , 0 , 14 , 0 ],
55-     [0 , 0 , 9 , 0 , 0 , 20 ],
56-     [0 , 0 , 0 , 7 , 0 , 4 ],
57-     [0 , 0 , 0 , 0 , 0 , 0 ],
58- ]
108+ if  __name__  ==  "__main__" :
109+     from  doctest  import  testmod 
59110
60- source ,  sink   =   0 ,  5 
61- print (ford_fulkerson (graph , source , sink ) )
111+      testmod () 
112+      print (f" { ford_fulkerson (graph , source = 0 , sink = 5 )  =   } " 
0 commit comments