preflow_push#
- preflow_push(G, s, t, capacity='capacity', residual=None, global_relabel_freq=1, value_only=False)[source]#
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:
- GNetworkX graph
Edges of the graph are expected to have an attribute called ‘capacity’. If this attribute is not present, the edge is considered to have infinite capacity.
- snode
Source node for the flow.
- tnode
Sink node for the flow.
- capacitystring or function (default= ‘capacity’)
If this is a string, then edge capacity will be accessed via the edge attribute with this key (that is, the capacity of the edge joining
utovwill beG.edges[u, v][capacity]). If no such edge attribute exists, the capacity of the edge is assumed to be infinite.If this is a function, the capacity of an edge is the value returned by the function. The function must accept exactly three positional arguments: the two endpoints of an edge and the dictionary of edge attributes for that edge. The function must return a number or None to indicate a hidden edge.
- residualNetworkX graph
Residual network on which the algorithm is to be executed. If None, a new residual network is created. Default value: None.
- global_relabel_freqinteger, float
Relative frequency of applying the global relabeling heuristic to speed up the algorithm. If it is None, the heuristic is disabled. Default value: 1.
- value_onlybool
If False, compute a maximum flow; otherwise, compute a maximum preflow which is enough for computing the maximum flow value. Default value: False.
- Returns:
- RNetworkX DiGraph
Residual network after computing the maximum flow.
- Raises:
- NetworkXError
The algorithm does not support MultiGraph and MultiDiGraph. If the input graph is an instance of one of these two classes, a NetworkXError is raised.
- NetworkXUnbounded
If the graph has a path of infinite capacity, the value of a feasible flow on the graph is unbounded above and the function raises a NetworkXUnbounded.
Notes
The residual network
Rfrom an input graphGhas the same nodes asG.Ris 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 inG. For each nodeuinR,R.nodes[u]['excess']represents the difference between flow intouand flow out ofu.For each edge
(u, v)inR,R[u][v]['capacity']is equal to the capacity of(u, v)inGif it exists inGor 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 inR.graph['inf']. For each edge(u, v)inR,R[u][v]['flow']represents the flow function of(u, v)and satisfiesR[u][v]['flow'] == -R[v][u]['flow'].The flow value, defined as the total flow into
t, the sink, is stored inR.graph['flow_value']. Reachability totusing only edges(u, v)such thatR[u][v]['flow'] < R[u][v]['capacity']induces a minimums-tcut.Examples
>>> 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.nodes["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.nodes["y"]["excess"] True