Skip to content

Commit eb72b1e

Browse files
committed
Address reviewer feedback: update docstrings and type hints
1 parent aa7661a commit eb72b1e

File tree

1 file changed

+60
-27
lines changed

1 file changed

+60
-27
lines changed

networking_flow/dinic.py

Lines changed: 60 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,31 @@
1818

1919

2020
class Dinic:
21-
def __init__(self, n: int):
21+
"""
22+
Implements Dinic's Algorithm for finding the Maximum Flow in a flow network.
23+
"""
24+
25+
def __init__(self, n: int) -> None:
2226
"""
2327
Initialize the Dinic algorithm with n nodes.
24-
Nodes are 0-indexed.
28+
29+
Args:
30+
n: Total number of nodes in the network. Nodes are 0-indexed.
2531
"""
2632
self.n = n
27-
self.graph = [[] for _ in range(n)]
28-
self.level = []
33+
self.graph: list[list[list[int]]] = [[] for _ in range(n)]
34+
self.level: list[int] = []
2935

3036
def add_edge(self, u: int, v: int, capacity: int) -> None:
3137
"""
32-
Adds a directed edge with a capacity.
33-
Note: Stores indices to handle the residual edges efficiently.
38+
Adds a directed edge with a specified capacity to the graph.
39+
40+
Note: This stores indices to handle residual edges efficiently.
41+
42+
Args:
43+
u: Source node index.
44+
v: Destination node index.
45+
capacity: Capacity of the edge.
3446
"""
3547
# Forward edge: [v, capacity, index_of_reverse_edge]
3648
self.graph[u].append([v, capacity, len(self.graph[v])])
@@ -41,11 +53,19 @@ def bfs(self, source: int, sink: int) -> bool:
4153
"""
4254
Builds the Level Graph (L_G) using BFS.
4355
Corresponds to the INITIALIZE step in the Even-Itai refinement.
44-
Returns True if the sink is reachable, False otherwise.
56+
57+
Args:
58+
source: The source node index.
59+
sink: The sink (target) node index.
60+
61+
Returns:
62+
True if the sink is reachable from the source in the residual graph,
63+
False otherwise.
4564
"""
4665
self.level = [-1] * self.n
4766
self.level[source] = 0
48-
# using list as queue to avoid importing collections.deque
67+
# Using list as queue to avoid importing collections.deque
68+
# to adhere to "no external imports" policy.
4969
queue = [source]
5070

5171
while queue:
@@ -57,19 +77,20 @@ def bfs(self, source: int, sink: int) -> bool:
5777

5878
return self.level[sink] >= 0
5979

60-
def dfs(self, u: int, sink: int, flow: int, ptr: list) -> int:
80+
def dfs(self, u: int, sink: int, flow: int, ptr: list[int]) -> int:
6181
"""
62-
Finds a blocking flow in the Level Graph.
82+
Finds a blocking flow in the Level Graph using DFS.
6383
Combines the ADVANCE and RETREAT steps.
6484
6585
Args:
6686
u: Current node.
6787
sink: Target node.
68-
flow: Current flow bottleneck.
69-
ptr: Current arc pointers (to implement 'Remove saturated edges').
88+
flow: Current flow bottleneck along the path.
89+
ptr: List of current arc pointers for each node (to implement
90+
'Remove saturated edges' optimization).
7091
7192
Returns:
72-
The amount of flow pushed.
93+
The amount of flow successfully pushed from u to sink.
7394
"""
7495
if u == sink or flow == 0:
7596
return flow
@@ -98,19 +119,31 @@ def max_flow(self, source: int, sink: int) -> int:
98119
"""
99120
Computes the maximum flow from source to sink.
100121
101-
>>> dinic = Dinic(6)
102-
>>> dinic.add_edge(0, 1, 16)
103-
>>> dinic.add_edge(0, 2, 13)
104-
>>> dinic.add_edge(1, 2, 10)
105-
>>> dinic.add_edge(1, 3, 12)
106-
>>> dinic.add_edge(2, 1, 4)
107-
>>> dinic.add_edge(2, 4, 14)
108-
>>> dinic.add_edge(3, 2, 9)
109-
>>> dinic.add_edge(3, 5, 20)
110-
>>> dinic.add_edge(4, 3, 7)
111-
>>> dinic.add_edge(4, 5, 4)
112-
>>> dinic.max_flow(0, 5)
113-
23
122+
Time Complexity:
123+
- O(V^2 * E) for general networks.
124+
- O(E * sqrt(V)) for unit networks (e.g., Bipartite Matching).
125+
126+
Args:
127+
source: The source node index.
128+
sink: The sink (target) node index.
129+
130+
Returns:
131+
The maximum flow value.
132+
133+
Examples:
134+
>>> dinic = Dinic(6)
135+
>>> dinic.add_edge(0, 1, 16)
136+
>>> dinic.add_edge(0, 2, 13)
137+
>>> dinic.add_edge(1, 2, 10)
138+
>>> dinic.add_edge(1, 3, 12)
139+
>>> dinic.add_edge(2, 1, 4)
140+
>>> dinic.add_edge(2, 4, 14)
141+
>>> dinic.add_edge(3, 2, 9)
142+
>>> dinic.add_edge(3, 5, 20)
143+
>>> dinic.add_edge(4, 3, 7)
144+
>>> dinic.add_edge(4, 5, 4)
145+
>>> dinic.max_flow(0, 5)
146+
23
114147
"""
115148
max_f = 0
116149
# While we can build a Level Graph (source can reach sink)
@@ -146,4 +179,4 @@ def max_flow(self, source: int, sink: int) -> int:
146179
for u, v, c in edges:
147180
dn.add_edge(u, v, c)
148181

149-
print(f"Maximum Flow: {dn.max_flow(0, 5)}")
182+
print(f"Maximum Flow: {dn.max_flow(0, 5)}")

0 commit comments

Comments
 (0)