Unbias a random generator: Difference between revisions
Content added Content deleted
(Clarify how to unbias using mathematical properties, rm draft status (no problems for a long time)) |
(Added D version) |
||
Line 7: | Line 7: | ||
The actual unbiasing should be done by generating two numbers at a time from randN and only returning a 1 or 0 if they are different. As long as you always return the first number or always return the second number, the probabilities discussed above should take over the biased probability of randN. |
The actual unbiasing should be done by generating two numbers at a time from randN and only returning a 1 or 0 if they are different. As long as you always return the first number or always return the second number, the probabilities discussed above should take over the biased probability of randN. |
||
=={{header| |
=={{header|D}}== |
||
<lang d>import std.stdio, std.random; |
|||
bool biased(int n) { |
|||
return uniform(0.0, 1.0) < (1.0 / n); |
|||
} |
|||
bool unbiased(int n) { |
|||
bool a, b; |
|||
do { |
|||
a = biased(n); |
|||
b = biased(n); |
|||
} while (a == b); |
|||
return a; |
|||
} |
|||
void main() { |
|||
int M = 50_000; |
|||
foreach (n; 3 .. 7) { |
|||
int c1, c2; |
|||
foreach (i; 0 .. M) { |
|||
c1 += biased(n); |
|||
c2 += unbiased(n); |
|||
} |
|||
writefln("%d: %2.2f%% %2.2f%%", n, 100.0*c1/M, 100.0*c2/M); |
|||
} |
|||
}</lang> |
|||
Output: |
|||
<pre>3: 33.12% 50.15% |
|||
4: 25.13% 50.02% |
|||
5: 19.61% 50.01% |
|||
6: 16.70% 49.98%</pre> |
|||
=={{header|J}}== |
|||
<lang j>randN=: 0 = ? |
<lang j>randN=: 0 = ? |
||
unbiased=: i.@# { ::$: 2 | 0 3 -.~ _2 #.\ 4&* randN@# ]</lang> |
unbiased=: i.@# { ::$: 2 | 0 3 -.~ _2 #.\ 4&* randN@# ]</lang> |