94template <
typename Flow_Type>
106 distance = std::numeric_limits<Flow_Type>::max();
167 const Flow_Type INF = std::numeric_limits<Flow_Type>::max();
176 using PQ_Entry = std::pair<Flow_Type, Node *>;
181 while (
not pq.is_empty())
183 auto [dist, u] =
pq.getMin();
191 Arc *arc = it.get_curr();
196 Flow_Type residual = forward ? (arc->cap - arc->flow) : arc->flow;
208 if constexpr (std::is_integral_v<Flow_Type>)
287 const Flow_Type INF = std::numeric_limits<Flow_Type>::max();
289 const size_t n = net.
vsize();
293 if constexpr (std::is_integral_v<Flow_Type>) {
294 if (b > 0
and a > INF - b)
return INF;
300 if constexpr (std::is_integral_v<Flow_Type>) {
313 for (
size_t i = 0; i < n - 1; ++i)
318 auto arc = it.get_curr();
323 if (arc->cap > arc->flow)
360 auto arc = it.get_curr();
364 if (arc->cap > arc->flow)
387template <FlowNetwork Net>
395 <<
"Network must have single source and single sink";
420 <<
"successive_shortest_paths: negative-cost cycle detected in residual graph";
430 for (
Node *v = sink; v != source;)
435 Flow_Type residual = forward ? (arc->cap - arc->flow) : arc->flow;
442 for (
Node *v = sink; v != source;)
467 if (
auto p = it.get_curr();
ssp_info<Net>(p).distance < std::numeric_limits<Flow_Type>::max())
480 if constexpr (std::is_integral_v<Flow_Type>)
492 if (
auto p = it.get_curr();
493 ssp_info<Net>(p).distance >= std::numeric_limits<Flow_Type>::max())
497 return {total_flow, total_cost};
506 std::pair<typename Net::Flow_Type, typename Net::Flow_Type>
operator()(
Net &net)
const
524template <
typename Flow_Type>
533template <
typename Flow_Type>
581template <
class Net,
class GetDemand>
603 if (total_supply != total_demand)
629 net_.remove_node(src_);
642 Node *p = it.get_curr();
643 if (p == super_source
or p == super_sink)
660 result.
feasible = (flow == total_supply);
672template <
typename Cost_Type>
715template <
typename Cost_Type>
723 size_t n =
costs.size();
733 <<
"solve_assignment: costs matrix is not square (" << n <<
" x " <<
row.size() <<
")";
743 for (
size_t i = 0; i < n; ++i)
752 for (
size_t j = 0; j < n; ++j)
760 for (
size_t i = 0; i < n; ++i)
761 for (
size_t j = 0; j < n; ++j)
769 result.
feasible = (
static_cast<size_t>(flow) == n);
774 for (
size_t i = 0; i < n; ++i)
777 auto arc = it.get_curr();
800template <
typename Cost_Type>
842template <
typename Cost_Type>
844 const std::vector<Cost_Type> &
demands,
845 const std::vector<std::vector<Cost_Type>> &
costs)
858 <<
"solve_transportation: costs has " <<
costs.size() <<
" rows but " <<
m <<
" supply points";
859 for (
size_t i = 0; i <
m; ++i)
861 <<
"solve_transportation: costs[" << i <<
"] has " <<
costs[i].
size() <<
" columns but " << n
865 for (
size_t i = 0; i <
m; ++i)
867 <<
"solve_transportation: supplies[" << i <<
"] is negative";
868 for (
size_t j = 0; j < n; ++j)
870 <<
"solve_transportation: demands[" << j <<
"] is negative";
883 if (
m == 0
or n == 0)
885 result.
feasible = (total_supply == total_demand);
890 if (total_supply != total_demand)
904 for (
size_t i = 0; i <
m; ++i)
912 for (
size_t j = 0; j < n; ++j)
920 std::vector<std::vector<Arc *>>
arcs(
m, std::vector<Arc *>(n));
921 for (
size_t i = 0; i <
m; ++i)
922 for (
size_t j = 0; j < n; ++j)
933 result.
feasible = (flow == total_supply);
938 for (
size_t i = 0; i <
m; ++i)
939 for (
size_t j = 0; j < n; ++j)
952template <
typename Flow_Type>
963 std::cout <<
"=== Min-Cost Flow Statistics ===\n"
994 auto arc = it.get_curr();
995 solution[arc] = arc->flow;
1018 auto arc = it.get_curr();
1019 if (solution.
has(arc))
1020 arc->flow = solution[arc];
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument 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.
Dynamic heap of elements of type T ordered by a comparison functor.
T & insert(const T &item)
Insert a copy of item into the heap.
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.
bool has(const Key &key) const noexcept
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
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)
constexpr size_t size() const noexcept
Returns the number of entries in the table.
DynArray< Graph::Arc * > arcs
#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.
size_t size(Node *root) noexcept
bool ssp_init_potentials(Net &net, typename Net::Node *source)
Initialize potentials using Bellman-Ford.
and
Check uniqueness with explicit hash + equality functors.
void restore_flow_solution(Net &net, const DynMapTree< typename Net::Arc *, typename Net::Flow_Type > &solution)
Restore network simplex solution from warm start.
TransportationResult< Cost_Type > solve_transportation(const std::vector< Cost_Type > &supplies, const std::vector< Cost_Type > &demands, const std::vector< std::vector< Cost_Type > > &costs)
Solve the transportation problem using min-cost flow.
SSP_Node_Info< typename Net::Flow_Type > & ssp_info(typename Net::Node *p) noexcept
Access SSP node info.
TransshipmentResult< typename Net::Flow_Type > solve_transshipment(Net &net, GetDemand get_demand)
Solve minimum cost transshipment problem.
std::pair< typename Net::Flow_Type, typename Net::Flow_Type > successive_shortest_paths(Net &net)
Compute minimum cost maximum flow using Successive Shortest Paths.
AssignmentResult< Cost_Type > solve_assignment(const std::vector< std::vector< Cost_Type > > &costs)
Solve the assignment problem using min-cost flow.
bool ssp_shortest_path(Net &net, typename Net::Node *source, typename Net::Node *sink)
Find shortest path using Dijkstra with potentials.
DynMapTree< typename Net::Arc *, typename Net::Flow_Type > save_flow_solution(const Net &net)
Save network simplex solution for warm start.
Net::Flow_Type reduced_cost(const Net &net, typename Net::Arc *arc, bool forward)
Compute reduced cost of an arc.
Filtered iterator on all the arcs of a graph.
Result of assignment problem.
DynList< std::pair< size_t, size_t > > assignments
(worker, task) pairs
Statistics for min-cost flow algorithms.
Arc type for maximum flow minimum cost networks.
Capacitated flow network with costs associated to arcs.
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.
Node * get_sink() const
Return an arbitrary sink node.
typename Arc::Flow_Type Flow_Type
Capacity/flow numeric type.
void remove_node(Node *p) noexcept override
Remove node p and all its arcs from the network.
constexpr bool is_single_sink() const noexcept
Return true if the network has a single sink.
Node info for SSP algorithm.
bool forward
Direction of parent arc.
Flow_Type distance
Shortest path distance.
bool in_tree
Is node in shortest path tree?
Flow_Type potential
Node potential for reduced costs.
void * parent_node
Parent node.
void * parent_arc
Parent arc in shortest path tree.
Functor wrapper for SSP algorithm.
std::pair< typename Net::Flow_Type, typename Net::Flow_Type > operator()(Net &net) const
Result of transportation problem.
std::vector< std::vector< Cost_Type > > shipments
shipments[i][j] from i to j
Result of transshipment problem.
Flow_Type total_cost
Total transportation cost.
bool feasible
Is there a feasible solution?
Flow_Type total_flow
Total flow shipped.
Node with supply/demand for transshipment problems.
Flow_Type demand
Positive = supply, negative = demand.
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
Dynamic array container with automatic resizing.
Dynamic binary heap with node-based storage.
Maximum flow minimum cost network algorithms.