-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathWeightedDiscretePDF.h
59 lines (48 loc) · 1.42 KB
/
WeightedDiscretePDF.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// $Id: WeightedDiscretePDF.h,v 1.4 2006/07/07 05:54:31 zr Exp $
template <class T>
class WDPDF_Node
{
private:
bool m_mark;
public:
WDPDF_Node<T> *parent, *left, *right;
T key;
float weight, sumWeights;
public:
WDPDF_Node(T key_, float weight_, WDPDF_Node<T> *parent_);
~WDPDF_Node();
WDPDF_Node<T> *sibling() { return this==parent->left?parent->right:parent->left; }
void markRed() { m_mark = true; }
void markBlack() { m_mark = false; }
bool isRed() { return m_mark; }
bool isBlack() { return !m_mark; }
bool leftIsBlack() { return !left || left->isBlack(); }
bool rightIsBlack() { return !right || right->isBlack(); }
bool leftIsRed() { return !leftIsBlack(); }
bool rightIsRed() { return !rightIsBlack(); }
void setSum() { sumWeights = weight + (left?left->sumWeights:0) + (right?right->sumWeights:0); }
};
template <class T>
class WeightedDiscretePDF
{
private:
WDPDF_Node<T> *m_root;
public:
WeightedDiscretePDF();
~WeightedDiscretePDF();
void insert(T item, float weight);
void update(T item, float newWeight);
void remove(T item);
bool inTree(T item);
/* pick a tree element according to its
* weight. p should be in [0,1).
*/
T choose(float p);
private:
WDPDF_Node<T> **lookup(T item, WDPDF_Node<T> **parent_out);
void split(WDPDF_Node<T> *node);
void rotate(WDPDF_Node<T> *node);
void lengthen(WDPDF_Node<T> *node);
void propogateSumsUp(WDPDF_Node<T> *n);
};
#include "WeightedDiscretePDF.cpp"