00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_RAND_TREE_H
00045 # define TPL_RAND_TREE_H
00046
00047 # include <limits.h>
00048 # include <gsl/gsl_rng.h>
00049 # include <ahUtils.H>
00050 # include <ahFunction.H>
00051 # include <tpl_randNode.H>
00052 # include <tpl_binNodeUtils.H>
00053
00054 using namespace Aleph;
00055
00056 namespace Aleph {
00057
00077 template <template <typename> class NodeType, typename Key, class Compare>
00078 class Gen_Rand_Tree
00079 {
00080
00081 public:
00082
00084 typedef NodeType<Key> Node;
00085
00086 private:
00087
00088 Node * tree_root;
00089 gsl_rng * r;
00090 Gen_Rand_Tree(const Gen_Rand_Tree&);
00091
00092 Gen_Rand_Tree& operator = (const Gen_Rand_Tree&);
00093
00094 public:
00095
00097 gsl_rng * gsl_rng_object() { return r;}
00100 Gen_Rand_Tree() : tree_root(Node::NullPtr), r(NULL)
00101 {
00102 r = gsl_rng_alloc (gsl_rng_mt19937);
00103
00104 if (r == NULL)
00105 throw std::bad_alloc();
00106
00107 gsl_rng_set(r, time(NULL) % gsl_rng_max(r));
00108 }
00109
00111 virtual ~Gen_Rand_Tree()
00112 {
00113 if (r != NULL)
00114 gsl_rng_free(r);
00115 }
00139 Node * random_insert(Node * root, Node * node)
00140 {
00141 if (root == Node::NullPtr)
00142 return node;
00143
00144 const long & n = COUNT(root);
00145
00146 const size_t rn = gsl_rng_uniform_int(r, n + 1);;
00147
00148 if (rn == n)
00149 return insert_root_xt<Node, Compare> (root, node);
00150
00151 Node * result;
00152 if (Compare() (KEY(node), KEY(root)))
00153 {
00154 result = random_insert(LLINK(root), node);
00155
00156 if (result != Node::NullPtr)
00157 {
00158 LLINK(root) = result;
00159 ++COUNT(root);
00160 }
00161 }
00162 else if (Compare() (KEY(root), KEY(node)))
00163 {
00164 result = random_insert(RLINK(root), node);
00165
00166 if (result != Node::NullPtr)
00167 {
00168 RLINK(root) = result;
00169 ++COUNT(root);
00170 }
00171 }
00172 else
00173 return Node::NullPtr;
00174
00175 return root;
00176 }
00186 Node * insert(Node * p)
00187 {
00188
00189 I(p != Node::NullPtr);
00190 I((LLINK(p) == Node::NullPtr) and (RLINK(p) == Node::NullPtr));
00191 I(COUNT(p) == 1);
00192
00193 Node * result = random_insert(tree_root, p);
00194
00195 if (result == Node::NullPtr)
00196 return NULL;
00197
00198 tree_root = result;
00199
00200 return p;
00201 }
00227 Node * random_join_exclusive(Node * tl, Node * tr)
00228 {
00229 if (tl == Node::NullPtr)
00230 return tr;
00231
00232 if (tr == Node::NullPtr)
00233 return tl;
00234
00235 const size_t & m = COUNT(tl);
00236 const size_t & n = COUNT(tr);
00237
00238 const size_t rn = 1 + gsl_rng_uniform_int(r, m + n);
00239
00240 if (rn <= m)
00241 {
00242 COUNT(tl) += COUNT(tr);
00243 RLINK(tl) = random_join_exclusive(RLINK(tl), tr);
00244
00245 return tl;
00246 }
00247 else
00248 {
00249 COUNT(tr) += COUNT(tl);
00250 LLINK(tr) = random_join_exclusive(tl, LLINK(tr));
00251
00252 return tr;
00253 }
00254 }
00278 Node * random_remove(Node *& root, const Key & key)
00279 {
00280 if (root == Node::NullPtr)
00281 return Node::NullPtr;
00282
00283 Node * ret_val;
00284
00285 if (Compare() (key, KEY(root)))
00286 {
00287 ret_val = random_remove(LLINK(root), key);
00288
00289 if (ret_val != Node::NullPtr)
00290 COUNT(root)--;
00291
00292 return ret_val;
00293 }
00294 else if (Compare() (KEY(root), key))
00295 {
00296 ret_val = random_remove(RLINK(root), key);
00297
00298 if (ret_val != Node::NullPtr)
00299 COUNT(root)--;
00300
00301 return ret_val;
00302 }
00303
00304
00305 ret_val = root;
00306 root = random_join_exclusive(LLINK(root), RLINK(root));
00307 ret_val->reset();
00308
00309 return ret_val;
00310 }
00322 Node * remove(const Key & key)
00323 {
00324 Node * ret_val = random_remove(tree_root, key);
00325
00326 return ret_val != Node::NullPtr ? ret_val : NULL;
00327 }
00329 Node * search(const Key & key)
00330 {
00331 Node * retVal = searchInBinTree<Node, Compare>(tree_root, key);
00332
00333 return retVal == Node::NullPtr ? NULL : retVal;
00334 }
00335
00338 Node *& getRoot() { return tree_root; }
00339
00340 };
00341
00362 template <typename Key, class Compare = Aleph::less<Key> >
00363 class Rand_Tree : public Gen_Rand_Tree<RandNode, Key, Compare>
00364 { };
00365
00386 template <typename Key, class Compare = Aleph::less<Key> >
00387 class Rand_Tree_Vtl : public Gen_Rand_Tree<RandNodeVtl, Key, Compare>
00388 { };
00389
00390 }
00391
00392 # endif // TPL_RAND_TREE_H
00393