104 for (
size_t i = 0; i < s.nodes.size(); ++i)
107 for (
const auto & [u, v] : s.edges)
110 <<
"Edge endpoint out of range";
136 for (
auto it =
matching.get_it(); it.has_curr(); it.next_ne())
138 auto * arc = it.get_curr();
139 size_t u =
static_cast<size_t>(g.
get_src_node(arc)->get_info());
140 size_t v =
static_cast<size_t>(g.
get_tgt_node(arc)->get_info());
143 seen.insert(make_pair(u, v));
147 for (
const auto & p :
seen)
163 if (pairs.is_empty())
167 for (
size_t i = 0; i < pairs.size(); ++i)
169 const auto & [u, v] = pairs[i];
171 if (i + 1 < pairs.size())
192 const string & file_path)
202 ofstream
out(file_path);
205 cerr <<
"Cannot write file: " << file_path <<
endl;
209 out <<
"\\documentclass[tikz,border=10pt]{standalone}\n";
210 out <<
"\\usepackage{tikz}\n";
211 out <<
"\\usetikzlibrary{arrows.meta}\n";
212 out <<
"\\begin{document}\n";
213 out <<
"\\begin{tikzpicture}[x=1cm,y=1cm]\n";
215 out <<
" \\fill[blue!2] (-4.2,-3.2) rectangle (4.2,3.2);\n";
216 out <<
" \\node[font=\\bfseries\\large] at (0,2.95) {"
217 << s.title <<
"};\n";
220 <<
"edge/.style={line width=0.9pt, draw=black!65},"
221 <<
"match/.style={line width=2.6pt, draw=orange!90!black},"
222 <<
"vertex/.style={circle, draw=black!70, fill=white, minimum size=9mm, inner sep=1pt, font=\\small\\bfseries}"
225 for (
size_t i = 0; i < s.nodes.size(); ++i)
227 const auto & node = s.nodes[i];
228 out <<
" \\node[vertex] (n" << i <<
") at ("
229 << fixed << setprecision(2) << node.x <<
"," << node.y <<
") {"
230 << node.label <<
"};\n";
233 for (
const auto & [u, v] : s.edges)
236 <<
"Edge endpoint out of range";
243 if (
matched_set.search(make_pair(a, b)) !=
nullptr)
246 out <<
" \\draw[edge] (n" << u <<
") -- (n" << v <<
");\n";
250 out <<
" \\draw[match] (n" << u <<
") -- (n" << v <<
");\n";
252 out <<
" \\node[font=\\small] at (0,-2.95) {matching size = "
255 out <<
"\\end{tikzpicture}\n";
256 out <<
"\\end{document}\n";
305 cout <<
" " << backend_name <<
" -> size " << cardinality
309 cerr <<
" Warning: cardinality mismatch across backends\n";
325 cout <<
"\n" << s.title <<
"\n";
326 cout << string(s.title.size(),
'-') <<
"\n";
328 size_t cardinality = 0;
341 const string tex_path =
"/tmp/blossom_" + s.slug +
".tex";
344 cout <<
" TikZ export: " <<
tex_path <<
"\n";
360 .slug =
"pentagon_stems",
361 .title =
"Blossom demo: odd cycle + stems",
373 {0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 0},
374 {1, 5}, {2, 6}, {3, 7}
379 .slug =
"double_flower",
380 .title =
"Blossom demo: two odd flowers",
394 {0, 1}, {1, 2}, {2, 3}, {3, 4}, {4, 0},
395 {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 5},
396 {2, 5}, {3, 7}, {1, 9}, {6, 9}
400 cout <<
"Edmonds-Blossom maximum matching examples\n";
401 cout <<
"========================================\n";
406 cout <<
"\nTo compile a TikZ file to PDF (optional):\n";
407 cout <<
" cd /tmp && pdflatex blossom_pentagon_stems.tex\n";
408 cout <<
" cd /tmp && pdflatex blossom_double_flower.tex\n";
Edmonds' Blossom algorithm for maximum matching in general graphs.
#define ah_range_error_if(C)
Throws std::range_error if condition holds.
int main()
Program entry that runs two Edmonds–Blossom example scenarios and emits TikZ visualizations.
Simple dynamic array with automatic resizing and functional operations.
void reserve(size_t cap)
Reserves cap cells into the array.
Dynamic doubly linked list with O(1) size and bidirectional access.
Dynamic set backed by balanced binary search trees with automatic memory management.
Arc for graphs implemented with simple adjacency lists.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
DynArray< Graph::Node * > nodes
Main namespace for Aleph-w library functions.
T & swap(T &t1, T &t2)
Generic swap using object's swap method.
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::pair< First, Second > pair
Alias to std::pair kept for backwards compatibility.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
Arc of graph implemented with double-linked adjacency lists.
Array-based graph implementation.
Dynamic array container with automatic resizing.
Dynamic set implementations based on balanced binary search trees.
Generic graph and digraph implementations.
Simple graph implementation with adjacency lists.