[Issue 5849] New: std.random.dice is better as a range
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sat Apr 16 18:10:35 PDT 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5849
Summary: std.random.dice is better as a range
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: Phobos
AssignedTo: nobody at puremagic.com
ReportedBy: bearophile_hugs at eml.cc
--- Comment #0 from bearophile_hugs at eml.cc 2011-04-16 18:06:59 PDT ---
When I have to use std.random.dice the frequencies don't change often, but I
usually have to compute many random values efficiently. Calling dice() many
times is not efficient, because it performs some preprocessing of the given
frequencies.
So I suggest to replace the function dice(xxx) with a range that generates the
results.
So the current usage of:
dice(70, 20, 10)
gets replaced by:
dice(70, 20, 10).front
And you are able to write:
take(dice(70, 20, 10), 5)
The good thing of this generator is its performance compared to the function.
See the performance difference between the two following implementations (5.3
seconds for the first version and 0.7 seconds for the second one).
------------------------
import std.stdio, std.random, std.string;
void main() {
enum int N = 10_000_000;
enum pr = [1/5., 1/6., 1/7., 1/8., 1/9., 1/10., 1/11., 1759/27720.];
double[pr.length] counts = 0.0;
foreach (i; 0 .. N)
counts[dice(pr)]++;
foreach (i, p; pr)
writefln("%.8f %.8f", p, counts[i] / N);
}
------------------------
import std.stdio, std.random, std.string;
void main() {
enum int N = 10_000_000;
enum pr = [1/5., 1/6., 1/7., 1/8., 1/9., 1/10., 1/11., 1759/27720.];
double[pr.length] cumulatives = pr[];
foreach (i, ref c; cumulatives[1 .. $-1])
c += cumulatives[i];
cumulatives[$-1] = 1.0;
double[pr.length] counts = 0.0;
auto rnd = Xorshift(unpredictableSeed());
foreach (i; 0 .. N) {
double rnum = rnd.front() / cast(double)typeof(rnd.front()).max;
rnd.popFront();
int j;
for ( ; rnum > cumulatives[j]; j++) {}
counts[j]++;
}
foreach (i, p; pr)
writefln("%.8f %.8f", p, counts[i] / N);
}
-------------------------
See also some other improvements I have suggested for std.random.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list