-
Notifications
You must be signed in to change notification settings - Fork 0
/
pRandom.cc
executable file
·183 lines (136 loc) · 3.44 KB
/
pRandom.cc
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
pRandom.c
- implementation file for C++ class pRandom
class pRandom
- provides a Genetic Algorithm oriented interface to the
random number generator of GNU C++
L. Weaver May 16, 1995
This version: @(#)pRandom.c 1.6 10 Jun 1995
*/
#include <sys/time.h>
#include <stdlib.h>
#include <assert.h>
#include "ACG.h"
#include <iostream>
#include "pRandom.h"
#define ACG_RANDMAX 4294967295
pRandom Random;
pRandom::pRandom()
{
generator=NULL;
mutation_clock = 0;
mutation_prob = 0.0;
autoseed();
}
pRandom::~pRandom()
{
delete generator;
}
int pRandom::True(float p)
// returns TRUE with probability p
{
return (generator->asLong()<=(long unsigned int)
(p*(double)ACG_RANDMAX));
}
int pRandom::uniform_int(int lower_bound, int upper_bound)
// returns each integer in [lower_bound,upper_bound] with equal probability
{
register double range = (double) (upper_bound-lower_bound+1);
return lower_bound +
(int)(
range*
((double)(generator->asLong())/
(1.0+(double)ACG_RANDMAX))
);
}
float pRandom::uniform_float(float lower_bound, float upper_bound)
// returns all values in [lower_bound,upper_bound) with equal probability
{
register double range = (double) (upper_bound-lower_bound);
return lower_bound +
(
range*
((double)(generator->asLong())
/(1.0+(double)ACG_RANDMAX))
);
}
int pRandom::exp_int(int base, float p)
// returns an integer x >= base, with prob (1-p)^(x-base)*p
{
// this method is probably far from efficient, but is a working
// placeholder
// while(1) {
// if (True(p))
// return base;
// else
// base++;
// }
// a far faster implementation than the previous method
double p1 = (double)p;
double total = p1;
double randval = (double) uniform_float(0.0,1.0);
while(total<randval){
base++;
total += (1.0-total)*p1;
}
return base;
}
int pRandom::bytes_at(void *addr, int num_bytes)
// generate num_bytes random bytes, placing them at addr
{
int i;
long num;
char *base = (char *)addr;
for(i=0;i<num_bytes;i++) {
num = generator->asLong();
(*base) = *(char *)#
base++;
}
return num_bytes;
}
float pRandom::set_mutation_rate(float p)
// set the probability of mutation
// must be done BEFORE mutation() is first called
{
assert(p>=0.0);
mutation_clock = exp_int(1,p);
return (mutation_prob=p);
}
int pRandom::mutation()
// returns TRUE (1) with probability mutation_rate, as set by
// set_mutation_rate() which must be called before this function is first called
// works by setting mutation_clock (via exp_int()) to a randomly determined
// number of ticks(calls to mutation()) which should occur before the next
// TRUE is returned. When this ticks expire, a new number of ticks is
// determined and TRUE returned
// - this is much faster than generating a random number each time
// to check if mutation should occur
{
if ((--mutation_clock)==0) {
// time for a mutation
// reset clock for the next one
mutation_clock = (long unsigned int) exp_int(1,mutation_prob);
return 1;
} else {
// not yet time for a mutation
return 0;
}
}
int pRandom::seed(int new_seed)
// change generators to one seeded with new_seed
{
lastseed = new_seed;
if (generator!=NULL)
delete generator;
generator = new ACG(lastseed);
return lastseed;
}
int pRandom::autoseed()
// change to a generator seeded automatically by the system
{
lastseed = (unsigned int)(time(0));
if (generator!=NULL)
delete generator;
generator = new ACG(lastseed);
return lastseed;
}