72 template <
typename Node_Info = Empty_Class>
93 template <
typename Arc_Info = Empty_Class,
typename F_Type =
double>
146 template <
class NodeT = Net_Cost_Node<Empty_Class>,
147 class ArcT = Net_Cost_Arc<Empty_Class,
double>>
185 zip(this->
arcs(), net.
arcs()).for_each([](
const auto & p)
188 auto asrc = p.second;
259 template <
typename...
Args>
297 Arc *a = it.get_curr();
298 total += a->flow_cost();
314 Arc *a = it.get_curr();
333 Arc *a = it.get_curr();
366 return a->cap > a->flow;
404 a->cap = std::numeric_limits<Distance_Type>::max();
419 template <
typename Ftype>
438 template <
typename Ftype>
460 template <
class Res_Net>
461 typename Res_Net::Arc *
463 typename Res_Net::Node *src,
464 typename Res_Net::Node *tgt,
465 const typename Res_Net::Flow_Type cap,
466 const typename Res_Net::Flow_Type flow,
467 const typename Res_Net::Flow_Type cost)
471 auto arc =
residual_net.insert_arc(src, tgt, cap, cost);
474 arc->is_residual =
false;
478 rarc->is_residual =
true;
480 rarc->flow = arc->cap - arc->flow;
482 assert(arc->cap == cap
and arc->flow == flow
and arc->cost == cost);
511 <<
"Network is not single source and single sink";
518 auto p = it.get_curr();
526 auto ga = it.get_curr();
533 ga->cap,
ga->flow,
ga->cost);
552 template <
class Res_Net>
555 return net.all_arcs([](
typename Res_Net::Arc *a)
557 return a->img !=
nullptr and a->img->img == a;
574 template <
class Res_Net>
578 <<
"Path is empty or not a cycle";
580 using Ftype =
typename Res_Net::Flow_Type;
583 Ftype slack = std::numeric_limits<Ftype>::max();
586 assert(a->cap - a->flow > 0);
595 assert(a->cap == img->cap);
615 arcs.for_each([](std::pair<void *, void *> p)
667 template <FlowNetwork
Net,
669 std::tuple<size_t, double>
692 auto [
cycle, iterations] =
695 if (
cycle.is_empty())
734 template <FlowNetwork
Net,
747 const size_t step = 10)
776 void operator ()(
const Net &,
typename Net::Node *p, std::ostream &
o)
778 o <<
"label = \"(" << p->get_info() <<
"," <<
NODE_COUNTER(p) <<
")\"";
784 void operator ()(
const Net &,
typename Net::Arc *a, std::ostream &
o)
786 o <<
"label = \"" << a->flow <<
"/" << a->cap <<
"/" << a->cost <<
"\"";
810 net.
nodes().for_each([&i](
typename Rnet::Node *p)
817 void operator ()(
const Rnet &,
typename Rnet::Node *p, std::ostream &
o)
825 void operator ()(
const Rnet &,
typename Rnet::Arc *a, std::ostream &
o)
827 o <<
"label = \"" << a->flow <<
"/" << a->cap <<
"/" << a->cost <<
"\"";
875 if (
auto a = it.get_curr(); a->flow == 0)
877 else if (a->flow == a->cap)
883 return std::make_tuple(std::move(empty), std::move(full), std::move(partial));
899 if (
auto a = it.get_curr(); a->flow > 0
and a->flow < a->cap)
914 template <
typename Ftype>
955 template <
typename Ftype>
1041 template <FlowNetwork Net>
1068 if constexpr (std::is_floating_point_v<Flow_Type>)
1069 return std::numeric_limits<Flow_Type>::epsilon() * 1000;
1101 if constexpr (std::is_floating_point_v<Flow_Type>)
1102 return std::abs(x) <=
eps();
1113 auto src =
static_cast<Node *
>(a->src_node);
1114 auto tgt =
static_cast<Node *
>(a->tgt_node);
1130 auto p = it.get_curr();
1140 auto a = it.get_curr();
1152 return a->flow >
eps()
and a->flow < a->cap -
eps();
1170 auto p = it.get_curr();
1172 ni.parent =
nullptr;
1173 ni.parent_arc =
nullptr;
1196 const auto &pi =
ninfo(p);
1200 oi.depth = pi.depth + 1;
1202 auto src =
static_cast<Node *
>(a->src_node);
1205 oi.arc_from_parent =
true;
1206 oi.potential = pi.potential - a->cost;
1210 oi.arc_from_parent =
false;
1211 oi.potential = pi.potential + a->cost;
1223 auto p = queue.
get();
1235 auto a = it.get_curr();
1243 else if (a->flow >
eps())
1266 auto a = it.get_curr();
1270 if (a->flow <=
eps())
1272 else if (a->flow >= a->cap -
eps())
1308 auto a = it.get_curr();
1340 if (
best !=
nullptr)
1363 while (p !=
nullptr)
1399 auto u =
static_cast<Node *
>(entering->src_node);
1400 auto v =
static_cast<Node *
>(entering->tgt_node);
1466 delta = entering->cap - entering->flow;
1468 delta = entering->flow;
1553 entering->flow += delta;
1555 entering->flow -= delta;
1647 while (p !=
nullptr)
1696 for (
auto it = path.
get_it(); it.has_curr(); )
1698 Node *curr = it.get_curr();
1701 if (
not it.has_curr())
1745 if (
parent(child) != curr)
1752 if (
ci.arc_from_parent)
1812 return std::abs(a->flow - a->cap) <
eps();
1822 return a->cap - a->flow;
1848 <<
"Network is not single source and single sink";
1851 auto total_start = std::chrono::high_resolution_clock::now();
1860 auto phase1_start = std::chrono::high_resolution_clock::now();
1862 auto phase1_end = std::chrono::high_resolution_clock::now();
1869 auto phase2_start = std::chrono::high_resolution_clock::now();
1879 if (entering ==
nullptr)
1890 if (std::abs(delta) <
eps())
1908 auto phase2_end = std::chrono::high_resolution_clock::now();
1913 auto total_end = std::chrono::high_resolution_clock::now();
1936 std::cout <<
"=== Network Simplex Statistics ===\n"
1974 auto a = it.get_curr();
2022 if (a->flow <=
eps())
2024 else if (a->flow >= a->cap -
eps())
2048 auto a = it.get_curr();
2065 auto a = it.get_curr();
2083 auto a = it.get_curr();
2088 if (std::abs(
rc) >
eps() * 100)
2102 auto p = it.get_curr();
2119 std::cout <<
"\n=== Network Simplex Diagnostics ===\n";
2133 std::cout <<
"Arcs: Tree=" << tree_arcs <<
" Lower=" <<
lower_arcs
2135 std::cout <<
"Expected tree arcs: " << (
net.
vsize() - 1) <<
"\n";
2139 std::cout <<
"Tree arcs rc=0: " << (
tree_rc_ok ?
"YES" :
"NO") <<
"\n";
2145 auto a = it.get_curr();
2155 std::cout <<
" VIOLATION: Lower arc with rc=" <<
rc
2156 <<
" flow=" << a->flow <<
"/" << a->cap <<
"\n";
2165 std::cout <<
" VIOLATION: Upper arc with rc=" <<
rc
2166 <<
" flow=" << a->flow <<
"/" << a->cap <<
"\n";
2171 std::cout <<
"Optimality violations: " <<
violations <<
"\n";
2172 std::cout <<
"==================================\n";
2214 template <FlowNetwork
Net,
2232 template <FlowNetwork
Net,
Bellman-Ford algorithm for single-source shortest paths.
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.
size_t size_t int32_t * out
Bellman-Ford algorithm for shortest paths with negative weights.
bool has_curr() const noexcept
Return true the iterator has an current arc.
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.
bool is_empty() const noexcept
Return true if this is empty.
Doubly-linked list (defined in tpl_dynList.H).
T & insert(const T &item)
T & append(const T &item)
Generic key-value map implemented on top of a binary search tree.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair.
Data & find(const Key &key)
Find the value associated with key.
void empty()
remove all elements from the set
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Network Simplex algorithm for minimum cost flow.
Flow_Type residual_lower(Arc *a) const
Get residual lower (room to decrease flow).
const Arc_Info & ainfo(Arc *a) const
Get arc info const reference.
Arc * parent_arc(Node *p) const
Get parent arc.
bool support_lower_bounds
Arc * find_entering_arc()
Find entering arc using most negative reduced cost.
size_t get_num_pivots() const
Return number of pivots performed in last run.
bool augment_and_find_leaving(Arc *entering, Flow_Type &delta, Arc *&leaving, bool &leaving_goes_lower)
Augment flow around the cycle and find leaving arc.
void pivot_tree(Arc *entering, Arc *leaving, bool leaving_goes_lower)
Update tree structure after pivot.
size_t run(Flow_Type unused=0)
Execute Network Simplex algorithm.
DynArray< Arc_Info > arc_info
Network_Simplex(Net &network)
Construct Network Simplex solver.
typename Net::Flow_Type Flow_Type
void set_lower_bound(Arc *a, Flow_Type lower_bound)
Set lower bound for an arc.
const Node_Info & ninfo(Node *p) const
Get node info const reference.
bool verify_tree_integrity() const
Verify tree integrity - all parent_arcs should be Tree arcs.
DynMapTree< Arc *, size_t > arc_to_idx
void build_spanning_tree()
Build initial spanning tree from source.
void init_structures()
Initialize data structures.
static Flow_Type eps()
Epsilon for floating-point comparisons.
Node * find_lca(Node *u, Node *v)
Find the lowest common ancestor of two nodes.
Flow_Type residual_capacity(Arc *a) const
Get residual capacity (room to increase flow).
DynArray< Node_Info > node_info
bool is_partial_flow(Arc *a) const
Check if arc has partial flow (strictly between bounds).
Flow_Type reduced_cost(Arc *a) const
Compute reduced cost of an arc.
size_t count_non_tree_partial_arcs() const
Count arcs with partial flow not in tree.
static constexpr Flow_Type Inf
Flow_Type get_lower_bound(Arc *a) const
Get lower bound for an arc.
bool is_at_lower_bound(Arc *a) const
Check if arc flow is at lower bound.
long depth(Node *p) const
Get depth.
NetworkSimplexStats stats
DynMapTree< Node *, size_t > node_to_idx
void print_stats() const
Print execution statistics to stdout.
bool is_valid_basic_solution() const
Check if current solution is a valid basic feasible solution.
bool is_at_upper_bound(Arc *a) const
Check if arc flow is at upper bound (capacity).
size_t force_partial_arcs_into_tree()
Phase I: Force all partial-flow arcs into the spanning tree.
void print_diagnostics() const
Print diagnostic information about current state.
Node * parent(Node *p) const
Get parent node.
Arc_Info & ainfo(Arc *a)
Get arc info reference.
Node_Info & ninfo(Node *p)
Get node info reference.
const NetworkSimplexStats & get_stats() const noexcept
Return execution statistics from last run.
Flow_Type potential(Node *p) const
Get potential.
bool verify_tree_reduced_costs() const
Verify that tree arcs have zero reduced cost.
bool is_zero(Flow_Type x) const
Check if value is effectively zero.
Filtered iterator for outcoming arcs of a node.
bool is_cycle() const
Return true if this is a cycle; throws if path is empty.
bool is_empty() const noexcept
Return true if the path is empty.
void for_each_arc(Operation op=Operation()) const
Execute an operation on each arc of path.
Container< Arc * > arcs() const
Return a container with all the arcs of the graph.
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Return the adjacent node to node through arc.
constexpr size_t vsize() const noexcept
size_t esize() const noexcept
Return the total of arcs of graph.
Container< Node * > nodes() const
Return a container with all the nodes of the graph.
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
QuadTree - Hierarchical spatial index for 2D points.
Graph visualization and output generation utilities.
DynArray< Graph::Arc * > arcs
#define NODE_COUNTER(p)
Get the counter of a node.
Container< T > arcs_map(GT &g, Op transformation, SA sa=SA())
Map the filtered arcs of a graph to a transformed type.
#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().
Net_Graph< Net_Node< string >, Net_Arc< Empty_Class, FlowType > > Net
Main namespace for Aleph-w library functions.
Itor lower_bound(Itor beg, Itor end, const T &value)
Find lower bound in a sorted range.
DynList< typename Net::Arc * > get_partial_arcs(const Net &net)
Get arcs with partial flow (0 < flow < cap).
Residual_Net< typenameNet::Flow_Type >::Node * build_residual_net(const Net &net, Residual_Net< typename Net::Flow_Type > &rnet, DynMapTree< void *, void * > &arcs)
Build a residual network from a flow network.
void cancel_cycle(const Res_Net &, const Path< Res_Net > &path)
Cancel a negative cycle by augmenting flow.
DynList< std::pair< typename Container1::Item_Type, typename Container2::Item_Type > > zip(const Container1 &a, const Container2 &b)
Zip two containers into a list of pairs.
and
Check uniqueness with explicit hash + equality functors.
void residual_to_net(const DynMapTree< void *, void * > &arcs)
Transfer flow values from residual network back to original.
std::tuple< size_t, double > max_flow_min_cost_by_cycle_canceling(Net &net, double it_factor=0.4, size_t step=10)
Compute maximum flow at minimum cost using cycle canceling.
void create_residual_arc(const Net &net, PP_Res_Net< Net > &rnet, typename Net::Arc *a)
Create residual arcs for a in the residual network.
size_t max_flow_min_cost_by_network_simplex(Net &net)
Compute maximum flow at minimum cost using Network Simplex.
Simplex_Arc_State
Arc state in Network Simplex.
@ Upper
Non-basic arc at upper bound (flow = cap).
@ Tree
Basic arc (in spanning tree).
@ Lower
Non-basic arc at lower bound (flow = 0).
std::tuple< DynList< typename Net::Arc * >, DynList< typename Net::Arc * >, DynList< typename Net::Arc * > > Feasible_Tree
Feasible spanning tree classification.
void print_net_cost(const Net &net, std::ostream &out)
Output a flow network to Graphviz format.
bool check_residual_net(const Res_Net &net)
Verify residual network consistency.
void next()
Advance all underlying iterators (bounds-checked).
void print_residual_net(const Residual_Net< typename Net::Flow_Type > &net, std::ostream &out)
Output a residual network to Graphviz format.
Feasible_Tree< Net > build_feasible_spanning_tree(const Net &net)
Build feasible spanning tree classification.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Filtered iterator on all the arcs of a graph.
Iterator over arcs of a graph.
Functor wrapper for ford_fulkerson_maximum_flow().
Functor wrapper for maximum flow minimum cost algorithm.
std::tuple< size_t, double > operator()(Net &net, const double it_factor=0.4, const size_t step=10)
Execute the algorithm.
Functor wrapper for Network Simplex algorithm.
size_t operator()(Net &net)
Execute the algorithm.
Arc of a flow network implemented with adjacency lists.
Net_Arc & operator=(const Net_Arc &arc)
Copy assignment.
Flow_Type flow
Flow value.
Arc type for maximum flow minimum cost networks.
Flow_Type cost
Cost per unit of flow (negative for residual arcs).
Flow_Type flow_cost() const noexcept
Return the cost of the current flow through this arc.
Net_Cost_Arc(const Net_Cost_Arc &a)
Copy constructor.
Net_Cost_Arc & operator=(const Net_Cost_Arc &a)
Copy assignment operator.
Net_Cost_Arc()=default
Default constructor.
F_Type Flow_Type
Type representing flow, capacity, and cost values.
Capacitated flow network with costs associated to arcs.
typename Arc::Arc_Type Arc_Type
Type of attribute stored in an arc.
Flow_Type flow_cost() const
Compute the total cost of flow circulating through the network.
Flow_Type get_cost(Arc *a) const noexcept
Return the cost of an arc (const version).
typename Node::Node_Type Node_Type
Type of attribute stored in a node.
auto in_pars(Node *p)
Compute incoming flow parameters for a node.
Net_Cost_Graph & operator=(const Net_Cost_Graph &net)
Copy assignment operator (uses copy-and-swap idiom).
typename Arc::Flow_Type Flow_Type
Type representing capacity, flow, and cost values.
Net_Cost_Graph(Net_Cost_Graph &&)=default
Move constructor.
auto out_pars(Node *p)
Compute outgoing flow parameters for a node.
Net_Cost_Graph()=default
Default constructor.
virtual Arc * insert_arc(Node *src_node, Node *tgt_node)
Insert arc (internal use only).
Net_Cost_Graph(const Net_Cost_Graph &net)
Copy constructor.
Flow_Type & get_cost(Arc *a) noexcept
Return a modifiable reference to the cost of an arc.
Arc * emplace_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap, const Flow_Type &__cost, Args &&... args)
Create and insert an arc with arc info using perfect forwarding.
virtual Arc * insert_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap, const Flow_Type &__cost)
Create and insert an arc in a flow network with costs.
static Flow_Type arc_flow_cost(Arc *a) noexcept
Compute the cost of the flow through an arc.
Flow network implemented with adjacency lists.
Node * insert_node(const Node_Type &node_info)
Insert a new node by copying node_info.
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.
Arc * insert_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap, const Flow_Type &flow, const typename Arc::Arc_Type &arc_info=Arc_Type())
Insert a capacitated arc with an initial flow.
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.
void swap(Net_Graph &other) noexcept
Swap contents with another network. O(1) operation.
Execution statistics for Network Simplex algorithm.
double phase1_time_ms
Phase I elapsed time in milliseconds.
size_t tree_arcs
Number of arcs in spanning tree.
size_t degenerate_pivots
Pivots with zero flow change.
size_t total_pivots
Total pivot operations.
size_t initial_partial_arcs
Arcs with partial flow before Phase I.
size_t phase1_pivots
Pivots in Phase I (feasibility)
size_t phase2_pivots
Pivots in Phase II (optimization)
size_t forced_into_tree
Arcs forced into tree in Phase I.
double total_time_ms
Total elapsed time in milliseconds.
double phase2_time_ms
Phase II elapsed time in milliseconds.
Filtered iterator of adjacent arcs of a node.
Cost distance functor for Bellman-Ford on residual networks.
static void set_zero(typename Net::Arc *a) noexcept
Reset arc to zero state.
typename Net::Flow_Type Distance_Type
Residual arc type with mirror pointer.
Res_Arc * img
Pointer to the mirror arc in the opposite direction.
bool is_residual
True if this is a residual (backward) arc.
Arc filter for residual networks.
Res_Filt() noexcept=default
Default constructor.
Res_Filt(typename Net::Node *) noexcept
Constructor (node parameter ignored).
Arc information for Network Simplex algorithm.
bool skip
Skip this arc temporarily (failed pivot, will retry later).
Simplex_Arc_State state
Arc state (Lower, Upper, or Tree).
Ftype lower_bound
Lower bound on flow (default 0).
Node information for Network Simplex algorithm.
void * parent
Parent node in the spanning tree (nullptr for root).
bool arc_from_parent
True if parent_arc is oriented from parent towards this node.
long depth
Depth in the spanning tree (root has depth 0).
long mark
Mark used for LCA computation.
void * parent_arc
Arc connecting this node to its parent.
Ftype potential
Node potential (dual variable pi).
Functor class for generating Graphviz DOT specifications.
Articulation points (cut nodes), bridges, and biconnected components.
Dynamic key-value map based on balanced binary search trees.
Path finding algorithms in graphs.
Network flow graph structures.