202#include <tclap/CmdLine.h>
208using namespace Aleph;
221 cout <<
"\n" << string(60,
'=') <<
"\n";
223 cout << string(60,
'=') <<
"\n\n";
234 for (
auto it = g.
get_node_it(); it.has_curr(); it.next())
236 auto node = it.get_curr();
240 cout <<
" " << node->get_info() <<
": degree " << degree <<
endl;
250 for (
size_t i = 0; i < n; i++)
254 for (
size_t i = 0; i < n; i++)
255 for (
size_t j = i + 1; j < n; j++)
267 cout <<
"Hamiltonian: Visit every VERTEX exactly once\n";
268 cout <<
"Eulerian: Visit every EDGE exactly once\n\n";
281 cout <<
"Triangle: A-B-C-A\n";
282 cout <<
" Vertices: 3, Edges: 3\n";
283 cout <<
" Each vertex has degree 2\n\n";
285 cout <<
"Hamiltonian cycle: A -> B -> C -> A (visits each vertex once)\n";
286 cout <<
"Eulerian cycle: A -> B -> C -> A (visits each edge once)\n";
287 cout <<
"\nTriangle is BOTH Hamiltonian AND Eulerian!\n";
293 auto center =
star.insert_node(
"Center");
294 auto p1 =
star.insert_node(
"P1");
295 auto p2 =
star.insert_node(
"P2");
296 auto p3 =
star.insert_node(
"P3");
297 auto p4 =
star.insert_node(
"P4");
298 star.insert_arc(center, p1, 1);
299 star.insert_arc(center, p2, 1);
300 star.insert_arc(center, p3, 1);
301 star.insert_arc(center, p4, 1);
303 cout <<
"Star: Center connected to P1, P2, P3, P4\n";
304 cout <<
" Center degree: 4\n";
305 cout <<
" P1-P4 degrees: 1 each\n\n";
307 cout <<
"Hamiltonian? NO - Can't visit all without repeating Center\n";
308 cout <<
"Eulerian? NO - Peripheral vertices have odd degree\n";
319 cout <<
"Ore's Theorem states:\n";
320 cout <<
"For a graph G with n >= 3 vertices, if for every pair of\n";
321 cout <<
"NON-ADJACENT vertices u, v: deg(u) + deg(v) >= n,\n";
322 cout <<
"then G has a Hamiltonian cycle.\n\n";
330 cout <<
"K5: Complete graph with 5 vertices\n";
331 cout <<
" All vertices connected to all others\n";
332 cout <<
" Each vertex has degree 4\n\n";
334 cout <<
"Check Ore's condition:\n";
335 cout <<
" In K5, every pair IS adjacent (no non-adjacent pairs)\n";
336 cout <<
" Condition is trivially satisfied!\n\n";
339 cout <<
"Satisfies Ore's condition? " << (
test1(
k5) ?
"YES" :
"NO") <<
endl;
340 cout <<
"=> K5 is Hamiltonian\n";
346 auto n0 =
c5.insert_node(
"0");
347 auto n1 =
c5.insert_node(
"1");
348 auto n2 =
c5.insert_node(
"2");
349 auto n3 =
c5.insert_node(
"3");
350 auto n4 =
c5.insert_node(
"4");
351 c5.insert_arc(n0, n1, 1);
352 c5.insert_arc(n1, n2, 1);
353 c5.insert_arc(n2, n3, 1);
354 c5.insert_arc(n3, n4, 1);
355 c5.insert_arc(n4, n0, 1);
357 cout <<
"C5: Cycle 0-1-2-3-4-0\n";
358 cout <<
" Each vertex has degree 2\n\n";
360 cout <<
"Check Ore's condition:\n";
361 cout <<
" Non-adjacent pair (0, 2): deg(0) + deg(2) = 2 + 2 = 4\n";
362 cout <<
" Need >= n = 5, but only have 4\n";
363 cout <<
" Condition NOT satisfied!\n\n";
366 cout <<
"Satisfies Ore's condition? " << (
test2(
c5) ?
"YES" :
"NO") <<
endl;
367 cout <<
"\nBUT: C5 IS Hamiltonian! (The cycle itself is Hamiltonian)\n";
368 cout <<
"=> Ore's is SUFFICIENT but not NECESSARY\n";
379 cout <<
"The Hamiltonian cycle problem is the foundation of TSP.\n";
380 cout <<
"TSP asks: What's the shortest Hamiltonian cycle?\n\n";
400 cout <<
"Cities: Bogota, Medellin, Cali, Barranquilla, Cartagena\n";
401 cout <<
"Connections:\n";
402 cout <<
" Bogota-Medellin, Bogota-Cali, Bogota-Barranquilla\n";
403 cout <<
" Medellin-Cali, Medellin-Barranquilla\n";
404 cout <<
" Barranquilla-Cartagena\n\n";
408 cout <<
"\nNon-adjacent pairs check:\n";
409 cout <<
" (Bogota, Cartagena): 3 + 1 = 4 < 5 - FAILS\n";
410 cout <<
" (Cali, Barranquilla): 2 + 2 = 4 < 5 - FAILS\n";
411 cout <<
" (Cali, Cartagena): 2 + 1 = 3 < 5 - FAILS\n";
416 cout <<
"\nThis doesn't mean no Hamiltonian cycle exists!\n";
417 cout <<
"Let's check manually:\n";
418 cout <<
" Bogota -> Medellin -> Barranquilla -> Cartagena -> ?\n";
419 cout <<
" Cartagena only connects to Barranquilla - STUCK!\n";
420 cout <<
"\nNeed to add Cali-Cartagena or Bogota-Cartagena connection.\n";
427 cout <<
"Added: Cali-Cartagena\n\n";
430 cout <<
"\nNow we can find a Hamiltonian cycle:\n";
431 cout <<
" Bogota -> Cali -> Cartagena -> Barranquilla -> Medellin -> Bogota\n";
432 cout <<
" (Visits each city exactly once and returns to start)\n";
443 cout <<
"Dense graphs are more likely to satisfy Ore's condition.\n\n";
447 {
"Sparse (n edges)", 8, 8},
448 {
"Medium (2n edges)", 8, 16},
449 {
"Dense (3n edges)", 8, 24},
450 {
"Complete (n(n-1)/2)", 8, 28}
453 cout <<
setw(25) <<
"Configuration" <<
setw(15) <<
"Satisfies Ore?" <<
endl;
462 for (
size_t i = 0; i < n; i++)
480 cout <<
"\nConclusion: Denser graphs more likely to be Hamiltonian.\n";
491 cout <<
"Dirac's Theorem:\n";
492 cout <<
"For a graph G with n >= 3 vertices, if deg(v) >= n/2 for ALL vertices,\n";
493 cout <<
"then G has a Hamiltonian cycle.\n\n";
495 cout <<
"Comparison with Ore's Theorem:\n";
496 cout <<
" | Property | Dirac | Ore |\n";
497 cout <<
" |--------------|-------------|-------------|\n";
498 cout <<
" | Complexity | O(V) | O(V^2) |\n";
499 cout <<
" | Condition | deg >= n/2 | sum >= n |\n";
500 cout <<
" | Strictness | More strict | Less strict |\n\n";
508 cout <<
"K6: Complete graph with 6 vertices\n";
509 cout <<
" Each vertex has degree 5\n";
510 cout <<
" n/2 = 3, so need deg >= 3\n";
511 cout <<
" 5 >= 3 ✓\n\n";
517 cout <<
"Ore: " << (
ore1(
k6) ?
"SATISFIED" :
"NOT satisfied") <<
endl;
525 for (
int i = 0; i < 6; i++)
527 for (
int i = 0; i < 6; i++)
530 cout <<
"C6: Cycle 0-1-2-3-4-5-0\n";
531 cout <<
" Each vertex has degree 2\n";
532 cout <<
" n/2 = 3, need deg >= 3\n";
533 cout <<
" 2 < 3 ✗\n\n";
539 cout <<
"Ore: " << (
ore2(
c6) ?
"SATISFIED" :
"NOT satisfied") <<
endl;
542 cout <<
"Min degree found: " <<
min_deg <<
" (at vertex " << min_node->get_info() <<
")\n";
543 cout <<
"\nBUT: C6 IS Hamiltonian! (The cycle itself is the Hamiltonian cycle)\n";
551 for (
size_t i = 0; i < n; i++)
555 for (
size_t i = 0; i < n; i++)
556 for (
size_t j = i + 1; j < n; j++)
557 if (j - i <= n/2
or i + n - j <= n/2)
569 cout <<
"For large graphs:\n";
570 cout <<
" - Ore checks ALL pairs of non-adjacent vertices: O(V^2)\n";
571 cout <<
" - Dirac checks EACH vertex's degree: O(V)\n\n";
573 cout <<
"Example timing for n=1000:\n";
574 cout <<
" Ore: ~1,000,000 pair comparisons\n";
575 cout <<
" Dirac: ~1,000 degree checks\n\n";
577 cout <<
"Use Dirac when:\n";
578 cout <<
" - Graph is expected to be dense\n";
579 cout <<
" - Quick preliminary test needed\n";
580 cout <<
" - Performance is critical\n\n";
582 cout <<
"Note: If Dirac passes, Ore also passes (but not vice versa).\n";
594 "Hamiltonian graph example for Aleph-w.\n"
595 "Demonstrates Ore's sufficiency condition for Hamiltonian cycles.",
601 "Run specific section: compare, ore, practical, density, dirac, or 'all'",
602 false,
"all",
"section",
cmd
610 cout <<
"============================================================\n";
611 cout <<
" ALEPH-W HAMILTONIAN GRAPHS EXAMPLE\n";
612 cout <<
"============================================================\n";
629 cout <<
"\n" << string(60,
'=') <<
"\n";
630 cout <<
"Hamiltonian graphs demo completed!\n";
631 cout << string(60,
'=') <<
"\n\n";
635 catch (TCLAP::ArgException& e)
637 cerr <<
"Error: " << e.error() <<
" for argument " << e.argId() <<
endl;
642 cerr <<
"Error: " << e.what() <<
endl;
Graph implemented with double-linked 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)
Tests Dirac's sufficient condition for Hamiltonian graphs.
Tests Ore's sufficient condition for Hamiltonian graphs.
auto get_node_it() const noexcept
Obtains an iterator to the nodes of graph.
static void bar(int val, int scale=1)
DynArray< Graph::Node * > nodes
Hamiltonian sufficiency testing for graphs.
void print_subsection(const string &title)
void print_section(const string &title)
void build_complete_graph(UGraph &g, size_t n)
void print_degrees(UGraph &g)
Main namespace for Aleph-w library functions.
std::string to_string(const time_t t, const std::string &format)
Format a time_t value into a string using format.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Arc of graph implemented with double-linked adjacency lists.
Node belonging to a graph implemented with a double linked adjacency list.
Filtered iterator of adjacent arcs of a node.
void test(unsigned long n, gsl_rng *r)
Generic graph and digraph implementations.