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();
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] =
693 if (
cycle.is_empty())
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)
1397 auto u =
static_cast<Node *
>(entering->src_node);
1398 auto v =
static_cast<Node *
>(entering->tgt_node);
1464 delta = entering->cap - entering->flow;
1466 delta = entering->flow;
1551 entering->flow += delta;
1553 entering->flow -= delta;
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();
1877 if (entering ==
nullptr)
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)
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.
#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.
and
Check uniqueness with explicit hash + equality functors.
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.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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.