k-Flow Decomposition in General Graphs
See also
This class implements a solver for the problem of decomposing a flow in a general graph possibly with cycles into a given number \(k\) of walks (\(k\)-flow decomposition). This problem is a generalization of Minimum Flow Decomposition, in the sense that we are also given the number of walks that we need to decompose the flow in.
The class MinFlowDecompCycles uses this class internally to find the minimum value of \(k\) for which a \(k\)-flow decomposition exists.
Warning
Suppose that the number of walks of a minimum flow decomposition is \(k^*\). If we ask for a decomposition with \(k > k^*\) walks, this class will always return a decomposition with \(k\) walks, but some walks might have weight 0.
kFlowDecompCycles
kFlowDecompCycles(
G: DiGraph,
flow_attr: str,
k: int,
flow_attr_origin: str = "edge",
weight_type: type = float,
subset_constraints: list = [],
subset_constraints_coverage: float = 1.0,
elements_to_ignore: list = [],
additional_starts: list = [],
additional_ends: list = [],
optimization_options: dict = None,
solver_options: dict = {},
)
Bases: AbstractWalkModelDiGraph
This class implements the k-Flow Decomposition problem, namely it looks for a decomposition of a weighted general directed graph, possibly with cycles, into \(k\) weighted walks such that the flow on each edge of the graph equals the sum of the weights of the walks going through that edge (multiplied by the number of times the walk goes through it).
Parameters
-
G: nx.DiGraph
The input directed graph, as networkx DiGraph, which can have cycles.
-
flow_attr: str
The attribute name from where to get the flow values on the edges.
-
k: int
The number of walks to decompose in.
-
flow_attr_origin: str
, optionalThe origin of the flow attribute. Default is
"edge"
. Options:"edge"
: the flow attribute is assumed to be on the edges of the graph."node"
: the flow attribute is assumed to be on the nodes of the graph. See the documentation on how node-weighted graphs are handled.
-
weight_type: int | float
, optionalThe type of the weights and slacks (
int
orfloat
). Default isfloat
. -
subset_constraints: list
, optionalList of subset constraints. Default is an empty list. Each subset constraint is a list of edges that must be covered by some solution walk (in any order), according to the
subset_constraints_coverage
parameter (see below). -
subset_constraints_coverage: float
, optionalCoverage fraction of the subset constraints that must be covered by some solution walk.
Defaults to
1.0
, meaning that 100% of the edges (or nodes, ifflow_attr_origin
is"node"
) of the constraint need to be covered by some solution walk). See subset constraints documentation -
elements_to_ignore: list
, optionalList of edges (or nodes, if
flow_attr_origin
is"node"
) to ignore when adding constrains on flow explanation by the weighted walks. Default is an empty list. See ignoring edges documentation -
additional_starts: list
, optionalList of additional start nodes of the walks. Default is an empty list.
-
additional_ends: list
, optionalList of additional end nodes of the walks. Default is an empty list.
-
optimization_options: dict
, optionalDictionary with the optimization options. Default is
None
. See optimization options documentation. -
solver_options: dict
, optionalDictionary with the solver options. Default is
{}
. See solver options documentation.
Raises
-
ValueError
- If
weight_type
is notint
orfloat
. - If the flow attribute
flow_attr
is not specified in some edge. - If the graph contains edges with negative flow values.
- ValueError: If
flow_attr_origin
is notnode
oredge
.
- If
Source code in flowpaths/kflowdecompcycles.py
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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
|
get_solution
Retrieves the solution for the flow decomposition problem.
If the solution has already been computed and cached as self.solution
, it returns the cached solution.
Otherwise, it checks if the problem has been solved, computes the solution walks, weights
and caches the solution.
Returns
-
solution: dict
A dictionary containing the solution walks (key
"walks"
) and their corresponding weights (key"weights"
).
Raises
exception
If model is not solved.
Source code in flowpaths/kflowdecompcycles.py
is_valid_solution
Checks if the solution is valid by comparing the flow from walks with the flow attribute in the graph edges.
Raises
- ValueError: If the solution is not available (i.e., self.solution is None).
Returns
- bool: True if the solution is valid, False otherwise.
Notes
get_solution()
must be called before this method.- The solution is considered valid if the flow from walks is equal
(up to
TOLERANCE * num_edge_walks_on_edges[(u, v)]
) to the flow value of the graph edges.