Skip to content

Commit

Permalink
Dinitz correction (networkx#6968)
Browse files Browse the repository at this point in the history
* Update dinitz_alg.py

* Update:

* Resubmit and use tuples

* Modify the for loop

* Use reversed pairwise in the for loop
  • Loading branch information
YVWX authored and cvanelteren committed Apr 22, 2024
1 parent 3e3cdb3 commit 0c1a257
Showing 1 changed file with 44 additions and 20 deletions.
64 changes: 44 additions & 20 deletions networkx/algorithms/flow/dinitz_alg.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,35 +173,59 @@ def dinitz_impl(G, s, t, capacity, residual, cutoff):

def breath_first_search():
parents = {}
queue = deque([s])
vertex_dist = {s: 0}
queue = deque([(s, 0)])
# Record all the potential edges of shortest augmenting paths
while queue:
if t in parents:
break
u = queue.popleft()
for v in R_succ[u]:
attr = R_succ[u][v]
if v not in parents and attr["capacity"] - attr["flow"] > 0:
parents[v] = u
queue.append(v)
u, dist = queue.popleft()
for v, attr in R_succ[u].items():
if attr["capacity"] - attr["flow"] > 0:
if v in parents:
if vertex_dist[v] == dist + 1:
parents[v].append(u)
else:
parents[v] = deque([u])
vertex_dist[v] = dist + 1
queue.append((v, dist + 1))
return parents

def depth_first_search(parents):
# DFS to find all the shortest augmenting paths
"""Build a path using DFS starting from the sink"""
path = []
total_flow = 0
u = t
flow = INF
while u != s:
path.append(u)
v = parents[u]
flow = min(flow, R_pred[u][v]["capacity"] - R_pred[u][v]["flow"])
# path also functions as a stack
path = [u]
# The loop ends with no augmenting path left in the layered graph
while True:
if len(parents[u]) > 0:
v = parents[u][0]
path.append(v)
else:
path.pop()
if len(path) == 0:
break
v = path[-1]
parents[v].popleft()
# Augment the flow along the path found
if v == s:
flow = INF
for u, v in pairwise(path):
flow = min(flow, R_pred[u][v]["capacity"] - R_pred[u][v]["flow"])
for u, v in pairwise(reversed(path)):
R_pred[v][u]["flow"] += flow
R_pred[u][v]["flow"] -= flow
# Find the proper node to continue the search
if R_pred[v][u]["capacity"] - R_pred[v][u]["flow"] == 0:
parents[v].popleft()
while path[-1] != v:
path.pop()
total_flow += flow
v = path[-1]
u = v
path.append(s)
# Augment the flow along the path found
if flow > 0:
for u, v in pairwise(path):
R_pred[u][v]["flow"] += flow
R_pred[v][u]["flow"] -= flow
return flow
return total_flow

flow_value = 0
while flow_value < cutoff:
Expand Down

0 comments on commit 0c1a257

Please sign in to comment.