3 #include "random-var.h"
7 random_var::random_var(int c
)
14 random_var::random_var(int s
, int e
, weight_func w
)
21 random_var::random_var(int s
, int e
, std::vector
<int> ws
)
22 : start(s
), end(e
), weights(ws
)
24 ASSERT(weights
.size() == static_cast<unsigned int>(end
- start
));
28 const random_var
& random_var::operator=(const random_var
& other
)
33 weights
= other
.weights
;
37 int random_var::weight(int val
) const
39 if (val
< start
|| val
>= end
)
41 return (weights
[val
- start
]);
44 void random_var::init_weights(weight_func w
)
46 ASSERT(weights
.empty());
47 for (int v
= start
; v
< end
; ++v
)
48 weights
.push_back(w
? (*w
)(v
) : 1);
51 void random_var::init()
54 for (int v
= start
; v
< end
; ++v
)
57 ASSERT(weight(start
) > 0 && weight(end
- 1) > 0);
60 int random_var::roll2val(int r
) const
62 ASSERT(0 <= r
&& r
< total
);
73 int random_var::roll() const
75 return (roll2val(random2(total
)));
78 int random_var::max() const
83 int random_var::min() const
88 double random_var::expected() const
91 for (int i
= start
; i
< end
; ++i
)
92 ev
+= i
* weight(i
) / (double)total
;
97 //////////////////////////////////
99 random_var
constant(int n
)
101 return (random_var(n
));
104 random_var
operator+(const random_var
& x
, const random_var
& y
)
106 const int start
= x
.min() + y
.min();
107 const int end
= x
.max() + y
.max() + 1;
108 std::vector
<int> weights(end
- start
, 0);
110 for (int vx
= x
.min(); vx
<= x
.max(); ++vx
)
111 for (int vy
= y
.min(); vy
<= y
.max(); ++vy
)
112 weights
[vx
+ vy
- start
] += x
.weight(vx
) * y
.weight(vy
);
114 return (random_var(start
, end
, weights
));
117 random_var
negate(const random_var
& x
)
119 const int start
= -x
.max();
120 const int end
= -x
.min() + 1;
121 std::vector
<int> weights(end
- start
, 0);
123 for (int v
= x
.min(); v
<= x
.max(); ++v
)
124 weights
[-v
- start
] = x
.weight(v
);
126 return (random_var(start
, end
, weights
));
129 random_var
operator-(const random_var
& x
, const random_var
& y
)
131 return (x
+ negate(y
));
134 const random_var
& operator+=(random_var
& x
, const random_var
& y
)
140 const random_var
& operator-=(random_var
& x
, const random_var
& y
)
146 random_var
operator/(const random_var
& x
, int d
)
148 const int start
= x
.min() / d
;
149 const int end
= x
.max() / d
+ 1;
150 std::vector
<int> weights(end
- start
, 0);
152 for (int v
= x
.min(); v
<= x
.max(); ++v
)
153 weights
[v
/2 - start
] += x
.weight(v
);
155 return (random_var(start
, end
, weights
));
158 random_var
rv::max(const random_var
& x
, const random_var
& y
)
160 const int start
= std::max(x
.min(), y
.min());
161 const int end
= std::max(x
.max(), y
.max()) + 1;
162 std::vector
<int> weights(end
- start
, 0);
164 for (int vx
= x
.min(); vx
<= x
.max(); ++vx
)
165 for (int vy
= y
.min(); vy
<= y
.max(); ++vy
)
166 weights
[std::max(vx
, vy
) - start
] += x
.weight(vx
) * y
.weight(vy
);
168 return (random_var(start
, end
, weights
));
171 random_var
rv::min(const random_var
& x
, const random_var
& y
)
173 const int start
= std::min(x
.min(), y
.min());
174 const int end
= std::min(x
.max(), y
.max()) + 1;
175 std::vector
<int> weights(end
- start
, 0);
177 for (int vx
= x
.min(); vx
<= x
.max(); ++vx
)
178 for (int vy
= y
.min(); vy
<= y
.max(); ++vy
)
179 weights
[std::min(vx
, vy
) - start
] += x
.weight(vx
) * y
.weight(vy
);
181 return (random_var(start
, end
, weights
));
184 random_var
rv::roll_dice(int d
, int n
)
187 return (constant(0));
188 random_var x
= constant(0);
189 for (int i
= 0; i
< d
; ++i
)
190 x
+= random_var(1, n
+1);
194 random_var
rv::random2(int n
)
196 return (random_var(0, std::max(n
, 1)));