93template <
typename Flow_Type>
105 distance = std::numeric_limits<Flow_Type>::max();
170 const Flow_Type INF = std::numeric_limits<Flow_Type>::max();
179 using PQ_Entry = std::pair<Flow_Type, Node*>;
180 std::priority_queue<PQ_Entry, std::vector<PQ_Entry>, std::greater<PQ_Entry>>
pq;
186 auto [dist, u] =
pq.
top();
195 Arc* arc = it.get_curr();
200 Flow_Type residual = forward ? (arc->cap - arc->flow) : arc->flow;
262std::pair<typename Net::Flow_Type, typename Net::Flow_Type>
281 const Flow_Type INF = std::numeric_limits<Flow_Type>::max();
282 const size_t n = net.
vsize();
290 for (
size_t i = 0; i < n - 1; ++i)
295 auto arc = it.get_curr();
300 if (arc->cap > arc->flow)
341std::pair<typename Net::Flow_Type, typename Net::Flow_Type>
349 <<
"Network must have single source and single sink";
355 std::vector<SSP_Node_Info<Flow_Type>> node_info(net.
vsize());
371 for (
Node* v = sink; v != source;)
376 Flow_Type residual = forward ? (arc->cap - arc->flow) : arc->flow;
383 for (
Node* v = sink; v != source;)
408 auto p = it.get_curr();
409 if (
ssp_info<Net>(p).distance < std::numeric_limits<Flow_Type>::max())
420 auto p = it.get_curr();
421 if (
ssp_info<Net>(p).distance >= std::numeric_limits<Flow_Type>::max())
426 return {total_flow, total_cost};
435 std::pair<typename Net::Flow_Type, typename Net::Flow_Type>
455template <
typename Flow_Type>
464template <
typename Flow_Type>
506template <
class Net,
class GetDemand>
529 if (total_supply != total_demand)
542 Node* p = it.get_curr();
543 if (p == super_source
or p == super_sink)
560 result.
feasible = (flow == total_supply);
576template <
typename Cost_Type>
616template <
typename Cost_Type>
648 std::vector<Node*> workers(n);
649 for (
size_t i = 0; i < n; ++i)
656 std::vector<Node*> tasks(n);
657 for (
size_t j = 0; j < n; ++j)
664 for (
size_t i = 0; i < n; ++i)
665 for (
size_t j = 0; j < n; ++j)
673 result.
feasible = (
static_cast<size_t>(flow) == n);
679 for (
size_t i = 0; i < n; ++i)
684 auto arc = it.get_curr();
688 for (
size_t j = 0; j < n; ++j)
689 if (tasks[j] == tgt
and arc->flow > 0)
709template <
typename Cost_Type>
748template <
typename Cost_Type>
751 const std::vector<Cost_Type>&
demands,
752 const std::vector<std::vector<Cost_Type>>&
costs)
764 if (m == 0
or n == 0)
773 for (
auto s :
supplies) total_supply += s;
774 for (
auto d :
demands) total_demand += d;
776 if (total_supply != total_demand)
790 for (
size_t i = 0; i < m; ++i)
798 for (
size_t j = 0; j < n; ++j)
806 std::vector<std::vector<Arc*>>
arcs(m, std::vector<Arc*>(n));
807 for (
size_t i = 0; i < m; ++i)
808 for (
size_t j = 0; j < n; ++j)
818 result.
feasible = (flow == total_supply);
823 for (
size_t i = 0; i < m; ++i)
824 for (
size_t j = 0; j < n; ++j)
838template <
typename Flow_Type>
849 std::cout <<
"=== Min-Cost Flow Statistics ===\n"
882 auto arc = it.get_curr();
883 solution[arc] = arc->flow;
906 auto arc = it.get_curr();
907 if (solution.
has(arc))
908 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.
WeightedDigraph::Node Node
bool has_curr() const noexcept
Check if there is a current valid item.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Append a new item by copy.
void empty() noexcept
empty the list
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).
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)
DynArray< Graph::Arc * > arcs
#define NODE_COOKIE(p)
Return the node cookie
Main namespace for Aleph-w library functions.
Net::Flow_Type reduced_cost(const Net &net, typename Net::Arc *arc, typename Net::Node *from, bool forward)
Compute reduced cost of an arc.
bool ssp_init_potentials(Net &net, typename Net::Node *source)
Initialize potentials using Bellman-Ford.
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
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.
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.
Dynamic binary heap with node-based storage.
Maximum flow minimum cost network algorithms.