diff env/lib/python3.9/site-packages/networkx/algorithms/flow/mincost.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.9/site-packages/networkx/algorithms/flow/mincost.py	Mon Mar 22 18:12:50 2021 +0000
@@ -0,0 +1,331 @@
+"""
+Minimum cost flow algorithms on directed connected graphs.
+"""
+
+__all__ = ["min_cost_flow_cost", "min_cost_flow", "cost_of_flow", "max_flow_min_cost"]
+
+import networkx as nx
+
+
+def min_cost_flow_cost(G, demand="demand", capacity="capacity", weight="weight"):
+    r"""Find the cost of a minimum cost flow satisfying all demands in digraph G.
+
+    G is a digraph with edge costs and capacities and in which nodes
+    have demand, i.e., they want to send or receive some amount of
+    flow. A negative demand means that the node wants to send flow, a
+    positive demand means that the node want to receive flow. A flow on
+    the digraph G satisfies all demand if the net flow into each node
+    is equal to the demand of that node.
+
+    Parameters
+    ----------
+    G : NetworkX graph
+        DiGraph on which a minimum cost flow satisfying all demands is
+        to be found.
+
+    demand : string
+        Nodes of the graph G are expected to have an attribute demand
+        that indicates how much flow a node wants to send (negative
+        demand) or receive (positive demand). Note that the sum of the
+        demands should be 0 otherwise the problem in not feasible. If
+        this attribute is not present, a node is considered to have 0
+        demand. Default value: 'demand'.
+
+    capacity : string
+        Edges of the graph G are expected to have an attribute capacity
+        that indicates how much flow the edge can support. If this
+        attribute is not present, the edge is considered to have
+        infinite capacity. Default value: 'capacity'.
+
+    weight : string
+        Edges of the graph G are expected to have an attribute weight
+        that indicates the cost incurred by sending one unit of flow on
+        that edge. If not present, the weight is considered to be 0.
+        Default value: 'weight'.
+
+    Returns
+    -------
+    flowCost : integer, float
+        Cost of a minimum cost flow satisfying all demands.
+
+    Raises
+    ------
+    NetworkXError
+        This exception is raised if the input graph is not directed or
+        not connected.
+
+    NetworkXUnfeasible
+        This exception is raised in the following situations:
+
+            * The sum of the demands is not zero. Then, there is no
+              flow satisfying all demands.
+            * There is no flow satisfying all demand.
+
+    NetworkXUnbounded
+        This exception is raised if the digraph G has a cycle of
+        negative cost and infinite capacity. Then, the cost of a flow
+        satisfying all demands is unbounded below.
+
+    See also
+    --------
+    cost_of_flow, max_flow_min_cost, min_cost_flow, network_simplex
+
+    Notes
+    -----
+    This algorithm is not guaranteed to work if edge weights or demands
+    are floating point numbers (overflows and roundoff errors can
+    cause problems). As a workaround you can use integer numbers by
+    multiplying the relevant edge attributes by a convenient
+    constant factor (eg 100).
+
+    Examples
+    --------
+    A simple example of a min cost flow problem.
+
+    >>> G = nx.DiGraph()
+    >>> G.add_node("a", demand=-5)
+    >>> G.add_node("d", demand=5)
+    >>> G.add_edge("a", "b", weight=3, capacity=4)
+    >>> G.add_edge("a", "c", weight=6, capacity=10)
+    >>> G.add_edge("b", "d", weight=1, capacity=9)
+    >>> G.add_edge("c", "d", weight=2, capacity=5)
+    >>> flowCost = nx.min_cost_flow_cost(G)
+    >>> flowCost
+    24
+    """
+    return nx.network_simplex(G, demand=demand, capacity=capacity, weight=weight)[0]
+
+
+def min_cost_flow(G, demand="demand", capacity="capacity", weight="weight"):
+    r"""Returns a minimum cost flow satisfying all demands in digraph G.
+
+    G is a digraph with edge costs and capacities and in which nodes
+    have demand, i.e., they want to send or receive some amount of
+    flow. A negative demand means that the node wants to send flow, a
+    positive demand means that the node want to receive flow. A flow on
+    the digraph G satisfies all demand if the net flow into each node
+    is equal to the demand of that node.
+
+    Parameters
+    ----------
+    G : NetworkX graph
+        DiGraph on which a minimum cost flow satisfying all demands is
+        to be found.
+
+    demand : string
+        Nodes of the graph G are expected to have an attribute demand
+        that indicates how much flow a node wants to send (negative
+        demand) or receive (positive demand). Note that the sum of the
+        demands should be 0 otherwise the problem in not feasible. If
+        this attribute is not present, a node is considered to have 0
+        demand. Default value: 'demand'.
+
+    capacity : string
+        Edges of the graph G are expected to have an attribute capacity
+        that indicates how much flow the edge can support. If this
+        attribute is not present, the edge is considered to have
+        infinite capacity. Default value: 'capacity'.
+
+    weight : string
+        Edges of the graph G are expected to have an attribute weight
+        that indicates the cost incurred by sending one unit of flow on
+        that edge. If not present, the weight is considered to be 0.
+        Default value: 'weight'.
+
+    Returns
+    -------
+    flowDict : dictionary
+        Dictionary of dictionaries keyed by nodes such that
+        flowDict[u][v] is the flow edge (u, v).
+
+    Raises
+    ------
+    NetworkXError
+        This exception is raised if the input graph is not directed or
+        not connected.
+
+    NetworkXUnfeasible
+        This exception is raised in the following situations:
+
+            * The sum of the demands is not zero. Then, there is no
+              flow satisfying all demands.
+            * There is no flow satisfying all demand.
+
+    NetworkXUnbounded
+        This exception is raised if the digraph G has a cycle of
+        negative cost and infinite capacity. Then, the cost of a flow
+        satisfying all demands is unbounded below.
+
+    See also
+    --------
+    cost_of_flow, max_flow_min_cost, min_cost_flow_cost, network_simplex
+
+    Notes
+    -----
+    This algorithm is not guaranteed to work if edge weights or demands
+    are floating point numbers (overflows and roundoff errors can
+    cause problems). As a workaround you can use integer numbers by
+    multiplying the relevant edge attributes by a convenient
+    constant factor (eg 100).
+
+    Examples
+    --------
+    A simple example of a min cost flow problem.
+
+    >>> G = nx.DiGraph()
+    >>> G.add_node("a", demand=-5)
+    >>> G.add_node("d", demand=5)
+    >>> G.add_edge("a", "b", weight=3, capacity=4)
+    >>> G.add_edge("a", "c", weight=6, capacity=10)
+    >>> G.add_edge("b", "d", weight=1, capacity=9)
+    >>> G.add_edge("c", "d", weight=2, capacity=5)
+    >>> flowDict = nx.min_cost_flow(G)
+    """
+    return nx.network_simplex(G, demand=demand, capacity=capacity, weight=weight)[1]
+
+
+def cost_of_flow(G, flowDict, weight="weight"):
+    """Compute the cost of the flow given by flowDict on graph G.
+
+    Note that this function does not check for the validity of the
+    flow flowDict. This function will fail if the graph G and the
+    flow don't have the same edge set.
+
+    Parameters
+    ----------
+    G : NetworkX graph
+        DiGraph on which a minimum cost flow satisfying all demands is
+        to be found.
+
+    weight : string
+        Edges of the graph G are expected to have an attribute weight
+        that indicates the cost incurred by sending one unit of flow on
+        that edge. If not present, the weight is considered to be 0.
+        Default value: 'weight'.
+
+    flowDict : dictionary
+        Dictionary of dictionaries keyed by nodes such that
+        flowDict[u][v] is the flow edge (u, v).
+
+    Returns
+    -------
+    cost : Integer, float
+        The total cost of the flow. This is given by the sum over all
+        edges of the product of the edge's flow and the edge's weight.
+
+    See also
+    --------
+    max_flow_min_cost, min_cost_flow, min_cost_flow_cost, network_simplex
+
+    Notes
+    -----
+    This algorithm is not guaranteed to work if edge weights or demands
+    are floating point numbers (overflows and roundoff errors can
+    cause problems). As a workaround you can use integer numbers by
+    multiplying the relevant edge attributes by a convenient
+    constant factor (eg 100).
+    """
+    return sum((flowDict[u][v] * d.get(weight, 0) for u, v, d in G.edges(data=True)))
+
+
+def max_flow_min_cost(G, s, t, capacity="capacity", weight="weight"):
+    """Returns a maximum (s, t)-flow of minimum cost.
+
+    G is a digraph with edge costs and capacities. There is a source
+    node s and a sink node t. This function finds a maximum flow from
+    s to t whose total cost is minimized.
+
+    Parameters
+    ----------
+    G : NetworkX graph
+        DiGraph on which a minimum cost flow satisfying all demands is
+        to be found.
+
+    s: node label
+        Source of the flow.
+
+    t: node label
+        Destination of the flow.
+
+    capacity: string
+        Edges of the graph G are expected to have an attribute capacity
+        that indicates how much flow the edge can support. If this
+        attribute is not present, the edge is considered to have
+        infinite capacity. Default value: 'capacity'.
+
+    weight: string
+        Edges of the graph G are expected to have an attribute weight
+        that indicates the cost incurred by sending one unit of flow on
+        that edge. If not present, the weight is considered to be 0.
+        Default value: 'weight'.
+
+    Returns
+    -------
+    flowDict: dictionary
+        Dictionary of dictionaries keyed by nodes such that
+        flowDict[u][v] is the flow edge (u, v).
+
+    Raises
+    ------
+    NetworkXError
+        This exception is raised if the input graph is not directed or
+        not connected.
+
+    NetworkXUnbounded
+        This exception is raised if there is an infinite capacity path
+        from s to t in G. In this case there is no maximum flow. This
+        exception is also raised if the digraph G has a cycle of
+        negative cost and infinite capacity. Then, the cost of a flow
+        is unbounded below.
+
+    See also
+    --------
+    cost_of_flow, min_cost_flow, min_cost_flow_cost, network_simplex
+
+    Notes
+    -----
+    This algorithm is not guaranteed to work if edge weights or demands
+    are floating point numbers (overflows and roundoff errors can
+    cause problems). As a workaround you can use integer numbers by
+    multiplying the relevant edge attributes by a convenient
+    constant factor (eg 100).
+
+    Examples
+    --------
+    >>> G = nx.DiGraph()
+    >>> G.add_edges_from(
+    ...     [
+    ...         (1, 2, {"capacity": 12, "weight": 4}),
+    ...         (1, 3, {"capacity": 20, "weight": 6}),
+    ...         (2, 3, {"capacity": 6, "weight": -3}),
+    ...         (2, 6, {"capacity": 14, "weight": 1}),
+    ...         (3, 4, {"weight": 9}),
+    ...         (3, 5, {"capacity": 10, "weight": 5}),
+    ...         (4, 2, {"capacity": 19, "weight": 13}),
+    ...         (4, 5, {"capacity": 4, "weight": 0}),
+    ...         (5, 7, {"capacity": 28, "weight": 2}),
+    ...         (6, 5, {"capacity": 11, "weight": 1}),
+    ...         (6, 7, {"weight": 8}),
+    ...         (7, 4, {"capacity": 6, "weight": 6}),
+    ...     ]
+    ... )
+    >>> mincostFlow = nx.max_flow_min_cost(G, 1, 7)
+    >>> mincost = nx.cost_of_flow(G, mincostFlow)
+    >>> mincost
+    373
+    >>> from networkx.algorithms.flow import maximum_flow
+    >>> maxFlow = maximum_flow(G, 1, 7)[1]
+    >>> nx.cost_of_flow(G, maxFlow) >= mincost
+    True
+    >>> mincostFlowValue = sum((mincostFlow[u][7] for u in G.predecessors(7))) - sum(
+    ...     (mincostFlow[7][v] for v in G.successors(7))
+    ... )
+    >>> mincostFlowValue == nx.maximum_flow_value(G, 1, 7)
+    True
+
+    """
+    maxFlow = nx.maximum_flow_value(G, s, t, capacity=capacity)
+    H = nx.DiGraph(G)
+    H.add_node(s, demand=-maxFlow)
+    H.add_node(t, demand=maxFlow)
+    return min_cost_flow(H, capacity=capacity, weight=weight)