1
- # Ford-Fulkerson Algorithm for Maximum Flow Problem
2
1
"""
2
+ Ford-Fulkerson Algorithm for Maximum Flow Problem
3
+ * https://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm
4
+
3
5
Description:
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
6
8
"""
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.
7
31
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
8
41
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
15
45
16
46
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 :
20
51
queue .append (ind )
21
52
visited [ind ] = True
22
- parent [ind ] = u
53
+ parents [ind ] = u
54
+ return visited [sink ]
23
55
24
- return visited [t ]
25
56
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.
26
60
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
29
83
parent = [- 1 ] * (len (graph ))
30
84
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
33
89
s = sink
34
90
35
91
while s != source :
36
- # Find the minimum value in select path
92
+ # Find the minimum value in the selected path
37
93
path_flow = min (path_flow , graph [parent [s ]][s ])
38
94
s = parent [s ]
39
95
@@ -45,17 +101,12 @@ def ford_fulkerson(graph, source, sink):
45
101
graph [u ][v ] -= path_flow
46
102
graph [v ][u ] += path_flow
47
103
v = parent [v ]
104
+
48
105
return max_flow
49
106
50
107
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
59
110
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