70 template <
typename Node_Info = Empty_Class>
91 template <
typename Arc_Info = Empty_Class,
typename F_Type =
double>
144 template <
class NodeT = Net_Cost_Node<Empty_Class>,
145 class ArcT = Net_Cost_Arc<Empty_Class,
double>>
183 zip(this->
arcs(), net.
arcs()).for_each([](
const auto & p)
186 auto asrc = p.second;
257 template <
typename...
Args>
295 Arc *a = it.get_curr();
296 total += a->flow_cost();
312 Arc *a = it.get_curr();
331 Arc *a = it.get_curr();
364 return a->cap > a->flow;
402 a->cap = std::numeric_limits<Distance_Type>::max();
417 template <
typename Ftype>
436 template <
typename Ftype>
458 template <
class Res_Net>
459 typename Res_Net::Arc *
461 typename Res_Net::Node *src,
462 typename Res_Net::Node *tgt,
463 const typename Res_Net::Flow_Type cap,
464 const typename Res_Net::Flow_Type flow,
465 const typename Res_Net::Flow_Type cost)
469 auto arc =
residual_net.insert_arc(src, tgt, cap, cost);
472 arc->is_residual =
false;
476 rarc->is_residual =
true;
478 rarc->flow = arc->cap - arc->flow;
480 assert(arc->cap == cap
and arc->flow == flow
and arc->cost == cost);
509 <<
"Network is not single source and single sink";
516 auto p = it.get_curr();
517 auto q =
rnet.insert_node();
524 auto ga = it.get_curr();
531 ga->cap,
ga->flow,
ga->cost);
550 template <
class Res_Net>
553 return net.all_arcs([](
typename Res_Net::Arc *a)
555 return a->img !=
nullptr and a->img->img == a;
572 template <
class Res_Net>
576 <<
"Path is empty or not a cycle";
578 using Ftype =
typename Res_Net::Flow_Type;
581 Ftype slack = std::numeric_limits<Ftype>::max();
584 assert(a->cap - a->flow > 0);
593 assert(a->cap == img->cap);
613 arcs.for_each([](std::pair<void *, void *> p)
667 std::tuple<size_t, double>
690 auto [
cycle, iterations] =
745 const size_t step = 10)
774 void operator ()(
const Net &,
typename Net::Node *p, std::ostream &
o)
776 o <<
"label = \"(" << p->get_info() <<
"," <<
NODE_COUNTER(p) <<
")\"";
782 void operator ()(
const Net &,
typename Net::Arc *a, std::ostream &
o)
784 o <<
"label = \"" << a->flow <<
"/" << a->cap <<
"/" << a->cost <<
"\"";
808 net.
nodes().for_each([&i](
typename Rnet::Node *p)
815 void operator ()(
const Rnet &,
typename Rnet::Node *p, std::ostream &
o)
823 void operator ()(
const Rnet &,
typename Rnet::Arc *a, std::ostream &
o)
825 o <<
"label = \"" << a->flow <<
"/" << a->cap <<
"/" << a->cost <<
"\"";
873 if (
auto a = it.get_curr(); a->flow == 0)
875 else if (a->flow == a->cap)
881 return std::make_tuple(std::move(empty), std::move(full), std::move(
partial));
897 if (
auto a = it.get_curr(); a->flow > 0
and a->flow < a->cap)
912 template <
typename Ftype>
953 template <
typename Ftype>
1039 template <
class Net>
1066 if constexpr (std::is_floating_point_v<Flow_Type>)
1067 return std::numeric_limits<Flow_Type>::epsilon() * 1000;
1099 if constexpr (std::is_floating_point_v<Flow_Type>)
1100 return std::abs(x) <=
eps();
1111 auto src =
static_cast<Node *
>(a->src_node);
1112 auto tgt =
static_cast<Node *
>(a->tgt_node);
1128 auto p = it.get_curr();
1138 auto a = it.get_curr();
1150 return a->flow >
eps()
and a->flow < a->cap -
eps();
1168 auto p = it.get_curr();
1170 ni.parent =
nullptr;
1171 ni.parent_arc =
nullptr;
1194 const auto &pi =
ninfo(p);
1198 oi.depth = pi.depth + 1;
1200 auto src =
static_cast<Node *
>(a->src_node);
1203 oi.arc_from_parent =
true;
1204 oi.potential = pi.potential - a->cost;
1208 oi.arc_from_parent =
false;
1209 oi.potential = pi.potential + a->cost;
1221 auto p = queue.
get();
1233 auto a = it.get_curr();
1241 else if (a->flow >
eps())
1264 auto a = it.get_curr();
1268 if (a->flow <=
eps())
1270 else if (a->flow >= a->cap -
eps())
1306 auto a = it.get_curr();
1338 if (
best !=
nullptr)
1361 while (p !=
nullptr)
1645 while (p !=
nullptr)
1694 for (
auto it = path.
get_it(); it.has_curr(); )
1696 Node *curr = it.get_curr();
1699 if (
not it.has_curr())
1743 if (
parent(child) != curr)
1750 if (
ci.arc_from_parent)
1810 return std::abs(a->flow - a->cap) <
eps();
1820 return a->cap - a->flow;
1846 <<
"Network is not single source and single sink";
1849 auto total_start = std::chrono::high_resolution_clock::now();
1858 auto phase1_start = std::chrono::high_resolution_clock::now();
1860 auto phase1_end = std::chrono::high_resolution_clock::now();
1867 auto phase2_start = std::chrono::high_resolution_clock::now();
1888 if (std::abs(delta) <
eps())
1906 auto phase2_end = std::chrono::high_resolution_clock::now();
1911 auto total_end = std::chrono::high_resolution_clock::now();
1934 std::cout <<
"=== Network Simplex Statistics ===\n"
1972 auto a = it.get_curr();
2020 if (a->flow <=
eps())
2022 else if (a->flow >= a->cap -
eps())
2046 auto a = it.get_curr();
2063 auto a = it.get_curr();
2081 auto a = it.get_curr();
2086 if (std::abs(
rc) >
eps() * 100)
2100 auto p = it.get_curr();
2117 std::cout <<
"\n=== Network Simplex Diagnostics ===\n";
2131 std::cout <<
"Arcs: Tree=" << tree_arcs <<
" Lower=" <<
lower_arcs
2133 std::cout <<
"Expected tree arcs: " << (
net.
vsize() - 1) <<
"\n";
2137 std::cout <<
"Tree arcs rc=0: " << (
tree_rc_ok ?
"YES" :
"NO") <<
"\n";
2143 auto a = it.get_curr();
2153 std::cout <<
" VIOLATION: Lower arc with rc=" <<
rc
2154 <<
" flow=" << a->flow <<
"/" << a->cap <<
"\n";
2163 std::cout <<
" VIOLATION: Upper arc with rc=" <<
rc
2164 <<
" flow=" << a->flow <<
"/" << a->cap <<
"\n";
2169 std::cout <<
"Optimality violations: " <<
violations <<
"\n";
2170 std::cout <<
"==================================\n";
2212 template <
class Net,
2230 template <
class 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.
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.
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
Insert a new item by copy.
T & append(const T &item)
Append a new item by copy.
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).
constexpr bool is_empty() const noexcept
Return true if list is empty.
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.
Graph visualization and output generation utilities.
DynArray< Graph::Arc * > arcs
#define NODE_COUNTER(p)
Get the counter of a node.
#define NODE_COOKIE(p)
Return the node cookie
Container< T > arcs_map(GT &g, std::function< T(typename GT::Arc *)> transformation, SA sa=SA())
Map the filtered arcs of a graph to a transformed type.
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.
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
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.
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) and bridges.
Dynamic key-value map based on balanced binary search trees.
Path finding algorithms in graphs.
Network flow graph structures.