111 template <
typename Flow_Type>
143 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
165 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
185 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
237 auto p = it.get_curr();
239 "NODE_COOKIE not initialized for Dinic's algorithm. "
240 "Call dinic_maximum_flow() instead of build_level_graph() directly, "
241 "or initialize Dinic_Node_Info for all nodes before calling.");
260 auto arc = it.get_curr();
270 residual = arc->cap - arc->flow;
272 residual = arc->flow;
310 const size_t n = net.
vsize();
325 Node *curr = stack[depth - 1];
332 for (
size_t i = 0; i + 1 < depth; ++i)
345 for (
size_t i = 0; i + 1 < depth; ++i)
368 Arc *arc =
static_cast<Arc *
>(curr->arc_array[
ca]);
388 ? (arc->cap - arc->flow)
458 template <FlowNetwork Net>
465 <<
"Network must have single source and single sink";
495 template <FlowNetwork Net>
558 template <FlowNetwork Net>
566 <<
"Network must have single source and single sink";
574 max_cap = std::max(max_cap, it.get_curr()->cap);
581 while (delta <= max_cap / 2)
603 parent[source] =
nullptr;
613 Arc *arc = it.get_curr();
623 residual = arc->cap - arc->flow;
625 residual = arc->flow;
630 parent_arc[
next] = arc;
637 if (parent.
has(sink))
642 for (
Node *n = sink; n != source; n = parent[n])
644 Arc *arc = parent_arc[n];
646 (arc->cap - arc->flow) :
651 for (
Node *n = sink; n != source; n = parent[n])
653 Arc *arc = parent_arc[n];
684 template <FlowNetwork Net>
796 for (
auto it =
paths.get_it(); it.has_curr(); it.next_ne())
797 sum += it.get_curr().flow;
861 template <FlowNetwork Net>
869 <<
"Network must have single source and single sink";
877 Arc *arc = it.get_curr();
891 Arc *arc = it.get_curr();
922 Arc *arc = it.get_curr();
939 const size_t cycle_start = visited[
next_node];
948 for (
size_t i = 0; i < cycle_start; ++i)
969 for (
auto it =
cycle.arcs.get_it(); it.has_curr(); it.next_ne())
996 for (
auto it = path.arcs.get_it(); it.has_curr(); it.next_ne())
998 result.
paths.append(std::move(path));
1006 Node *start = it.get_curr();
1015 Arc *arc =
ait.get_curr();
1046 const size_t cycle_start = visited[curr];
1047 cycle.flow = std::numeric_limits<Flow_Type>::max();
1052 for (
size_t i = 0; i < cycle_start; ++i)
1059 while (
arc_it.has_curr())
1068 cycle.nodes.append(curr);
1080 Arc *arc =
ait.get_curr();
1099 for (
auto cit =
cycle.arcs.get_it();
cit.has_curr();
cit.next_ne())
1101 result.cycles.append(std::move(
cycle));
1114 template <FlowNetwork Net>
1146 template <
typename Flow_Type>
1154 template <
class Net>
1162 template <
class Net>
1184 template <FlowNetwork Net>
1192 <<
"Network must have single source and single sink";
1197 const long n =
static_cast<long>(
n_nodes);
1226 auto arc =
ait.get_curr();
1254 arc->flow = arc->cap;
1260 const size_t bucket_count =
static_cast<size_t>(2 * n + 1);
1267 auto p = it.get_curr();
1268 if (p != source
and p != sink
and
1272 buckets[
h].append(p);
1296 Arc *arc = it.get_curr();
1302 residual = arc->cap - arc->flow;
1304 residual = arc->flow;
1318 (v != source
and v != sink
and
1356 template <FlowNetwork Net>
1387 template <
typename Flow_Type>
1409 std::ostringstream
oss;
1410 oss <<
"=== Flow Statistics ===\n"
1416 <<
"Utilization: " << std::fixed << std::setprecision(2)
1448 template <
class Net>
1457 auto arc = it.get_curr();
1460 if (arc->flow == arc->cap)
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
C++20 concepts for the protocol shared by graph algorithms.
WeightedDigraph::Node Node
bool has_curr() const noexcept
Check if there is a current valid item.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
RAII guard that saves and restores graph cookies.
Dynamic queue of elements of generic type T based on single linked list.
T & put(const T &data)
The type of element.
T get()
Remove the oldest item of the queue.
T & front()
Return a modifiable reference to the oldest item in the queue.
bool is_empty() const noexcept
Return true if this is empty.
Doubly-linked list (defined in tpl_dynList.H).
T & append(const T &item)
Generic key-value map implemented on top of a binary search tree.
Pair * append(const Key &key, const Data &data)
bool has(const Key &key) const noexcept
bool contains(const Key &key) const noexcept
const size_t & size() const
Returns the cardinality of the set.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
constexpr bool is_empty() const noexcept
size_t size() const noexcept
Count the number of elements of the list.
Filtered iterator on the nodes of a graph.
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
constexpr size_t vsize() const noexcept
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
RAII guards for graph node/arc cookies.
#define NODE_COOKIE(p)
Return the node cookie
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Main namespace for Aleph-w library functions.
Net::Flow_Type remaining_flow(typename Net::Node *src, typename Net::Arc *a) noexcept
Return the remaining flow of a as seen from src.
FlowStatistics< typename Net::Flow_Type > compute_flow_statistics(const Net &net)
Compute statistics about the current flow in a network.
bool is_dinic_cookie_valid(typename Net::Node *p) noexcept
Check if a node's cookie is properly initialized for Dinic's algorithm.
Net::Flow_Type dinic_maximum_flow(Net &net)
Compute maximum flow using Dinic's algorithm.
long & hlpp_height(typename Net::Node *p) noexcept
Access the height label stored in the node's cookie.
bool build_level_graph(Net &net, typename Net::Node *source, typename Net::Node *sink)
Build level graph using BFS from source.
long & dinic_level(typename Net::Node *p) noexcept
Access the node level in Dinic's algorithm.
FlowDecomposition< Net > decompose_flow(const Net &net)
Decompose network flow into paths and cycles.
and
Check uniqueness with explicit hash + equality functors.
Net::Flow_Type capacity_scaling_maximum_flow(Net &net)
Compute maximum flow using capacity scaling.
bool & dinic_blocked(typename Net::Node *p) noexcept
Check if a node is blocked in Dinic's algorithm.
size_t & dinic_current_arc(typename Net::Node *p) noexcept
Access the current arc index in Dinic's algorithm.
Net::Flow_Type hlpp_maximum_flow(Net &net)
Compute maximum flow using Highest-Label Preflow-Push.
Net::Flow_Type & hlpp_excess(typename Net::Node *p) noexcept
Access the excess flow stored in the node's cookie.
void next()
Advance all underlying iterators (bounds-checked).
Net::Flow_Type dinic_blocking_flow(Net &net, typename Net::Node *source, typename Net::Node *sink)
Find all blocking flows using iterative DFS with current-arc optimization.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Filtered iterator on all the arcs of a graph.
Functor wrapper for capacity scaling.
Net::Flow_Type operator()(Net &net) const
Invoke capacity scaling maximum flow algorithm on the given network.
Functor wrapper for flow decomposition.
FlowDecomposition< Net > operator()(const Net &net) const
Invoke flow decomposition on the given network.
Functor wrapper for Dinic's algorithm.
Net::Flow_Type operator()(Net &net) const
Invoke Dinic's maximum flow algorithm on the given network.
Level information for Dinic's algorithm.
size_t current_arc
Current arc index for current-arc optimization.
bool blocked
Whether the node is blocked in the current phase.
long level
BFS level from source (-1 = unreachable)
Represents a flow cycle in the network.
typename Net::Flow_Type Flow_Type
Flow_Type flow
Flow on this cycle.
DynList< Node * > nodes
Nodes in the cycle.
DynList< Arc * > arcs
Arcs in the cycle.
Result of flow decomposition.
DynList< FlowCycle< Net > > cycles
Cycles (if any)
typename Net::Flow_Type Flow_Type
Flow_Type total_flow() const noexcept
Total flow (sum of path flows).
size_t num_paths() const noexcept
Number of paths.
size_t num_cycles() const noexcept
Number of cycles.
DynList< FlowPath< Net > > paths
Source-to-sink paths.
Represents a flow path from source to sink.
DynList< Node * > nodes
Nodes in the path.
bool is_empty() const noexcept
Check if a path is empty.
Flow_Type flow
Flow on this path.
typename Net::Flow_Type Flow_Type
size_t length() const noexcept
Get path length (number of arcs).
DynList< Arc * > arcs
Arcs in the path (source to sink order)
Statistics about a network flow.
std::string to_string() const
Format statistics as a string.
size_t num_saturated_arcs
Arcs with flow = capacity.
size_t num_empty_arcs
Arcs with flow = 0.
Flow_Type total_capacity
Sum of all capacities.
Flow_Type total_flow
Total flow value.
void print() const
Print statistics to standard output.
size_t num_partial_arcs
Arcs with 0 < flow < capacity.
double utilization
flow / capacity ratio
Functor wrapper for HLPP.
Net::Flow_Type operator()(Net &net) const
Invoke the Highest-Label Preflow-Push algorithm on the given network.
Node info for HLPP algorithm.
Flow network implemented with adjacency lists.
constexpr bool is_single_source() const noexcept
Return true if the network has a single source.
Node * get_source() const
Return an arbitrary source node.
Node * get_sink() const
Return an arbitrary sink node.
Flow_Type flow_value() const
Return the total flow value of the network.
typename Arc::Flow_Type Flow_Type
Capacity/flow numeric type.
constexpr bool is_single_sink() const noexcept
Return true if the network has a single sink.
Dynamic array container with automatic resizing.
Dynamic doubly linked list implementation.
Dynamic queue implementation based on linked lists.
Network flow graph structures.