80#ifndef BLOSSOM_WEIGHTED_H
81#define BLOSSOM_WEIGHTED_H
110 template <
typename Weight_Type =
long long>
118 namespace blossom_weighted_detail
123 template <
typename T>
126 static_assert(std::is_integral_v<T>,
"Blossom_Weighted requires integral arc weights");
128 if constexpr (std::is_signed_v<T>)
130 using Common = std::common_type_t<T, long long>;
131 constexpr auto ll_max = std::numeric_limits<long long>::max();
132 constexpr auto ll_min = std::numeric_limits<long long>::min();
134 const auto v =
static_cast<Common>(value);
137 <<
"Weight cannot be represented as long long";
141 using Common = std::common_type_t<T, long long>;
142 constexpr auto ll_max = std::numeric_limits<long long>::max();
144 const auto v =
static_cast<Common>(value);
146 <<
"Weight cannot be represented as long long";
149 return static_cast<long long>(value);
186 Weight weight = Weight(),
192 using Raw_Weight = std::decay_t<decltype(weight(static_cast<Arc *>(
nullptr)))>;
197 static_assert(std::is_integral_v<Raw_Weight>,
198 "Blossom_Weighted requires integral arc weights");
201 <<
"compute_maximum_weight_general_matching(): g is a digraph";
208 constexpr auto max_vertex =
static_cast<size_t>(std::numeric_limits<MwVertex>::max());
210 <<
"Graph has too many vertices for weighted blossom implementation";
217 Node *p = it.get_curr();
227 long long weight = 0;
236 Arc *arc = it.get_curr_ne();
244 <<
"Weighted blossom internal node index mapping is invalid";
269 return a.weight > b.weight;
276 for (
size_t i = 0; i <
records.size();)
304 long long total_weight = 0;
305 size_t cardinality = 0;
314 const size_t mid = lo + (hi - lo) / 2;
331 for (
const auto & [
fst,
snd]: matched_pairs)
333 auto u =
static_cast<size_t>(
fst);
334 auto v =
static_cast<size_t>(
snd);
340 <<
"Weighted blossom returned an unknown matched pair";
344 +
static_cast<__int128>(arc_info->weight);
346 or sum <
static_cast<__int128>(std::numeric_limits<long long>::min()))
347 <<
"Matching total weight overflows long long";
348 total_weight =
static_cast<long long>(
sum);
379 Weight weight = Weight(),
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.
High-level sorting functions for Aleph containers.
WeightedDigraph::Node Node
List_Graph< Graph_Node< Node_Info >, Graph_Arc< Arc_Info > > GT
Internal weighted matching core used by Blossom_Weighted.H.
Simple dynamic array with automatic resizing and functional operations.
T & append(const T &data)
Append a copy of data
void reserve(size_t cap)
Reserves cap cells into the array.
Functor wrapper for weighted blossom matching.
Compute_Maximum_Weight_General_Matching(Weight weight=Weight(), SA sa=SA(), const bool max_cardinality=false)
Construct the solver with specific options.
Blossom_Weighted_Result< long long > operator()(const GT &g, DynDlist< typename GT::Arc * > &matching)
Compute maximum-weight matching.
RAII guard that saves and restores graph cookies.
Default distance accessor for arc weights.
Dynamic doubly linked list with O(1) size and bidirectional access.
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Graph_Node< Node_Info > Node
The graph type.
Graph_Arc< Arc_Info > Arc
The node class type.
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)
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.
constexpr size_t get_num_arcs() const noexcept
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
RAII guards for graph node/arc cookies.
Blossom_Weighted_Result< long long > compute_maximum_weight_general_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Weight weight=Weight(), SA sa=SA(), const bool max_cardinality=false)
Compute maximum-weight matching in a general undirected graph.
#define NODE_COOKIE(p)
Return the node cookie
Blossom_Weighted_Result< long long > blossom_maximum_weight_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, Weight weight=Weight(), SA sa=SA(), const bool max_cardinality=false)
Alias for compute_maximum_weight_general_matching().
Array< Edge< WeightType > > adjust_weights_for_maximum_cardinality_matching(const Array< Edge< WeightType > > &edges_in)
Adjust edge weights to prioritize maximum cardinality matching.
unsigned int VertexId
Type representing the unique ID of a vertex.
std::pair< VertexId, VertexId > VertexPair
Type representing a pair of vertices.
Array< VertexPair > maximum_weight_matching(const Array< Edge< WeightType > > &edges)
Compute a maximum-weighted matching in a general undirected graph.
long long to_ll_checked(T value)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
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.
std::decay_t< typename HeadC::Item_Type > T
DynArray< T > & in_place_sort(DynArray< T > &c, Cmp cmp=Cmp())
Sorts a DynArray in place.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Filtered iterator on all the arcs of a graph.
Result of weighted matching.
Weight_Type total_weight
Sum of matched arc weights.
size_t cardinality
Number of arcs in the matching.
Default filter for filtered iterators on arcs.
Type representing a weighted edge.
Dynamic array container with automatic resizing.
Dynamic doubly linked list implementation.
Generic graph and digraph implementations.
Utility algorithms and operations for graphs.