-
Notifications
You must be signed in to change notification settings - Fork 0
/
Random.hh
75 lines (56 loc) · 1.44 KB
/
Random.hh
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef Random_hh
#define Random_hh
#include "Utils.hh"
/**
* Defines a random generator used by Board, (Sec)Game and Player.
*/
class Random_generator {
friend class Board;
friend class Game;
friend class SecGame;
static const long long RANDOM_MOD = ((long long)1)<<31;
static const long long RANDOM_MASC = RANDOM_MOD - 1;
long long rnd_seed;
/**
* Sets random seed.
*/
void set_random_seed (int s) {
if (s < 0) s = -s;
rnd_seed = s&RANDOM_MASC;
}
/**
* Computes next seed from current seed.
*/
void next_rnd () {
rnd_seed = (843314861*rnd_seed + 453816693)&RANDOM_MASC;
}
/**
* Returns a real random number in [0, 1).
*/
double uniform () {
next_rnd();
return double(rnd_seed)/RANDOM_MOD;
}
public:
/**
* Returns a random integer in [l..u]. u - l + 1 must be between 1 and 10^6.
*/
int random (int l, int u) {
if (l > u) return l; // wrong interval
long long m = (long long)u - (long long)l + 1;
if (m > 1e6) return l; // interval too long
next_rnd();
return l + int((u - l + 1)*uniform());
}
/**
* Returns a random permutation of [0..n-1]. n must be between 0 and 10^6.
*/
inline vector<int> random_permutation (int n) {
if (n < 0 or n > 1e6) return vector<int>(0); // wrong n
vector<int> v(n);
for (int i = 0; i < n; ++i) v[i] = i;
for (int i = 0; i < n - 1; ++i) swap(v[i], v[random(i, n - 1)]);
return v;
}
};
#endif