Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_random_queue.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
43# ifndef TPL_RANDOM_QUEUE_H
44# define TPL_RANDOM_QUEUE_H
45
46# include <gsl/gsl_rng.h>
47# include <htlist.H>
48# include <ah-dry.H>
49# include <tpl_dynArray.H>
50# include <utility>
51 # include <ah-errors.H>
52
53namespace Aleph {
54
67 template <class T>
69 : public LocateFunctions<Random_Set<T>, T>,
70 public FunctionalMethods<Random_Set<T>, T>,
71 public GenericKeys<Random_Set<T>, T>,
72 public EqualToMethod<Random_Set<T>>,
73 public StlAlephIterator<Random_Set<T>>
74{
75private:
76
78 gsl_rng * r = nullptr;
79
80public:
81
83
84 using Item_Type = T;
85
87 [[nodiscard]] gsl_rng * get_rng() const { return r; }
88
90 void set_seed(unsigned long seed) const noexcept { gsl_rng_set(r, seed); }
91
93 [[nodiscard]] size_t size() const { return array.size(); }
94
96 {
98 ah_bad_alloc_if(r == nullptr);
99
100 gsl_rng_set(r, time(nullptr) % gsl_rng_max(r));
101 }
102
104 void swap(Random_Set & s)
105 {
106 array.swap(s.array);
107 std::swap(r, s.r);
108 }
109
112 {
113 s.for_each([this] (auto item) { this->append(item); });
114 }
115
117 Random_Set(Random_Set && s) noexcept { swap(s); }
118
120 {
121 if (this == &s)
122 return *this;
123
124 array.cut(0); // Clear the array first
125 s.for_each([this] (auto item) { this->append(item); });
126
127 return *this;
128 }
129
131 {
132 swap(s);
133 return *this;
134 }
135
138 {
139 l.for_each([this] (const T & item) { append(item); });
140 }
141
144 template <class It> Random_Set(It b, It e) : Random_Set()
145 {
146 for (It it = b; it != e; ++it)
147 append(*it);
148 }
149
151 Random_Set(std::initializer_list<T> l) : Random_Set()
152 {
153 for (const auto & item : l)
154 append(item);
155 }
156
158 {
159 if (r != nullptr)
161 }
162
172 void put(const T & item)
173 {
174 static_assert(std::is_copy_constructible_v<T>,
175 "Random_Set::put requires copyable T");
176 array.append(item);
177 }
178
179
189 void put(T && item)
190 {
191 static_assert(std::is_move_constructible_v<T>,
192 "Random_Set::put requires moveable T");
193 array.append(std::forward<T>(item));
194 }
195
207 T & append(const T & item)
208 {
209 put(item);
210 const size_t last_index = array.size() - 1;
211 const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar
212 if (pos != last_index)
213 std::swap(array(pos), array(last_index));
214 return array(pos);
215 }
216
223 T & append(T && item)
224 {
225 put(std::forward<T>(item));
226 const size_t last_index = array.size() - 1;
227 const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar
228 if (pos != last_index)
229 std::swap(array(pos), array(last_index));
230 return array(pos);
231 }
232
235 {
236 ah_underflow_error_if(array.size() == 0) << "Random set is empty";
237
238 const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar
239 T ret_val = array.access(pos);
240 array.access(pos) = array.access(array.size() - 1);
241 array.cut(array.size() - 1);
242 return ret_val;
243 }
244
245 // pick() is like get() but without removing the item
246 T pick() const
247 {
248 ah_underflow_error_if(array.size() == 0) << "Random set is empty";
249
250 const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar
251 T ret_val = array.access(pos);
252 std::swap(array.access(pos), array.access(0));
253 return ret_val;
254 }
255
257 bool is_empty() const { return array.size() == 0; }
258
266 struct Iterator : public DynArray<T>
267 {
269 using Base::Base;
270 };
271
277 template <class Operation>
279 {
280 return array.traverse(operation);
281 }
282
284 template <class Operation>
286 {
287 return const_cast<Random_Set*>(this)->traverse(operation);
288 }
289
291 template <class Operation>
293 {
294 return traverse(operation);
295 }
296
298 template <class Operation>
300 {
301 return traverse(operation);
302 }
303};
304
305
314 template <typename T, template <typename> class C>
315auto shuffle(const C<T> & c)
316{
318 c.for_each([&q] (const T & item) { q.put(&const_cast<T&>(item)); });
319
320 C<T> ret;
321 while (not q.is_empty())
322 ret.append(*q.get());
323
324 return ret;
325}
326
327
335 template <typename T, template <typename> class C>
337{
339 c.for_each([&q] (const T & item) { q.put(&const_cast<T&>(item)); });
340
341 C<T*> ret;
342 while (not q.is_empty())
343 ret.append(q.get());
344
345 return ret;
346}
347
348} // end namespace Aleph
349
350# endif // TPL_RANDOM_QUEUE_H
351
Container traversal and functional operation mixins.
Exception handling system with formatted messages for Aleph-w.
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
Definition ah-errors.H:429
Iterator on the items of array.
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
bool traverse(Operation &operation)
Conditional traversing of the random queue.
Random_Set(Random_Set &&s) noexcept
Move constructor.
gsl_rng * get_rng() const
The type of data contained in the queue.
void put(const T &item)
Insert an item by copy.
Random_Set(It b, It e)
Initialize the random queue with the items between b and e where these parameters are stl iterators.
bool traverse(Operation &operation) const
void set_seed(unsigned long seed) const noexcept
Set the seed of random number generator.
bool traverse(Operation &&operation=Operation())
Random_Set & operator=(const Random_Set &s)
bool is_empty() const
Return true if the queue is empty.
T Item_Type
The type of set.
T get()
Extract randomly an item.
T & append(T &&item)
Insert randomly an item by moving.
void put(T &&item)
Insert an item by moving.
DynArray< T > array
Random_Set(const Random_Set &s)
Copy constructor.
T & append(const T &item)
Insert randomly an item by copy.
bool traverse(Operation &&operation=Operation()) const
void swap(Random_Set &s)
Swap in constant time this with s
Random_Set(const DynList< T > &l)
Initialize the random queue with the elements of l
Random_Set(std::initializer_list< T > l)
Initialize the random queue with the items of l
size_t size() const
Return the number of items in the queue.
Equality test for containers.
Definition ah-dry.H:1534
Common methods to the Aleph-w ( ) containers.
Definition ah-dry.H:548
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Definition ah-dry.H:685
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:904
Common sequential searching methods on containers.
Definition ah-dry.H:164
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
C< T * > shuffle_ptr(const C< T > &c)
Return a random sequence of pointers to items of a sequence.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
auto shuffle(const C< T > &c)
Randomly shuffle a sequence.
DynList< T > maps(const C &c, Op op)
Classic map operation.
Generic list of items stored in a container.
Definition ah-dry.H:1501
Lazy and scalable dynamic array implementation.
DynList< int > l