// example code for: http://stackoverflow.com/a/21976027/616460
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
// the important bits are the implementations of next() below. everything
// else is (somewhat sloppy) code to support testing and output.
class Dist {
// modify MAX_VALUE and RUN_COUNT as you see fit
static final int MAX_VALUE = 60;
static final int RUN_COUNT = 10000;
// base class for a test; generates a set of RUN_COUNT random values
// in the range [0, MAX_VALUE) and stores a histogram of the results.
// subclasses should implement next() to return a value [0, MAXVALUE).
static abstract class RandomTest {
final int[] count = new int[MAX_VALUE];
RandomTest
(String name
) { this.
name = name
; } RandomTest run () {
System.
out.
println("Running " + name
+ "..."); for (int n = 0; n < RUN_COUNT; ++ n) count[next()] ++;
return this;
}
abstract int next ();
}
// Uniform distribution
static class Uniform extends RandomTest {
Uniform () { super("Uniform"); }
@Override int next () {
return random.nextInt(MAX_VALUE);
}
}
// pow(value, bias)
static class Pow extends RandomTest {
final double bias;
Pow (double bias) { super("Pow(" + bias + ")"); this.bias = bias; }
@Override int next () {
double v
= Math.
pow(random.
nextDouble(), bias
); return (int)(v * MAX_VALUE);
}
}
// [0,1) section of gaussian distribution, scaled by given value
static class Gaussian extends RandomTest {
final double scale;
Gaussian (double scale) { super("G(" + scale + ")"); this.scale = scale; }
@Override int next () {
double v;
do {
v
= Math.
abs(random.
nextGaussian() / scale
); } while (v >= 1.0);
return (int)(v * MAX_VALUE);
}
}
// cubic S
static class Cubic extends RandomTest {
Cubic () { super("Cubic"); }
@Override int next () {
double v = random.nextDouble();
v = 3*v*v - 2*v*v*v;
return (int)(v * MAX_VALUE);
}
}
// print one row of results; prints header if index == -1
static void printResultRow (List<RandomTest> tests, int index) {
System.
out.
printf("%-5s:",
(index
< 0) ? "Name" : Integer.
toString(index
)); for (RandomTest test:tests) {
String s
= (index
< 0) ? test.
name : Integer.
toString(test.
count[index
]); }
}
// run all tests and print results
public static void main
(String[] args
) {
List<RandomTest> tests = new ArrayList<RandomTest>();
tests.add(new Uniform().run());
tests.add(new Pow(0.5).run());
tests.add(new Pow(2.0).run());
tests.add(new Pow(10.0).run());
tests.add(new Gaussian(1.0).run());
tests.add(new Gaussian(3.5).run());
tests.add(new Cubic().run());
for (int n = -1; n < MAX_VALUE; ++ n)
printResultRow(tests, n);
}
}