Handling graphs with flows / weights on nodes
If your graph has flow values or weights associated with the nodes, instead of the edges, we provide a simple way to handle them, via the class NodeExpandedDiGraph
, as described below.
See this example on how to correct weights on node-weighted graphs, support subpath constraints, and then apply Minimum Flow Decomposition on them.
NodeExpandedDiGraph
NodeExpandedDiGraph(
G: DiGraph,
node_flow_attr: str,
try_filling_in_missing_flow_attr: bool = False,
node_length_attr: str = None,
)
Bases: DiGraph
This class is a subclass of the networkx DiGraph class. It is used to represent a directed graph
where all nodes v
have been “expanded” or “subdivided” into an edge (v.0, v.1)
. This is useful for representing
graphs where the flow values, or weights, are associated with the nodes, rather than the edges.
These expanded edges are then added to the edges_to_ignore
list, available as a property of this class.
Using this class
- Create a
NodeExpandedDiGraph
object by passing a directed graphG
and the attribute namenode_flow_attr
from where to get the flow values / weights on the nodes. - Pass the edges from the
edges_to_ignore
attribute of this class to the decomposition models, in order to ignore all original edges of the graph, and thus consider in the constraints only the new edges added in the expanded graph (which have flow values). - Solve the decomposition model on the expanded graph.
- Use the
condense_paths
method to condense the solution paths (which are in the expanded graph) to paths in the original graph.
Parameters
-
G : nx.DiGraph
The input directed graph, as networkx DiGraph.
-
node_flow_attr : str
The attribute name from where to get the flow values / weights on the nodes. This attribute for each
v
is then set to the edge(v.0, v.1)
connecting the new expanded nodes. This attribute can be missing from some nodes of the graph, in which case the edge(v.0, v.1)
is added toedges_to_ignore
. -
try_filling_in_missing_flow_attr : bool
, optionalIf
True
, try filling in missing flow values in the expanded graph (i.e., if some original edge does not have the attribute specified bynode_flow_attr
), by setting them to the flow values of a flow between the sources and the sinks of the original graph, such that for every edge wherenode_flow_attr
is present, the demand and capacity are equal to the value specified bynode_flow_attr
. Default isFalse
. -
node_length_attr : str
, optionalThe attribute name from where to get the length values on the nodes. Default is
None
. If you specify this attribute, it may be missing from some nodes of the graph.
Example
import flowpaths as fp
import networkx as nx
graph = nx.DiGraph()
graph.add_node("s", flow=13)
graph.add_node("a", flow=6)
graph.add_node("b", flow=9)
graph.add_node("c", flow=13)
graph.add_node("d", flow=6)
graph.add_node("t", flow=13)
# Adding edges
graph.add_edges_from([("s", "a"), ("s", "b"), ("a", "b"), ("a", "c"), ("b", "c"), ("c", "d"), ("c", "t"), ("d", "t")])
# Expand the graph
ne_graph = fp.NodeExpandedDiGraph(graph, node_flow_attr="flow")
# Solve the problem on the expanded graph
mfd_model = fp.MinFlowDecomp(
ne_graph,
flow_attr="flow",
edges_to_ignore=ne_graph.edges_to_ignore,
)
mfd_model.solve()
if mfd_model.is_solved():
# Getting the solution in the expanded graph
solution = mfd_model.get_solution()
# Condensing the paths in the expanded graph to paths in the the original graph
original_paths = ne_graph.get_condensed_paths(solution["paths"])
print("Original paths:", original_paths)
print("Weights:", solution["weights"])
Source code in flowpaths/nodeexpandeddigraph.py
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
|
edges_to_ignore
property
List of edges to ignore when solving the decomposition model on the expanded graph.
These are the edges of the original graph, since only the new edges that have been introduced
for every node must considered in the decomposition model, with flow value from the node attribute node_flow_attr
.
get_condensed_paths
Condense a list of paths from the expanded graph to the original graph.
This assumes that:
- The nodes in the expanded graph are named as ‘node.0’ and ‘node.1’, where ‘node’ is the name of the node in the original graph.
- The paths are lists of nodes in the expanded graph, where the nodes are ordered as ‘nodeA.0’, ‘nodeA.1’, ‘nodeB.0’, ‘nodeB.1’, etc. Meaning that we always have two nodes from the same original node in sequence.
Parameters
-
paths : list
List of paths in the expanded graph.
Returns
-
condensed_paths: list
List of paths in the original graph.
Raises
-
ValueError
- If the node names in the expanded_path on even positions (starting from 0) do not end with
.0
. - If these node names (with the suffix
.0
removed) are not in the original graph.
- If the node names in the expanded_path on even positions (starting from 0) do not end with
Source code in flowpaths/nodeexpandeddigraph.py
get_expanded_edge
Get the the expanded edge ('node.0', 'node.1')
for a given node node
in the original graph.
Source code in flowpaths/nodeexpandeddigraph.py
get_expanded_subpath_constraints
Expand a list of subpath constraints from the original graph (where every constraint is a list nodes or edges in the original graph) to a list of subpath constraints in the expanded graph (where every constraint is a list of edges in the expanded graph).
- If the constraints are lists of nodes, then the corresponding edges are of type
('node.0', 'node.1')
- If the constraints are lists of edges of the form
(u,v)
, then the corresponding edges are of type('u.1', 'v.0')
Parameters
-
subpath_constraints : list
List of subpath constraints in the original graph.
Returns
-
expanded_constraints : list
List of subpath constraints in the expanded graph.