Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_rand_tree.H
1 
2 # ifndef TPL_RAND_TREE_H
3 # define TPL_RAND_TREE_H
4 
5 # include <limits.h>
6 # include <gsl/gsl_rng.h>
7 # include <ahUtils.H>
8 # include <ahFunction.H>
9 # include <tpl_randNode.H>
10 # include <tpl_binTreeOps.H>
11 
12 using namespace Aleph;
13 
14 namespace Aleph {
15 
35  template <template <typename> class NodeType, typename Key, class Compare>
37 {
38 public:
39 
41  typedef NodeType<Key> Node;
42 
43 private:
44 
45  Node * tree_root;
46  gsl_rng * r;
47  Compare & cmp;
48 
72  Node * random_insert(Node * root, Node * p)
73  {
74  const long & n = COUNT(root);
75  const size_t rn = gsl_rng_uniform_int(r, n + 1);
76  if (rn == n) // ¿Gana p el sorteo de ser raíz?
78 
79  Node * result;
80  if (cmp(KEY(p), KEY(root))) // KEY(p) < KEY(root) ?
81  { // sí ==> insertar en árbol izquierdo
82  result = random_insert(LLINK(root), p);
83  if (result != Node::NullPtr) // ¿hubo inserción?
84  { // si ==> actualizar rama y contadores
85  LLINK(root) = result;
86  ++COUNT(root);
87 
88  return root;
89  }
90  }
91  else if (cmp(KEY(root), KEY(p))) // KEY(p) > KEY(root) ?
92  { // insertar en árbol derecho
93  result = random_insert(RLINK(root), p);
94  if (result != Node::NullPtr) // ¿hubo inserción?
95  { // si ==> actualizar rama y contadores
96  RLINK(root) = result;
97  ++COUNT(root);
98 
99  return root;
100  }
101  }
102 
103  return Node::NullPtr; // clave duplicada ==> no hay inserción
104  }
105 
127  Node * random_insert_dup(Node * root, Node * p)
128  {
129  const long & n = COUNT(root);
130  const size_t rn = gsl_rng_uniform_int(r, n + 1);
131  if (rn == n) // ¿Gana p el sorteo de ser raíz?
133 
134  if (cmp(KEY(p), KEY(root))) // KEY(p) < KEY(root) ?
135  LLINK(root) = random_insert_dup(LLINK(root), p);
136  else
137  RLINK(root) = random_insert_dup(RLINK(root), p);
138 
139  ++COUNT(root);
140 
141  return root;
142  }
143 
144  Gen_Rand_Tree& operator = (const Gen_Rand_Tree&);
145 
146  void init(unsigned int seed)
147  {
148  r = gsl_rng_alloc (gsl_rng_mt19937);
149 
150  if (r == NULL)
151  throw std::bad_alloc();
152 
153  gsl_rng_set(r, seed % gsl_rng_max(r));
154  }
155 
156 public:
157 
159  Compare & key_comp() { return cmp; }
160 
162  Compare & get_compare() { return key_comp(); }
163 
164 
166  gsl_rng * gsl_rng_object() { return r;}
167 
170  Gen_Rand_Tree(unsigned int seed, Compare && __cmp)
171  : tree_root(Node::NullPtr), r(NULL), cmp(__cmp)
172  {
173  init(seed);
174  }
175 
176  Gen_Rand_Tree(unsigned int seed, Compare & __cmp)
177  : tree_root(Node::NullPtr), r(NULL), cmp(__cmp)
178  {
179  init(seed);
180  }
181 
187  void swap(Gen_Rand_Tree & tree)
188  {
189  std::swap(tree_root, tree.tree_root);
190  std::swap(r, tree.r);
191  std::swap(cmp, tree.cmp);
192  }
193 
194 
196  virtual ~Gen_Rand_Tree()
197  {
198  if (r != NULL)
199  gsl_rng_free(r);
200  }
201 
211  Node * insert(Node * p)
212  {
213 
214  I(p != Node::NullPtr);
215  I((LLINK(p) == Node::NullPtr) and (RLINK(p) == Node::NullPtr));
216  I(COUNT(p) == 1);
217 
218  Node * result = random_insert(tree_root, p);
219  if (result == Node::NullPtr)
220  return NULL;
221 
222  return tree_root = result;
223  }
224 
235  {
236  I(p != Node::NullPtr);
237  I((LLINK(p) == Node::NullPtr) and (RLINK(p) == Node::NullPtr));
238  I(COUNT(p) == 1);
239 
240  return tree_root = random_insert_dup(tree_root, p);
241  }
242 
269  {
270  if (tl == Node::NullPtr)
271  return tr;
272 
273  if (tr == Node::NullPtr)
274  return tl;
275 
276  const size_t & m = COUNT(tl);
277  const size_t & n = COUNT(tr);
278  const size_t rn = 1 + gsl_rng_uniform_int(r, m + n);
279  if (rn <= m)
280  { // rama izquierda gana sorteo
281  COUNT(tl) += COUNT(tr);
282  RLINK(tl) = random_join_exclusive(RLINK(tl), tr);
283 
284  return tl;
285  }
286  else
287  {
288  COUNT(tr) += COUNT(tl);
289  LLINK(tr) = random_join_exclusive(tl, LLINK(tr));
290 
291  return tr;
292  }
293  }
294 
318  Node * random_remove(Node *& root, const Key & key)
319  {
320  if (root == Node::NullPtr)
321  return Node::NullPtr;
322 
323  Node * ret_val;
324  if (cmp(key, KEY(root)))
325  {
326  ret_val = random_remove(LLINK(root), key);
327  if (ret_val != Node::NullPtr)
328  COUNT(root)--;
329 
330  return ret_val;
331  }
332  else if (cmp(KEY(root), key))
333  {
334  ret_val = random_remove(RLINK(root), key);
335  if (ret_val != Node::NullPtr)
336  COUNT(root)--;
337 
338  return ret_val;
339  }
340 
341  // clave encontrada
342  ret_val = root;
343  root = random_join_exclusive(LLINK(root), RLINK(root));
344  ret_val->reset();
345 
346  return ret_val;
347  }
359  Node * remove(const Key & key)
360  {
361  Node * ret_val = random_remove(tree_root, key);
362 
363  return ret_val != Node::NullPtr ? ret_val : NULL;
364  }
366  Node * search(const Key & key)
367  {
368  Node * retVal = searchInBinTree<Node, Compare>(tree_root, key, cmp);
369 
370  return retVal == Node::NullPtr ? NULL : retVal;
371  }
372 
388  {
389  I(p != Node::NullPtr);
390  I(COUNT(p) == 1);
391 
392  Node * result = search(KEY(p));
393  if (result != NULL)
394  return result;
395 
396  tree_root = random_insert(tree_root, p);
397 
398  return p;
399  }
400 
401  bool verify() const
402  {
403  return check_rank_tree(tree_root);
404  }
405 
408  Node *& getRoot() { return tree_root; }
409 
420  Node * select(const size_t & i) const
421  {
422  return Aleph::select(tree_root, i);
423  }
424 
426  size_t size() const { return COUNT(tree_root); }
427 
440  std::pair<int,Node*> position(const Key & key)
441  {
442  std::pair<int,Node*> ret_val;
443  ret_val.first = BinTreeXt_Operation<Node, Compare> (cmp).
444  inorder_position(tree_root, key, ret_val.second);
445 
446  IG(KEY(ret_val.second) == key, ret_val.first >= 0);
447 
448  return ret_val;
449  }
450 
481  std::pair<int,Node*> find_position(const Key & key)
482  {
483  std::pair<int,Node*> r(-2, NULL);
484 
485  r.first = BinTreeXt_Operation<Node, Compare> (cmp) .
486  find_position(tree_root, key, r.second);
487 
488  return r;
489  }
490 
491  bool split_key(const Key & key, Gen_Rand_Tree & t1, Gen_Rand_Tree & t2)
492  {
493  return split_key_rec_xt(tree_root, key, t1, t2);
494  }
495 
496  bool split_key_dup(const Key & key, Gen_Rand_Tree & t1, Gen_Rand_Tree & t2)
497  {
498  split_key_dup_rec_xt(tree_root, key, t1, t2);
499  }
500 
501  void split_pos(size_t pos, Gen_Rand_Tree & t1, Gen_Rand_Tree & t2)
502  {
503  split_pos_rec(tree_root, pos, t1, t2);
504  }
505 
506  void join(Gen_Rand_Tree & t, Gen_Rand_Tree & dup)
507  {
508  Node * l = (Node*) LLINK(t.tree_root);
509  Node * r = (Node*) RLINK(t.tree_root);
510 
511  t.tree_root->reset();
512  Node * ret = insert(t.tree_root);
513  if (ret == NULL)
514  dup.insert(t.tree_root);
515 
516  join(l, dup);
517  join(r, dup);
518  }
519 
520  void join_dup(Gen_Rand_Tree & t)
521  {
522  tree_root = random_join_exclusive(tree_root, t.tree_root);
523  }
524 };
525 
546  template <typename Key, class Compare = Aleph::less<Key>>
547 class Rand_Tree : public Gen_Rand_Tree<RandNode, Key, Compare>
548 {
549 public:
550 
553  Rand_Tree(unsigned int seed, Compare && cmp = Compare())
554  : Gen_Rand_Tree<RandNode, Key, Compare>(seed, std::move(cmp))
555  {
556  // empty
557  }
558 
559  Rand_Tree(Compare && cmp = Compare())
560  : Gen_Rand_Tree<RandNode, Key, Compare>(time(NULL), std::move(cmp))
561  {
562  // empty
563  }
564 
565  Rand_Tree(Compare & cmp)
566  : Gen_Rand_Tree<RandNode, Key, Compare>(time(NULL), cmp)
567  {
568  // empty
569  }
570 
571  Rand_Tree(unsigned int seed, Compare & cmp)
572  : Gen_Rand_Tree<RandNode, Key, Compare>(seed, cmp)
573  {
574  // empty
575  }
576 };
577 
598  template <typename Key, class Compare = Aleph::less<Key>>
599 class Rand_Tree_Vtl : public Gen_Rand_Tree<RandNodeVtl,Key,Compare>
600 {
601 public:
602 
605  Rand_Tree_Vtl(unsigned int seed, Compare && cmp = Compare())
606  : Gen_Rand_Tree<RandNodeVtl, Key, Compare>(seed, std::move(cmp))
607  {
608  // empty
609  }
610 
611  Rand_Tree_Vtl(Compare && cmp = Compare())
612  : Gen_Rand_Tree<RandNodeVtl, Key, Compare>(time(NULL), std::move(cmp))
613  {
614  // empty
615  }
616 
617  Rand_Tree_Vtl(unsigned int seed, Compare & cmp)
618  : Gen_Rand_Tree<RandNodeVtl, Key, Compare>(seed, cmp)
619  {
620  // empty
621  }
622 
623  Rand_Tree_Vtl(Compare & cmp)
624  : Gen_Rand_Tree<RandNodeVtl, Key, Compare>(time(NULL), std::move(cmp))
625  {
626  // empty
627  }
628 };
629 
630 
631 } // end namespace Aleph
632 
633 # endif // TPL_RAND_TREE_H
634 
Node * search_or_insert(Node *p)
Definition: tpl_rand_tree.H:387
#define LLINK(p)
Definition: tpl_binNode.H:196
Node * random_join_exclusive(Node *tl, Node *tr)
Definition: tpl_rand_tree.H:268
#define RLINK(p)
Definition: tpl_binNode.H:201
Node * search(const Key &key)
Busca la clave key en el árbol binario de búsqueda aleatorizado.
Definition: tpl_rand_tree.H:366
long inorder_position(Node *r, const typename Node::key_type &key, Node *&p)
Definition: tpl_binNodeXt.H:135
virtual ~Gen_Rand_Tree()
Destructor (libera generador de números aleatorios.
Definition: tpl_rand_tree.H:196
Node * insert_root(Node *&root, Node *p)
Definition: tpl_binNodeUtils.H:2236
Gen_Rand_Tree(unsigned int seed, Compare &&__cmp)
Definition: tpl_rand_tree.H:170
#define COUNT(p)
Definition: tpl_binNodeXt.H:34
void split_key_dup_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r)
Definition: tpl_binNodeXt.H:427
Definition: tpl_binTreeOps.H:632
Rand_Tree(unsigned int seed, Compare &&cmp=Compare())
Definition: tpl_rand_tree.H:553
NodeType< Key > Node
Tipo de nodo binario.
Definition: tpl_rand_tree.H:41
Node * insert_dup(Node *p)
Definition: tpl_rand_tree.H:234
Definition: tpl_rand_tree.H:599
Node * select(Node *r, const size_t &pos)
Definition: tpl_binNodeXt.H:89
Node * insert(Node *p)
Definition: tpl_rand_tree.H:211
Node * insert_dup_root(Node *&root, Node *p)
Definition: tpl_binNodeUtils.H:2274
Compare & get_compare()
Definition: tpl_rand_tree.H:162
gsl_rng * gsl_rng_object()
Obtiene un puntero al objeto gsl_rng generador de números aleatorios.
Definition: tpl_rand_tree.H:166
void swap(Gen_Rand_Tree &tree)
Definition: tpl_rand_tree.H:187
Definition: tpl_rand_tree.H:547
std::pair< int, Node * > position(const Key &key)
Definition: tpl_rand_tree.H:440
Node *& getRoot()
Definition: tpl_rand_tree.H:408
void split_pos_rec(Node *r, const size_t i, Node *&ts, Node *&tg)
Definition: tpl_binNodeXt.H:541
std::pair< int, Node * > find_position(const Key &key)
Definition: tpl_rand_tree.H:481
Node * select(const size_t &i) const
Definition: tpl_rand_tree.H:420
Node * random_remove(Node *&root, const Key &key)
Definition: tpl_rand_tree.H:318
bool split_key_rec_xt(Node *root, const typename Node::key_type &key, Node *&l, Node *&r)
Definition: tpl_binNodeXt.H:373
Rand_Tree_Vtl(unsigned int seed, Compare &&cmp=Compare())
Definition: tpl_rand_tree.H:605
#define KEY(p)
Definition: tpl_binNode.H:206
size_t size() const
Retorna la cantidad de nodos que contiene el árbol.
Definition: tpl_rand_tree.H:426
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_rand_tree.H:159
Definition: tpl_rand_tree.H:36

Leandro Rabindranath León