1
2
3
4
5
6
7 def random_number
8 t = Time.now.to_f / (Time.now.to_f % Time.now.to_i)
9 random_seed = t * 1103515245 + 12345;
10 (random_seed / 65536) % 32768;
11 end
12
13 10.times { puts random_number }
14
15 cnt = Array.new(10,0)
16 20000.times { cnt[(random_number % 10).to_i] += 1 }
17 p cnt
18 puts
19
20
21
22
23
24
25 def gaussian_rand
26 u1 = u2 = w = g1 = g2 = 0
27 begin
28 u1 = 2 * rand - 1
29 u2 = 2 * rand - 1
30 w = u1 * u1 + u2 * u2
31 end while w >= 1
32
33 w = Math::sqrt( ( -2 * Math::log(w)) / w )
34 g2 = u1 * w;
35 g1 = u2 * w;
36
37 end
38
39 sum = 0
40 sumsq = 0
41 n = 1000
42 0.upto(n) do
43
44 r = gaussian_rand * 100 + 50
45
46 sum += r
47 sumsq += (r*r)
48 end
49
50 ave = sum/n
51 stddev = Math::sqrt(sumsq/n - ave * ave)
52 puts "Average = #{ave}"
53 puts "StdDev = #{stddev}"
54 puts
55
56
57
58
59
60
61
62 IM = 139968
63 IA = 3877
64 IC = 29573
65
66 $last = 42.0
67 def gen_random (max) (max * ($last = ($last * IA + IC) % IM)) / IM end
68
69 10.times do
70 puts gen_random(100000.0)
71 end
72
73 printf "%.5f\n", gen_random(100.0)
74 puts
75
76
77
78
79
80
81
82 def box_mueller( mean = 0.0, stddev = 1.0 )
83 x1 = 0.0, x2 = 0.0, w = 0.0
84
85 until w > 0.0 && w < 1.0
86 x1 = 2.0 * rand - 1.0
87 x2 = 2.0 * rand - 1.0
88 w = ( x1 * x2 ) + ( x2 * x2 )
89 end
90
91 w = Math.sqrt( -2.0 * Math.log( w ) / w )
92 r = x1 * w
93
94 mean + r * stddev
95 end
96
97 10.times { puts box_mueller(5.0, 1.0) }
98 puts
99
100
101
102
103
104
105 def gen
106 (x=rand)>0.5 ? x : (x < rand/2.0) ? 1.0 - x : x
107 end
108
109 def gen2
110 (x = rand) && rand ? 1.0 - x : x
111 end
112
113 def compute_distribution(numSamples, &block)
114 samples = []
115 values = 10
116 numSamples.times{samples << yield}
117 dist = Array.new(values, 0)
118 samples.each{ |s| dist[(s*values).floor] += 1 }
119 dist
120 end
121
122 p compute_distribution(1000){rand}
123 p compute_distribution(1000){gen}
124 p compute_distribution(1000) { gen2 }
125 puts
126
127
128
129
130
131
132 def rng(m, low, high)
133
134
135 return nil unless high > low && m > low && m < high
136
137 u = rand
138
139 if u <= (m-low)/(high-low)
140 r = low+ Math.sqrt(u*(high-low)*(m-low))
141 else
142 r = high - Math.sqrt((1.0-u)*(high-low)*(high-m))
143 end
144
145 end
146
147 10.times do
148
149 puts rng(50.0, 25.0, 75.0)
150 end
151 puts
152
153
154
155
156
157 class Range
158 def rand
159 return first if exclude_end? && last == first
160 Kernel::rand(last - first + (exclude_end? ? 0 : 1)) + first
161 end
162 end
163
164 r1 = -9..9
165 r2 = -90...100
166 p r1.rand, r2.rand
167
168 r3 = 0..9
169
170 num = []
171 10.times do
172 num << r3.rand
173 if num.first.zero? then num.shift; redo end
174 end
175
176 p num
177 puts num.to_s.to_i
178 puts
179
180
181
182
183
184
185
186 class Array
187 def shuffle
188 array = dup
189 size.downto 2 do |j|
190 r = rand j
191 array[j-1], array[r] = array[r], array[j-1]
192 end
193 array
194 end
195 end
196
197 array = (1..50).to_a
198
199 10.times { p array.shuffle.first(10) }
200
201
202
203
204
205 class RNG
206
207 def num(min=8,max=min+5,iter=1)
208
209 return nil unless min.is_a?(Integer) && max.is_a?(Integer) && max > min && iter.is_a?(Integer)
210
211 ret = []
212 stats = Hash.new(0)
213 digits = Array(0..9).sort_by {rand}
214
215 digits_size = digits.size
216
217 iter.times do
218 count = 0
219 len = min + rand(max-min+1)
220 ar = []
221 while count < len
222 i = rand(digits_size)
223 random_num = digits.at(i)
224 stats[random_num] += 1
225 ar << random_num
226 digits = digits.sort_by {rand}
227 count += 1
228 if count == 1 && ar.first.zero? then ar.shift; stats[0] -= 1; count = 0 end
229 end
230 ret << ar.to_s.to_i
231 end
232
233 ret << stats
234 end
235
236 end
237
238 puts
239
240 min = 8
241 max = 13
242 iter = 10000
243 result = RNG.new.num(min, max, iter)
244 stats = result.pop
245
246 t = 0
247 stats.each_value { |v| t += v }
248
249 n = 0
250 t = t * 1.0
251 m = t / 10.0
252
253 stats.sort.each do |k,v|
254 i = (v / t) * 100.0
255 x = v > m ? v - m : m - v
256 y = (x / m) * 100.0
257 n += i
258 puts "#{k} :: #{"%.2f" % m} :: #{v} :: #{"%.2f" % i} % :: #{ "%.2f" % ((m-v) * -1) } :: #{"%.2f" % y} %"
259 end
260
261 puts n, m, t
262
263 puts
264 puts RNG.new.num(20, 25, 10)[0..-2]
265
266 puts
267 rn = RNG.new.num(80, 100)
268 puts rn[0..-2]
269 p rn.last
270