00001
00002
00003 template <class T>
00004 class WDPDF_Node
00005 {
00006 private:
00007 bool m_mark;
00008
00009 public:
00010 WDPDF_Node<T> *parent, *left, *right;
00011 T key;
00012 float weight, sumWeights;
00013
00014 public:
00015 WDPDF_Node(T key_, float weight_, WDPDF_Node<T> *parent_);
00016 ~WDPDF_Node();
00017
00018 WDPDF_Node<T> *sibling() { return this==parent->left?parent->right:parent->left; }
00019
00020 void markRed() { m_mark = true; }
00021 void markBlack() { m_mark = false; }
00022 bool isRed() { return m_mark; }
00023 bool isBlack() { return !m_mark; }
00024 bool leftIsBlack() { return !left || left->isBlack(); }
00025 bool rightIsBlack() { return !right || right->isBlack(); }
00026 bool leftIsRed() { return !leftIsBlack(); }
00027 bool rightIsRed() { return !rightIsBlack(); }
00028 void setSum() { sumWeights = weight + (left?left->sumWeights:0) + (right?right->sumWeights:0); }
00029 };
00030
00031 template <class T>
00032 class WeightedDiscretePDF
00033 {
00034 private:
00035 WDPDF_Node<T> *m_root;
00036
00037 public:
00038 WeightedDiscretePDF();
00039 ~WeightedDiscretePDF();
00040
00041 void insert(T item, float weight);
00042 void update(T item, float newWeight);
00043 void remove(T item);
00044 bool inTree(T item);
00045
00046
00047
00048
00049 T choose(float p);
00050
00051 private:
00052 WDPDF_Node<T> **lookup(T item, WDPDF_Node<T> **parent_out);
00053 void split(WDPDF_Node<T> *node);
00054 void rotate(WDPDF_Node<T> *node);
00055 void lengthen(WDPDF_Node<T> *node);
00056 void propogateSumsUp(WDPDF_Node<T> *n);
00057 };
00058
00059 #include "WeightedDiscretePDF.cpp"