Find a maximum single-commodity flow using the highest-label preflow-push algorithm.
This function returns the residual network resulting after computing the maximum flow. See below for details about the conventions NetworkX uses for defining residual networks.
This algorithm has a running time of \(O(n^2 \sqrt{m})\) for \(n\) nodes and \(m\) edges.
Parameters: | G : NetworkX graph
s : node
t : node
capacity : string
residual : NetworkX graph
global_relabel_freq : integer, float
value_only : bool
|
---|---|
Returns: | R : NetworkX DiGraph
|
Raises: | NetworkXError :
NetworkXUnbounded :
|
See also
maximum_flow(), minimum_cut(), edmonds_karp(), ford_fulkerson(), shortest_augmenting_path()
Notes
The residual network R from an input graph G has the same nodes as G. R is a DiGraph that contains a pair of edges (u, v) and (v, u) iff (u, v) is not a self-loop, and at least one of (u, v) and (v, u) exists in G. For each node u in R, R.node[u]['excess'] represents the difference between flow into u and flow out of u.
For each edge (u, v) in R, R[u][v]['capacity'] is equal to the capacity of (u, v) in G if it exists in G or zero otherwise. If the capacity is infinite, R[u][v]['capacity'] will have a high arbitrary finite value that does not affect the solution of the problem. This value is stored in R.graph['inf']. For each edge (u, v) in R, R[u][v]['flow'] represents the flow function of (u, v) and satisfies R[u][v]['flow'] == -R[v][u]['flow'].
The flow value, defined as the total flow into t, the sink, is stored in R.graph['flow_value']. Reachability to t using only edges (u, v) such that R[u][v]['flow'] < R[u][v]['capacity'] induces a minimum s-t cut.
Examples
>>> import networkx as nx
>>> from networkx.algorithms.flow import preflow_push
The functions that implement flow algorithms and output a residual network, such as this one, are not imported to the base NetworkX namespace, so you have to explicitly import them from the flow package.
>>> G = nx.DiGraph()
>>> G.add_edge('x','a', capacity=3.0)
>>> G.add_edge('x','b', capacity=1.0)
>>> G.add_edge('a','c', capacity=3.0)
>>> G.add_edge('b','c', capacity=5.0)
>>> G.add_edge('b','d', capacity=4.0)
>>> G.add_edge('d','e', capacity=2.0)
>>> G.add_edge('c','y', capacity=2.0)
>>> G.add_edge('e','y', capacity=3.0)
>>> R = preflow_push(G, 'x', 'y')
>>> flow_value = nx.maximum_flow_value(G, 'x', 'y')
>>> flow_value == R.graph['flow_value']
True
>>> # preflow_push also stores the maximum flow value
>>> # in the excess attribute of the sink node t
>>> flow_value == R.node['y']['excess']
True
>>> # For some problems, you might only want to compute a
>>> # maximum preflow.
>>> R = preflow_push(G, 'x', 'y', value_only=True)
>>> flow_value == R.graph['flow_value']
True
>>> flow_value == R.node['y']['excess']
True