109 template <
typename Flow_Type>
141 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
163 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
183 "NODE_COOKIE not initialized; call dinic_maximum_flow() instead");
235 auto p = it.get_curr();
237 "NODE_COOKIE not initialized for Dinic's algorithm. "
238 "Call dinic_maximum_flow() instead of build_level_graph() directly, "
239 "or initialize Dinic_Node_Info for all nodes before calling.");
258 auto arc = it.get_curr();
268 residual = arc->cap - arc->flow;
270 residual = arc->flow;
308 const size_t n = net.
vsize();
323 Node *curr = stack[depth - 1];
330 for (
size_t i = 0; i + 1 < depth; ++i)
343 for (
size_t i = 0; i + 1 < depth; ++i)
366 Arc *arc =
static_cast<Arc *
>(curr->arc_array[
ca]);
386 ? (arc->cap - arc->flow)
463 <<
"Network must have single source and single sink";
564 <<
"Network must have single source and single sink";
572 max_cap = std::max(max_cap, it.get_curr()->cap);
579 while (delta <= max_cap / 2)
601 parent[source] =
nullptr;
611 Arc *arc = it.get_curr();
621 residual = arc->cap - arc->flow;
623 residual = arc->flow;
628 parent_arc[
next] = arc;
635 if (parent.
has(sink))
640 for (
Node *n = sink; n != source; n = parent[n])
642 Arc *arc = parent_arc[n];
644 (arc->cap - arc->flow) :
649 for (
Node *n = sink; n != source; n = parent[n])
651 Arc *arc = parent_arc[n];
794 for (
auto it =
paths.get_it(); it.has_curr(); it.next_ne())
795 sum += it.get_curr().flow;
867 <<
"Network must have single source and single sink";
875 Arc *arc = it.get_curr();
889 Arc *arc = it.get_curr();
920 Arc *arc = it.get_curr();
967 for (
auto it =
cycle.arcs.
get_it(); it.has_curr(); it.next_ne())
994 for (
auto it = path.arcs.get_it(); it.has_curr(); it.next_ne())
996 result.
paths.append(std::move(path));
1004 Node *start = it.get_curr();
1013 Arc *arc =
ait.get_curr();
1045 cycle.flow = std::numeric_limits<Flow_Type>::max();
1057 while (
arc_it.has_curr())
1078 Arc *arc =
ait.get_curr();
1112 template <
class Net>
1144 template <
typename Flow_Type>
1152 template <
class Net>
1160 template <
class Net>
1182 template <
class Net>
1190 <<
"Network must have single source and single sink";
1195 const long n =
static_cast<long>(
n_nodes);
1222 ait.has_curr();
ait.next_ne())
1224 auto arc =
ait.get_curr();
1252 arc->flow = arc->cap;
1258 const size_t bucket_count =
static_cast<size_t>(2 * n + 1);
1265 auto p = it.get_curr();
1266 if (p != source
and p != sink
and
1294 Arc *arc = it.get_curr();
1300 residual = arc->cap - arc->flow;
1302 residual = arc->flow;
1316 (v != source
and v != sink
and
1354 template <
class Net>
1385 template <
typename Flow_Type>
1407 std::ostringstream
oss;
1408 oss <<
"=== Flow Statistics ===\n"
1414 <<
"Utilization: " << std::fixed << std::setprecision(2)
1446 template <
class Net>
1455 auto arc = it.get_curr();
1458 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.
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.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Append a new item by copy.
Generic key-value map implemented on top of a binary search tree.
bool has(const Key &key) const noexcept
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
constexpr bool is_empty() const noexcept
Return true if list is empty.
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
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.
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
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.