Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
graph_coloring_test.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 MIT License (see Graph_Coloring.H for full text)
13*/
14
15# include <gtest/gtest.h>
16# include <stdexcept>
17# include <string>
18# include <algorithm>
19# include <random>
20# include <vector>
21# include <Graph_Coloring.H>
22# include <tpl_sgraph.H>
23# include <tpl_agraph.H>
24
25using namespace Aleph;
26
27// ----- Graph type aliases -----
32
33// ===================================================================
34// Helper: build a complete graph K_n
35// ===================================================================
37{
38 Graph g;
40 for (size_t i = 0; i < n; ++i)
41 nodes.append(g.insert_node("v" + std::to_string(i)));
42
43 // For each pair (i, j) with i < j, insert an edge
44 size_t i = 0;
45 for (auto it_i = nodes.get_it(); it_i.has_curr(); it_i.next_ne(), ++i)
46 {
47 size_t j = 0;
48 for (auto it_j = nodes.get_it(); it_j.has_curr(); it_j.next_ne(), ++j)
49 if (j > i)
50 g.insert_arc(it_i.get_curr(), it_j.get_curr());
51 }
52
53 return g;
54}
55
56// ===================================================================
57// Helper: build a cycle graph C_n
58// ===================================================================
59static Graph build_cycle(size_t n)
60{
61 Graph g;
63 for (size_t i = 0; i < n; ++i)
64 nodes.append(g.insert_node("v" + std::to_string(i)));
65
66 Graph::Node *prev = nullptr;
67 Graph::Node *first = nullptr;
68 for (auto it = nodes.get_it(); it.has_curr(); it.next_ne())
69 {
70 Graph::Node *curr = it.get_curr();
71 if (prev != nullptr)
72 g.insert_arc(prev, curr);
73 else
74 first = curr;
75 prev = curr;
76 }
77 if (n > 2)
78 g.insert_arc(prev, first);
79
80 return g;
81}
82
83// ===================================================================
84// Helper: build a path graph P_n
85// ===================================================================
86static Graph build_path(size_t n)
87{
88 Graph g;
89 Graph::Node *prev = nullptr;
90 for (size_t i = 0; i < n; ++i)
91 {
92 auto *curr = g.insert_node("v" + std::to_string(i));
93 if (prev != nullptr)
94 g.insert_arc(prev, curr);
95 prev = curr;
96 }
97 return g;
98}
99
100// ===================================================================
101// Helper: build a star graph S_n (one center, n-1 leaves)
102// ===================================================================
103static Graph build_star(size_t n)
104{
105 Graph g;
106 if (n == 0) return g;
107 auto *center = g.insert_node("center");
108 for (size_t i = 1; i < n; ++i)
109 {
110 auto *leaf = g.insert_node("leaf" + std::to_string(i));
111 g.insert_arc(center, leaf);
112 }
113 return g;
114}
115
116// ===================================================================
117// Helper: build the Petersen graph (chromatic number = 3)
118// ===================================================================
120{
121 Graph g;
122 // Outer ring: 0..4, inner pentagram: 5..9
123 Graph::Node *nodes[10];
124 for (int i = 0; i < 10; ++i)
125 nodes[i] = g.insert_node("p" + std::to_string(i));
126
127 // Outer cycle: 0-1-2-3-4-0
128 for (int i = 0; i < 5; ++i)
129 g.insert_arc(nodes[i], nodes[(i + 1) % 5]);
130
131 // Inner pentagram: 5-7-9-6-8-5
132 g.insert_arc(nodes[5], nodes[7]);
133 g.insert_arc(nodes[7], nodes[9]);
134 g.insert_arc(nodes[9], nodes[6]);
135 g.insert_arc(nodes[6], nodes[8]);
136 g.insert_arc(nodes[8], nodes[5]);
137
138 // Spokes: i -- i+5
139 for (int i = 0; i < 5; ++i)
140 g.insert_arc(nodes[i], nodes[i + 5]);
141
142 return g;
143}
144
145// ===================================================================
146// Helper: build a wheel graph W_n (cycle of n-1 + central hub)
147// ===================================================================
148static Graph build_wheel(size_t n)
149{
150 Graph g;
151 if (n < 4) return g;
152
153 auto *hub = g.insert_node("hub");
155 for (size_t i = 1; i < n; ++i)
156 {
157 auto *v = g.insert_node("v" + std::to_string(i));
158 ring.append(v);
159 g.insert_arc(hub, v);
160 }
161
162 Graph::Node *prev = nullptr;
163 Graph::Node *first = nullptr;
164 for (auto it = ring.get_it(); it.has_curr(); it.next_ne())
165 {
166 auto *curr = it.get_curr();
167 if (prev != nullptr)
168 g.insert_arc(prev, curr);
169 else
170 first = curr;
171 prev = curr;
172 }
173 g.insert_arc(prev, first);
174
175 return g;
176}
177
178// ===================================================================
179// Helper: build K_{m,n} complete bipartite graph
180// ===================================================================
181static Graph build_complete_bipartite(size_t m, size_t n)
182{
183 Graph g;
184 DynList<Graph::Node *> left, right;
185 for (size_t i = 0; i < m; ++i)
186 left.append(g.insert_node("L" + std::to_string(i)));
187 for (size_t i = 0; i < n; ++i)
188 right.append(g.insert_node("R" + std::to_string(i)));
189
190 for (auto li = left.get_it(); li.has_curr(); li.next_ne())
191 for (auto ri = right.get_it(); ri.has_curr(); ri.next_ne())
192 g.insert_arc(li.get_curr(), ri.get_curr());
193
194 return g;
195}
196
197// ===================================================================
198// Count distinct colors in a coloring map
199// ===================================================================
202{
204 colors.for_each([&](const auto & p) { s.insert(p.second); });
205 return s.size();
206}
207
208// ===================================================================
209// Tests: trivial cases
210// ===================================================================
211
226
242
244{
245 Graph g;
246 for (int i = 0; i < 10; ++i)
247 g.insert_node("v" + std::to_string(i));
248
250
253
256
259}
260
261// ===================================================================
262// Tests: complete graphs K_n (need exactly n colors)
263// ===================================================================
264
279
289
299
309
310// ===================================================================
311// Tests: bipartite graphs and trees (chromatic number = 2)
312// ===================================================================
313
323
333
343
345{
346 // A simple tree (chain = path) needs 2 colors
347 auto g = build_path(10);
349
352}
353
354// ===================================================================
355// Tests: cycles (even = 2 colors, odd = 3 colors)
356// ===================================================================
357
367
377
387
388// ===================================================================
389// Tests: Petersen graph (chromatic number = 3)
390// ===================================================================
391
401
402// ===================================================================
403// Tests: disconnected graphs
404// ===================================================================
405
407{
408 // Two disconnected triangles
409 Graph g;
410 auto *a1 = g.insert_node("a1");
411 auto *a2 = g.insert_node("a2");
412 auto *a3 = g.insert_node("a3");
413 g.insert_arc(a1, a2);
414 g.insert_arc(a2, a3);
415 g.insert_arc(a3, a1);
416
417 auto *b1 = g.insert_node("b1");
418 auto *b2 = g.insert_node("b2");
419 auto *b3 = g.insert_node("b3");
420 g.insert_arc(b1, b2);
421 g.insert_arc(b2, b3);
422 g.insert_arc(b3, b1);
423
425
426 size_t k = dsatur_coloring(g, colors);
427 EXPECT_EQ(k, 3u);
429}
430
432{
433 // A triangle (needs 3 colors) + isolated node
434 Graph g;
435 auto *a = g.insert_node("a");
436 auto *b = g.insert_node("b");
437 auto *c = g.insert_node("c");
438 g.insert_arc(a, b);
439 g.insert_arc(b, c);
440 g.insert_arc(c, a);
441 g.insert_node("isolated");
442
444
445 size_t k = dsatur_coloring(g, colors);
446 EXPECT_EQ(k, 3u);
448}
449
450// ===================================================================
451// Tests: wheel graphs
452// ===================================================================
453
455{
456 // W5 = hub + C4; C4 is even cycle → 3 colors needed
457 auto g = build_wheel(5);
459
460 size_t k = dsatur_coloring(g, colors);
461 EXPECT_EQ(k, 3u);
463}
464
466{
467 // W6 = hub + C5; C5 is odd cycle → 4 colors needed
468 auto g = build_wheel(6);
470
471 size_t k = dsatur_coloring(g, colors);
472 EXPECT_EQ(k, 4u);
474}
475
476// ===================================================================
477// Tests: algorithm comparison — all produce valid colorings
478// ===================================================================
479
481{
482 auto g = build_petersen();
484
485 size_t k1 = greedy_coloring(g, c1);
486 size_t k2 = welsh_powell_coloring(g, c2);
487 size_t k3 = dsatur_coloring(g, c3);
488
492
493 // All should use at most Delta+1 colors
494 // Petersen graph is 3-regular, so Delta+1 = 4
495 EXPECT_LE(k1, 4u);
496 EXPECT_LE(k2, 4u);
497 EXPECT_LE(k3, 4u);
498}
499
501{
502 // Greedy coloring guarantees at most Delta+1 colors
503 auto g = build_complete_bipartite(4, 4);
505
506 size_t k = greedy_coloring(g, colors);
507 // K_{4,4}: Delta = 4, so k <= 5
508 EXPECT_LE(k, 5u);
510}
511
512// ===================================================================
513// Tests: validation
514// ===================================================================
515
517{
518 auto g = build_complete_graph(3);
520
521 // Assign the same color to all nodes
522 for (auto it = g.get_node_it(); it.has_curr(); it.next_ne())
523 colors.insert(it.get_curr(), 0);
524
526}
527
529{
530 Graph g;
531 auto *a = g.insert_node("a");
532 auto *b = g.insert_node("b");
533 g.insert_arc(a, b);
534
535 // Only color node a, not b
537 colors.insert(a, 0);
538
540}
541
542// Regression: edgeless graph where the colors map is keyed with a foreign
543// pointer not belonging to the graph. A size match alone would pass
544// incorrectly; the per-node check must catch this.
546{
547 Graph g;
548 auto *a = g.insert_node("a"); // sole graph node
549
550 // Create a dummy node in a separate graph and use it as a foreign key.
551 Graph other;
552 auto *foreign = other.insert_node("foreign");
553
555 colors.insert(foreign, 0); // same size (1) but wrong key
556
558
559 // A properly keyed map must pass.
561 good_colors.insert(a, 0);
563}
564
565// Regression: isolated node (no incident arcs) missing from colors.
566// The arc loop would never visit it, so without the per-node check the
567// function would incorrectly return true.
569{
570 Graph g;
571 auto *a = g.insert_node("a");
572 auto *b = g.insert_node("b");
573 auto *lone = g.insert_node("lone"); // no arcs
574 g.insert_arc(a, b);
575
577 colors.insert(a, 0);
578 colors.insert(b, 1);
579 // lone is intentionally absent
580
582
583 // Adding the isolated node makes it valid.
584 colors.insert(lone, 0);
586}
587
589{
590 Graph g;
591 auto *a = g.insert_node("a");
592 g.insert_arc(a, a);
593
595 colors.insert(a, 0);
596
598 EXPECT_THROW(greedy_coloring(g, colors), std::domain_error);
599 EXPECT_THROW(welsh_powell_coloring(g, colors), std::domain_error);
600 EXPECT_THROW(dsatur_coloring(g, colors), std::domain_error);
601 EXPECT_THROW(chromatic_number(g, colors), std::domain_error);
602}
603
605{
606 // Two nodes connected by two parallel arcs (multigraph).
607 Graph g;
608 auto *a = g.insert_node("a");
609 auto *b = g.insert_node("b");
610 g.insert_arc(a, b);
611 g.insert_arc(a, b);
612
613 // A coloring that assigns the same color to both endpoints is invalid.
615 colors.insert(a, 0);
616 colors.insert(b, 0);
618
619 // The algorithms should still produce a valid coloring (parallel edges are
620 // handled correctly — they are treated like a single edge for coloring).
623 EXPECT_TRUE(is_valid_coloring(g, result));
624
626 EXPECT_TRUE(is_valid_coloring(g, result));
627
629 EXPECT_TRUE(is_valid_coloring(g, result));
630
632 EXPECT_TRUE(is_valid_coloring(g, result));
633}
634
635// ===================================================================
636// Tests: chromatic number (exact, small graphs)
637// ===================================================================
638
646
648{
649 Graph g;
650 for (int i = 0; i < 5; ++i)
651 g.insert_node("v" + std::to_string(i));
652
656}
657
667
676
685
694
703
705{
706 Graph g;
707 for (int i = 0; i < 65; ++i)
708 g.insert_node("v" + std::to_string(i));
709
711 EXPECT_THROW(chromatic_number(g, colors), std::domain_error);
712}
713
715{
716 Graph g;
717 std::vector<Graph::Node *> ns;
718 for (int i = 0; i < 64; ++i)
719 ns.push_back(g.insert_node("v" + std::to_string(i)));
720
721 // Add an edge between the first and last node so adjacency around
722 // the highest index (63) is exercised.
723 g.insert_arc(ns[0], ns[63]);
724
727 size_t chi = chromatic_number(g, colors);
728 EXPECT_EQ(chi, 2u); // One edge → 2 colors needed
729 EXPECT_EQ(colors.size(), 64u);
730 });
731}
732
733// ===================================================================
734// Tests: List_SGraph type
735// ===================================================================
736
738{
739 SGraph g;
740 auto *a = g.insert_node(1);
741 auto *b = g.insert_node(2);
742 auto *c = g.insert_node(3);
743 g.insert_arc(a, b);
744 g.insert_arc(b, c);
745 g.insert_arc(c, a);
746
748
749 size_t k = dsatur_coloring(g, colors);
750 EXPECT_EQ(k, 3u);
752}
753
755{
756 SGraph g;
757 auto *a = g.insert_node(1);
758 auto *b = g.insert_node(2);
759 auto *c = g.insert_node(3);
760 auto *d = g.insert_node(4);
761 g.insert_arc(a, b);
762 g.insert_arc(b, c);
763 g.insert_arc(c, d);
764 g.insert_arc(d, a);
765
767
768 size_t k = greedy_coloring(g, colors);
769 EXPECT_LE(k, 3u);
771}
772
774{
775 DGraph g;
776 auto *a = g.insert_node("a");
777 auto *b = g.insert_node("b");
778 g.insert_arc(a, b);
779
781
784
787
790
793}
794
796{
797 DGraph g;
798 auto *a = g.insert_node("a");
799 auto *b = g.insert_node("b");
800 g.insert_arc(a, b);
801
803 colors.insert(b, 0);
804
806
809
812
815
818}
819
821{
822 AGraph g;
823 auto *a = g.insert_node("a");
824 auto *b = g.insert_node("b");
825 auto *c = g.insert_node("c");
826 g.insert_arc(a, b);
827 g.insert_arc(b, c);
828 g.insert_arc(c, a);
829
831
836}
837
838// ===================================================================
839// Tests: functor wrappers
840// ===================================================================
841
862
863// ===================================================================
864// Tests: cookie preservation
865// ===================================================================
866
868{
869 Graph g;
870 auto *a = g.insert_node("a");
871 auto *b = g.insert_node("b");
872 g.insert_arc(a, b);
873
874 // Set cookies to known values
875 int sentinel_a = 42;
876 int sentinel_b = 99;
879
882
883 // Cookies should be restored
886}
887
888// ===================================================================
889// Illustrative example: map coloring (South America)
890// ===================================================================
891
893{
894 // Simplified South America adjacency
895 Graph g;
896 auto *br = g.insert_node("Brazil");
897 auto *ar = g.insert_node("Argentina");
898 auto *uy = g.insert_node("Uruguay");
899 auto *py = g.insert_node("Paraguay");
900 auto *bo = g.insert_node("Bolivia");
901 auto *pe = g.insert_node("Peru");
902 auto *cl = g.insert_node("Chile");
903 auto *ec = g.insert_node("Ecuador");
904 auto *co = g.insert_node("Colombia");
905 auto *ve = g.insert_node("Venezuela");
906 auto *gy = g.insert_node("Guyana");
907 auto *sr = g.insert_node("Suriname");
908 auto *gf = g.insert_node("French Guiana");
909
910 // Borders
911 g.insert_arc(br, uy);
912 g.insert_arc(br, ar);
913 g.insert_arc(br, py);
914 g.insert_arc(br, bo);
915 g.insert_arc(br, pe);
916 g.insert_arc(br, co);
917 g.insert_arc(br, ve);
918 g.insert_arc(br, gy);
919 g.insert_arc(br, sr);
920 g.insert_arc(br, gf);
921 g.insert_arc(ar, uy);
922 g.insert_arc(ar, py);
923 g.insert_arc(ar, bo);
924 g.insert_arc(ar, cl);
925 g.insert_arc(py, bo);
926 g.insert_arc(bo, pe);
927 g.insert_arc(bo, cl);
928 g.insert_arc(pe, cl);
929 g.insert_arc(pe, ec);
930 g.insert_arc(pe, co);
931 g.insert_arc(ec, co);
932 g.insert_arc(co, ve);
933 g.insert_arc(ve, gy);
934 g.insert_arc(gy, sr);
935 g.insert_arc(sr, gf);
936
938 size_t k = dsatur_coloring(g, colors);
939
941 EXPECT_LE(k, 4u); // Four Color Theorem guarantees <= 4 for planar graphs
942}
943
944// ===================================================================
945// Illustrative example: exam scheduling
946// ===================================================================
947
949{
950 // Courses that share students cannot be scheduled at the same time.
951 // Courses: Math, Physics, CS, Chemistry, Biology, English
952 // Conflicts: Math-Physics, Math-CS, Physics-CS, Physics-Chemistry,
953 // Chemistry-Biology, Biology-English
954 Graph g;
955 auto *math = g.insert_node("Math");
956 auto *physics = g.insert_node("Physics");
957 auto *cs = g.insert_node("CS");
958 auto *chem = g.insert_node("Chemistry");
959 auto *bio = g.insert_node("Biology");
960 auto *eng = g.insert_node("English");
961
963 g.insert_arc(math, cs);
966 g.insert_arc(chem, bio);
967 g.insert_arc(bio, eng);
968
970 size_t num_slots = dsatur_coloring(g, colors);
971
973 // The chromatic number for this graph is 3
974 EXPECT_LE(num_slots, 3u);
975}
976
977// ===================================================================
978// Tests: chromatic number for wheel graphs
979// ===================================================================
980
982{
983 // W5 = hub + C4; chromatic number = 3
984 auto g = build_wheel(5);
986
989}
990
992{
993 // W6 = hub + C5; chromatic number = 4
994 auto g = build_wheel(6);
996
999}
1000
1001// ===================================================================
1002// Tests: Randomized/Property-based testing
1003// ===================================================================
1004
1006{
1007 // Fixed seed for reproducibility
1008 std::mt19937 rng(42);
1009
1010 auto build_random_graph = [&](size_t num_nodes, double edge_prob) -> Graph {
1011 Graph g;
1012 std::vector<Graph::Node *> nodes;
1013
1014 for (size_t i = 0; i < num_nodes; ++i)
1015 nodes.push_back(g.insert_node("v" + std::to_string(i)));
1016
1017 std::uniform_real_distribution<> dist(0.0, 1.0);
1018 for (size_t i = 0; i < num_nodes; ++i)
1019 for (size_t j = i + 1; j < num_nodes; ++j)
1020 if (dist(rng) < edge_prob)
1021 g.insert_arc(nodes[i], nodes[j]);
1022
1023 return g;
1024 };
1025
1026 auto max_degree = [](const Graph &g) -> size_t {
1027 size_t delta = 0;
1028 for (auto it = g.get_node_it(); it.has_curr(); it.next_ne())
1029 delta = std::max(delta, g.get_num_arcs(it.get_curr()));
1030 return delta;
1031 };
1032
1033 // Test cases: sparse, medium, dense, disconnected
1034 struct TestCase {
1035 size_t nodes;
1036 double edge_prob;
1037 std::string description;
1038 };
1039
1040 std::vector<TestCase> test_cases = {
1041 {10, 0.1, "sparse"},
1042 {15, 0.3, "medium"},
1043 {12, 0.6, "dense"},
1044 {20, 0.05, "disconnected components"},
1045 {8, 0.8, "very dense"}
1046 };
1047
1048 for (const auto &tc : test_cases)
1049 {
1050 for (int trial = 0; trial < 20; ++trial)
1051 {
1052 Graph g = build_random_graph(tc.nodes, tc.edge_prob);
1053
1054 if (g.get_num_nodes() == 0)
1055 continue;
1056
1057 size_t delta = max_degree(g);
1059
1060 // Test Greedy
1061 size_t k_greedy = greedy_coloring(g, colors);
1063 << "Greedy produced invalid coloring for " << tc.description
1064 << " graph (trial " << trial << ")";
1065 EXPECT_LE(k_greedy, delta + 1)
1066 << "Greedy used " << k_greedy << " colors but max degree is " << delta
1067 << " for " << tc.description << " graph (trial " << trial << ")";
1068
1069 // Test Welsh-Powell
1070 size_t k_wp = welsh_powell_coloring(g, colors);
1072 << "Welsh-Powell produced invalid coloring for " << tc.description
1073 << " graph (trial " << trial << ")";
1074 EXPECT_LE(k_wp, delta + 1)
1075 << "Welsh-Powell used " << k_wp << " colors but max degree is " << delta
1076 << " for " << tc.description << " graph (trial " << trial << ")";
1077
1078 // Test DSatur
1079 size_t k = dsatur_coloring(g, colors);
1080
1081 // Invariant 1: coloring must be valid
1083 << "DSatur produced invalid coloring for " << tc.description
1084 << " graph (trial " << trial << ")";
1085
1086 // Invariant 2: k <= Δ + 1 (Brooks' theorem bound)
1087 EXPECT_LE(k, delta + 1)
1088 << "DSatur used " << k << " colors but max degree is " << delta
1089 << " for " << tc.description << " graph (trial " << trial << ")";
1090
1091 // Test chromatic_number for small graphs
1092 if (g.get_num_nodes() <= 15)
1093 {
1095 size_t chi = chromatic_number(g, exact_colors);
1096
1098 << "chromatic_number produced invalid coloring for " << tc.description
1099 << " graph (trial " << trial << ")";
1100
1102 << "Exact chromatic number " << chi << " exceeds Greedy result " << k_greedy
1103 << " for " << tc.description << " graph (trial " << trial << ")";
1105 << "Exact chromatic number " << chi << " exceeds Welsh-Powell result " << k_wp
1106 << " for " << tc.description << " graph (trial " << trial << ")";
1107 EXPECT_LE(chi, k)
1108 << "Exact chromatic number " << chi << " exceeds DSatur result " << k
1109 << " for " << tc.description << " graph (trial " << trial << ")";
1110 }
1111 }
1112 }
1113}
Graph coloring algorithms and heuristics.
int num_nodes
Definition btreepic.C:410
virtual Node * insert_node(Node *p)
Definition tpl_agraph.H:393
Arc * insert_arc(Node *src, Node *tgt, void *a)
Definition tpl_agraph.H:456
Functor wrapper for dsatur_coloring.
Generic directed graph (digraph) wrapper template.
Definition graph-dry.H:3854
Dynamic singly linked list with functional programming support.
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
Generic key-value map implemented on top of a binary search tree.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair.
Dynamic set backed by balanced binary search trees with automatic memory management.
const size_t & size() const
Returns the cardinality of the set.
Key * insert(const Key &key)
Inserts a key into the dynamic set.
Arc for graphs implemented with simple adjacency lists.
Definition tpl_sgraph.H:197
Functor wrapper for greedy_coloring.
virtual Node * insert_node(Node *node) noexcept
Insertion of a node already allocated.
Definition tpl_graph.H:524
Node Node
The graph type.
Definition tpl_graph.H:432
Arc * insert_arc(Node *src_node, Node *tgt_node, void *a)
Definition tpl_graph.H:604
Graph class implemented with singly-linked adjacency lists.
Definition tpl_sgraph.H:274
Arc * insert_arc(Node *src, Node *tgt, void *a)
Definition tpl_sgraph.H:497
virtual Node * insert_node(Node *p)
Insertion of a node whose memory has already been allocated.
Definition tpl_sgraph.H:487
A non-degenerate triangle defined by three points.
Definition point.H:1478
Functor wrapper for welsh_powell_coloring.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:779
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Definition graph-dry.H:695
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:222
CityGraph build_random_graph(int num_nodes, double edge_probability, double max_weight, unsigned seed=42)
Build a random graph for performance testing.
#define TEST(name)
static mt19937 rng
static Graph build_complete_bipartite(size_t m, size_t n)
static Graph build_star(size_t n)
static Graph build_petersen()
static Graph build_path(size_t n)
static Graph build_complete_graph(size_t n)
static Graph build_cycle(size_t n)
static Graph build_wheel(size_t n)
static size_t count_distinct_colors(const DynMapTree< Graph::Node *, size_t > &colors)
DynArray< Graph::Node * > nodes
Definition graphpic.C:406
size_t dsatur_coloring(const GT &g, DynMapTree< typename GT::Node *, size_t > &colors)
DSatur graph coloring (saturation-degree heuristic).
bool is_valid_coloring(const GT &g, const DynMapTree< typename GT::Node *, size_t > &colors)
Validates a graph coloring.
size_t chromatic_number(const GT &g, DynMapTree< typename GT::Node *, size_t > &colors)
Computes the exact chromatic number of a small graph.
#define NODE_COOKIE(p)
Return the node cookie
size_t greedy_coloring(const GT &g, DynMapTree< typename GT::Node *, size_t > &colors)
Greedy graph coloring in iteration order.
size_t welsh_powell_coloring(const GT &g, DynMapTree< typename GT::Node *, size_t > &colors)
Welsh-Powell graph coloring.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
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.
Arc of graph implemented with double-linked adjacency lists.
Definition tpl_graph.H:222
FooMap m(5, fst_unit_pair_hash, snd_unit_pair_hash)
static int * k
Array-based graph implementation.
Simple graph implementation with adjacency lists.