Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
combinatorics_enumeration_example.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 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
31
41# include <iomanip>
42# include <iostream>
43# include <utility>
44
45# include <ah-comb-generators.H>
46# include <ah-comb.H>
47# include <print_rule.H>
48
49using namespace Aleph;
50
51namespace
52{
53 template <class Seq>
54 void print_seq(const Seq & s)
55 {
56 std::cout << "[";
57 for (size_t i = 0; i < s.size(); ++i)
58 {
59 if (i > 0)
60 std::cout << ", ";
61 std::cout << s(i);
62 }
63 std::cout << "]";
64 }
65
67 {
68 std::cout << "[1] next_permutation with duplicates (multiset)\n";
69 print_rule();
70
71 Array<int> a = {1, 1, 2, 3};
72
73 size_t count = 1;
74 std::cout << std::setw(3) << count << " : ";
75 print_seq(a);
76 std::cout << "\n";
77
78 while (next_permutation(a))
79 {
80 ++count;
81 std::cout << std::setw(3) << count << " : ";
82 print_seq(a);
83 std::cout << "\n";
84 }
85
86 std::cout << "Total distinct lexicographic permutations: " << count << "\n";
87 std::cout << "After last step, reset to first: ";
88 print_seq(a);
89 std::cout << "\n\n";
90 }
91
93 {
94 std::cout << "[2] next_permutation with custom comparator (descending order)\n";
95 print_rule();
96
97 Array<int> a = {4, 3, 2, 1}; // first in Aleph::greater order
98
99 for (size_t step = 1; step <= 5; ++step)
100 {
101 std::cout << "Step " << step << " -> ";
102 print_seq(a);
103 std::cout << "\n";
105 }
106
107 std::cout << "\n";
108 }
109
111 {
112 std::cout << "[3] next_combination_indices (k-combinations over [0..n))\n";
113 print_rule();
114
115 const size_t n = 6;
116 Array<size_t> idx = {0, 1, 2};
117
118 size_t count = 0;
119 while (true)
120 {
121 ++count;
122 std::cout << std::setw(3) << count << " : ";
123 print_seq(idx);
124 std::cout << "\n";
125
126 if (not next_combination_indices(idx, n))
127 break;
128 }
129
130 std::cout << "Total combinations C(" << n << ", 3): " << count
131 << " (verified by combination_count = "
132 << combination_count(n, 3) << ")\n\n";
133 }
134
136 {
137 std::cout << "[4] next_combination_mask (fixed-popcount bitmask)\n";
138 print_rule();
139
140 const size_t n = 6;
141 uint64_t mask = first_combination_mask(3); // 000111
142
143 size_t count = 0;
144 while (true)
145 {
146 ++count;
147 std::cout << std::setw(3) << count << " : mask = ";
148 for (size_t b = n; b > 0; --b)
149 std::cout << (((mask >> (b - 1)) & 1ULL) ? '1' : '0');
150 std::cout << "\n";
151
152 if (not next_combination_mask(mask, n))
153 break;
154 }
155
156 std::cout << "Total bitmask combinations: " << count << "\n\n";
157 }
158
160 {
161 std::cout << "[5] for_each_combination / build_combinations\n";
162 print_rule();
163
165 "geom", "strings", "graphs", "dp", "net"
166 };
167
168 std::cout << "Feature triplets:\n";
170 [] (const Array<std::string> & c)
171 {
172 std::cout << " - ";
173 print_seq(c);
174 std::cout << "\n";
175 return true;
176 });
177
178 auto pairs = build_combinations(features, 2);
179 std::cout << "\nMaterialized pairs: " << pairs.size() << "\n";
180 std::cout << "First: ";
181 print_seq(pairs(0));
182 std::cout << " | Last: ";
183 print_seq(pairs(pairs.size() - 1));
184 std::cout << "\n\n";
185 }
186
187 // --- Lazy counterparts (ah-comb-generators.H) --------------------------
188 //
189 // next_permutation()/next_combination_indices() already support early
190 // exit — the `do { ... } while (next_*(...))` shape above can `break` at
191 // any point. lazy_permutations()/lazy_combinations() wrap that same
192 // stepping logic as an `Aleph::Generator`, so the payoff here is
193 // *ergonomics and composability* (plain range-`for`, chainable with other
194 // `Generator`-based code), not a capability that was missing before.
195
197 {
198 std::cout << "[6] lazy_permutations (ah-comb-generators.H)\n";
199 print_rule();
200
201 Array<char> a = {'a', 'b', 'c', 'd'};
202 std::cout << "First 5 of the 4! = 24 permutations of a, b, c, d:\n";
203
204 int count = 0;
205 for (const Array<char> &p : lazy_permutations(std::move(a)))
206 {
207 std::cout << std::setw(3) << ++count << " : ";
208 print_seq(p);
209 std::cout << "\n";
210 if (count == 5)
211 break; // the remaining 19 permutations are never generated
212 }
213 std::cout << "\nNote: the yielded array is reused in place across steps —\n"
214 "copy it (as print_seq does implicitly, by reading before the\n"
215 "next iteration) if you need to keep more than one alive.\n\n";
216 }
217
219 {
220 std::cout << "[7] lazy_combinations (ah-comb-generators.H)\n";
221 print_rule();
222
224 "geom", "strings", "graphs", "dp", "net"
225 };
226 const size_t feature_count = features.size();
227
228 std::cout << "Feature triplets, driven by a range-for instead of a\n"
229 "callback:\n";
230 for (const Array<std::string> &c : lazy_combinations(std::move(features), 3))
231 {
232 std::cout << " - ";
233 print_seq(c);
234 std::cout << "\n";
235 }
236 std::cout << "Total: " << combination_count(feature_count, 3)
237 << " combinations, matching for_each_combination in [5].\n\n";
238 }
239} // namespace
240
241int main()
242{
243 std::cout << "\n=== Combinatorics / Enumeration ===\n\n";
244
252
253 std::cout << "Done.\n";
254 return 0;
255}
Lazy (coroutine-based) permutation and combination enumeration.
Combinatorics utilities: permutations, combinations, and matrix transposition.
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:365
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
bool for_each_combination(const Array< T > &values, const size_t k, Op &&op)
*‍/
Definition ah-comb.H:1026
Array< Array< T > > build_combinations(const Array< T > &values, const size_t k)
Materialize all k-combinations of Array<T>.
Definition ah-comb.H:1048
bool next_combination_indices(Array< size_t > &idx, const size_t n, const bool reset_on_last=true)
Advance an index-combination [i0 < i1 < ... < i(k-1)] to the next one.
Definition ah-comb.H:891
bool next_combination_mask(uint64_t &mask, const size_t n, const bool reset_on_last=true)
Advance a fixed-popcount bitmask to the next combination (Gosper hack).
Definition ah-comb.H:932
Aleph::Generator< Array< T > > lazy_permutations(Array< T > a, Compare cmp=Compare())
Lazily enumerate all permutations of a, in lexicographic order.
bool next_permutation(Array< T > &a, Compare cmp=Compare(), const bool reset_on_last=true)
Compute the next lexicographic permutation of an Array.
Definition ah-comb.H:813
uint64_t first_combination_mask(const size_t k)
Build the first k-of-64 combination mask (k low bits set).
Definition ah-comb.H:905
size_t combination_count(size_t n, size_t k)
Compute n choose k with overflow checks.
Definition ah-comb.H:837
void print_rule()
Prints a horizontal rule for example output separation.
Definition print_rule.H:39
Aleph::Generator< Array< T > > lazy_combinations(Array< T > a, size_t k)
Lazily enumerate all k-element combinations of a's elements.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
STL namespace.
void print_seq(const C< T > &c)