Aleph-w  1.9
General library for algorithms and data structures
tpl_random_queue.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 
28 # ifndef TPL_RANDOM_QUEUE_H
29 # define TPL_RANDOM_QUEUE_H
30 
31 # include <gsl/gsl_rng.h>
32 # include <htlist.H>
33 # include <ah-dry.H>
34 # include <tpl_dynArray.H>
35 
36 namespace Aleph {
37 
50  template <class T>
52  : public LocateFunctions<Random_Set<T>, T>,
53  public FunctionalMethods<Random_Set<T>, T>,
54  public GenericKeys<Random_Set<T>, T>,
55  public EqualToMethod<Random_Set<T>>,
56  public StlAlephIterator<Random_Set<T>>
57 {
58 private:
59 
60  DynArray<T> array;
61  gsl_rng * r = nullptr;
62 
63 public:
64 
65  using Set_Type = Random_Set;
66 
67  using Item_Type = T;
68 
70  gsl_rng * get_rng() const { return r; }
71 
73  void set_seed(unsigned long seed) noexcept { gsl_rng_set(r, seed); }
74 
76  size_t size() const { return array.size(); }
77 
78  Random_Set() : array(0), r(nullptr)
79  {
80  r = gsl_rng_alloc (gsl_rng_mt19937);
81  if (r == nullptr)
82  throw std::bad_alloc();
83 
84  gsl_rng_set(r, time(nullptr) % gsl_rng_max(r));
85  }
86 
88  void swap(Random_Set & s)
89  {
90  array.swap(s.array);
91  std::swap(r, s.r);
92  }
93 
96  {
97  s.for_each([this] (auto item) { this->append(item); });
98  }
99 
101  Random_Set(Random_Set && s) { swap(s); }
102 
103  Random_Set & operator = (const Random_Set & s)
104  {
105  if (this == &s)
106  return *this;
107 
108  if (s.size() > size())
109  array.reserve(s.size());
110  else
111  array.cut(s.size);
112  s.for_each([this] (auto item) { this->append(item); });
113 
114  return *this;
115  }
116 
117  Random_Set & operator = (Random_Set && s)
118  {
119  swap(s);
120  return *this;
121  }
122 
125  {
126  l.for_each([this] (const T & item) { append(item); });
127  }
128 
131  template <class It> Random_Set(It b, It e) : Random_Set()
132  {
133  for (It it = b; it != e; ++it)
134  append(*it);
135  }
136 
138  Random_Set(std::initializer_list<T> l) : Random_Set()
139  {
140  for (const auto & item : l)
141  append(item);
142  }
143 
144  ~Random_Set()
145  {
146  if (r != nullptr)
147  gsl_rng_free(r);
148  }
149 
159  void put(const T & item) { array.append(item); }
160 
161 
171  void put(T && item) { array.append(std::forward<T>(item)); }
172 
182  void append(const T & item)
183  {
184  put(item);
185  auto pos = gsl_rng_uniform_int(r, array.size()); // al azar
186  std::swap(array(pos), array(array.size() - 1));
187  }
188 
198  void append(T && item)
199  {
200  put(move(item));
201  auto pos = gsl_rng_uniform_int(r, array.size()); // al azar
202  std::swap(array(pos), array(array.size() - 1));
203  }
204 
206  T get()
207  {
208  if (array.size() == 0)
209  throw std::underflow_error("Random set is empty");
210 
211  const size_t pos = gsl_rng_uniform_int(r, array.size()); // al azar
212  T ret_val = array.access(pos);
213  array.access(pos) = array.access(array.size() - 1);
214  array.cut(array.size() - 1);
215  return ret_val;
216  }
217 
219  bool is_empty() const { return array.size() == 0; }
220 
228  struct Iterator : public DynArray<T>
229  {
230  using Base = DynArray<T>;
231  using Base::Base;
232  };
233 
239  template <class Operation>
240  bool traverse(Operation & operation)
241  noexcept(noexcept(array.traverse(operation)))
242  {
243  return array.traverse(operation);
244  }
245 
247  template <class Operation>
248  bool traverse(Operation & operation) const noexcept(noexcept(operation))
249  {
250  return const_cast<Random_Set*>(this)->traverse(operation);
251  }
252 
254  template <class Operation>
255  bool traverse(Operation && operation = Operation()) const
256  noexcept(noexcept(operation))
257  {
258  return traverse(operation);
259  }
260 
262  template <class Operation>
263  bool traverse(Operation && operation = Operation())
264  noexcept(noexcept(operation))
265  {
266  return traverse(operation);
267  }
268 };
269 
270 
279  template <typename T, template <typename> class C>
280 auto shuffle(const C<T> & c)
281 {
282  Random_Set<T*> q;
283  c.for_each([&q] (const T & item) { q.put(&const_cast<T&>(item)); });
284 
285  C<T> ret;
286  while (not q.is_empty())
287  ret.append(*q.get());
288 
289  return ret;
290 }
291 
292 
300  template <typename T, template <typename> class C>
301 C<T*> shuffle_ptr(const C<T> & c)
302 {
303  Random_Set<T*> q;
304  c.for_each([&q] (const T & item) { q.put(&const_cast<T&>(item)); });
305 
306  C<T*> ret;
307  while (not q.is_empty())
308  ret.append(q.get());
309 
310  return ret;
311 }
312 
313 } // end namespace Aleph
314 
315 # endif // TPL_RANDOM_QUEUE_H
316 
C< T * > shuffle_ptr(const C< T > &c)
Definition: tpl_random_queue.H:301
Definition: htlist.H:450
Definition: htlist.H:1290
void reserve(const size_t l, const size_t r)
Definition: tpl_dynArray.H:998
void put(const T &item)
Definition: tpl_random_queue.H:159
size_t size() const
Return the number of items inthe queue.
Definition: tpl_random_queue.H:76
Definition: htlist.H:133
void append(const T &item)
Definition: tpl_random_queue.H:182
void cut(const size_t new_dim=0)
Definition: tpl_dynArray.H:1104
Random_Set(Random_Set &&s)
Move constructor.
Definition: tpl_random_queue.H:101
auto shuffle(const C< T > &c)
Definition: tpl_random_queue.H:280
void append(T &&item)
Definition: tpl_random_queue.H:198
gsl_rng * get_rng() const
The type of data contained in the queue.
Definition: tpl_random_queue.H:70
Random_Set(It b, It e)
Definition: tpl_random_queue.H:131
T & access(const size_t i) const noexcept
Definition: tpl_dynArray.H:874
void for_each(Operation &operation) noexcept(noexcept(operation))
Definition: htlist.H:589
Random_Set(const DynList< T > &l)
Initialize the random queue with the elements of l
Definition: tpl_random_queue.H:124
bool traverse(Operation &operation) const noexcept(noexcept(operation))
Definition: tpl_random_queue.H:248
void swap(DynArray< T > &array) noexcept
Definition: tpl_dynArray.H:819
Random_Set(const Random_Set &s)
Copy constrcutor.
Definition: tpl_random_queue.H:95
Definition: ah-comb.H:35
bool traverse(Operation &operation) noexcept(noexcept(array.traverse(operation)))
Definition: tpl_random_queue.H:240
bool traverse(Operation &operation) const noexcept(noexcept(operation))
Definition: tpl_dynArray.H:1379
Definition: tpl_random_queue.H:51
void put(T &&item)
Definition: tpl_random_queue.H:171
void set_seed(unsigned long seed) noexcept
Set the seed of ramdom number generator.
Definition: tpl_random_queue.H:73
T get()
Extract randomly an item.
Definition: tpl_random_queue.H:206
T & append()
Definition: tpl_dynArray.H:1149
Random_Set(std::initializer_list< T > l)
Initialize the random queue with the items of l
Definition: tpl_random_queue.H:138
size_t size() const noexcept
Definition: tpl_dynArray.H:641
Definition: tpl_dynArray.H:159
void swap(Random_Set &s)
Swap in constant time this with s
Definition: tpl_random_queue.H:88
Definition: ahDry.H:41
bool traverse(Operation &&operation=Operation()) noexcept(noexcept(operation))
Definition: tpl_random_queue.H:263
Definition: tpl_dynArray.H:1258
bool is_empty() const
Return true if the queue is empty.
Definition: tpl_random_queue.H:219
T Item_Type
The type of set.
Definition: tpl_random_queue.H:67
Definition: htlist.H:1323
bool traverse(Operation &&operation=Operation()) const noexcept(noexcept(operation))
Definition: tpl_random_queue.H:255

Leandro Rabindranath León