79#ifndef MIN_COST_MATCHING_H
80#define MIN_COST_MATCHING_H
100template <
typename Cost_Type =
long long>
116template <
typename Cost_Type =
long long>
124namespace min_cost_matching_detail {
136 static_assert(std::is_integral_v<T>,
"Min_Cost_Matching requires integral arc costs");
139 constexpr int T_digits = std::numeric_limits<T>::digits;
140 constexpr int LL_digits = std::numeric_limits<long long>::digits;
156 <<
"Cost cannot be represented as long long";
164#if defined(_MSC_VER) && !defined(__clang__)
168 static_cast<__int128>(std::numeric_limits<long long>::min()))
169 <<
"Cost cannot be represented as long long";
173 return static_cast<long long>(
value);
179template <
class Cost_Accessor>
195 <<
"Minimum-cost matching cannot negate LLONG_MIN cost";
226template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
237 using Raw_Cost = std::decay_t<decltype(cost(static_cast<Arc *>(
nullptr)))>;
239 static_assert(std::is_integral_v<Raw_Cost>,
"Min_Cost_Matching requires integral arc costs");
248 long long total_cost = 0;
249 for (
auto it =
matching.get_it(); it.has_curr(); it.next_ne())
251 Arc *arc = it.get_curr();
253#if defined(_MSC_VER) && !defined(__clang__)
255 const long long lo = std::numeric_limits<long long>::min();
256 const long long hi = std::numeric_limits<long long>::max();
258 <<
"Minimum-cost matching total cost overflows long long";
265 sum <
static_cast<__int128>(std::numeric_limits<long long>::min()))
266 <<
"Minimum-cost matching total cost overflows long long";
267 total_cost =
static_cast<long long>(
sum);
273 <<
"Minimum-cost matching internal cardinality mismatch";
284template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
323template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
331 <<
"compute_minimum_cost_perfect_general_matching(): g is a digraph";
343 g,
matching, std::move(cost), std::move(sa),
true);
361template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
376template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
403template <AlephGraph GT,
class Cost = Dft_Dist<GT>, ArcFilter<GT> SA = Dft_Show_Arc<GT>>
Maximum-weight matching in general undirected graphs.
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#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 value
Functor wrapper for minimum-cost general matching.
Compute_Minimum_Cost_General_Matching(Cost cost=Cost(), SA sa=SA(), const bool max_cardinality=false)
Min_Cost_Matching_Result< long long > operator()(const GT &g, DynDlist< typename GT::Arc * > &matching)
Functor wrapper for minimum-cost perfect general matching.
Compute_Minimum_Cost_Perfect_General_Matching(Cost cost=Cost(), SA sa=SA())
Min_Cost_Perfect_Matching_Result< long long > operator()(const GT &g, DynDlist< typename GT::Arc * > &matching)
Dynamic doubly linked list with O(1) size and bidirectional access.
Graph_Arc< Arc_Info > Arc
The node class type.
Minimal std::expected-style result type for C++20.
Negated_Cost_Accessor(Cost_Accessor cost=Cost_Accessor())
long long operator()(Arc *arc) const
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
bool is_digraph() const noexcept
Return true if the graph this is directed.
Min_Cost_Perfect_Matching_Result< long long > compute_minimum_cost_perfect_general_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Cost cost=Cost(), SA sa=SA())
Compute minimum-cost perfect matching in a general undirected graph.
Min_Cost_Matching_Result< long long > compute_minimum_cost_general_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Cost cost=Cost(), SA sa=SA(), const bool max_cardinality=false)
Compute minimum-cost matching in a general undirected graph.
Min_Cost_Matching_Result< long long > blossom_minimum_cost_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Cost cost=Cost(), SA sa=SA(), const bool max_cardinality=false)
Alias for compute_minimum_cost_general_matching().
Min_Cost_Perfect_Matching_Result< long long > blossom_minimum_cost_perfect_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Cost cost=Cost(), SA sa=SA())
Alias for compute_minimum_cost_perfect_general_matching().
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
long long to_ll_checked(T value)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Result of minimum-cost matching.
Cost_Type total_cost
Sum of matched arc costs.
size_t cardinality
Number of arcs in the matching.
Result of minimum-cost perfect matching.
Cost_Type total_cost
Total cost if feasible.
bool feasible
Whether a perfect matching exists.
size_t cardinality
Cardinality (|V|/2 if feasible).