Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example;
- import static org.apache.commons.math.util.MathUtils.factorialDouble;
- public class BulkCoinFlipTest {
- private static boolean myChoose = false;
- private static boolean simulate = true;
- private static boolean memoize = false;
- private static boolean printHistogram = false;
- private static Double[] chanceMemo = null;
- public static void main(String[] args) {
- int periods = 1_000_000;
- double x = 0.2;
- int n = 80;
- // Pre-initialize the math stuff, for clean timing
- for (int i = 0; i < n; i++) {
- try {
- basicXChooseY(n, i);
- } catch (Exception ignore) {}
- myXChooseY(n, i);
- }
- simulate = false;
- runTrial(periods, x, n);
- simulate = true;
- // myChoose = false;
- // runTrial(periods, x, n);
- myChoose = true;
- runTrial(periods, x, n);
- memoize = true;
- runTrial(periods, x, n);
- }
- private static void runTrial(int periods, double x, int n) {
- try {
- System.out.println(periods + " tests of " + n + " rolls with " + (x * 100) + "% chance of success, using " +
- (simulate ? (myChoose ? "my" : "the basic") + " choose function and " + (memoize ? "" : "no ") + "memoization"
- : "individual rolls"));
- if (memoize) chanceMemo = new Double[n];
- int[] hist = new int[n + 1];
- long start = System.currentTimeMillis();
- for (int i = 0; i < periods; i++) {
- hist[getSuccesses(x, n)]++;
- }
- long elapsed = System.currentTimeMillis() - start;
- System.out.println("Elapsed time (ms): " + elapsed);
- if (printHistogram) printHistogram(hist, periods);
- } catch (Exception e) {
- System.out.println(e.toString());
- }
- System.out.println();
- }
- static int getSuccesses(double x, int n) {
- return simulate ? getSimulatedSuccesses(x, n) : getRealSuccesses(x, n);
- }
- static int getSimulatedSuccesses(double x, int n) {
- double roll = Math.random();
- int result = 0;
- double chance = getChanceOfMSuccesses(x, n, result);
- while (chance < roll) {
- roll -= chance;
- result++;
- chance = getChanceOfMSuccesses(x, n, result);
- }
- return result;
- }
- static int getRealSuccesses(double x, int n) {
- int result = 0;
- for (int i = 0; i < n; i++) {
- if (Math.random() < x) result++;
- }
- return result;
- }
- static double getChanceOfMSuccesses(double x, int n, int m) {
- if (memoize) {
- if (chanceMemo[m] != null) return chanceMemo[m];
- return chanceMemo[m] = Math.pow(x, m) * Math.pow(1 - x, n - m) * xChooseY(n, m);
- } else {
- return Math.pow(x, m) * Math.pow(1 - x, n - m) * xChooseY(n, m);
- }
- }
- static double xChooseY(int x, int y) {
- if (myChoose) return myXChooseY(x, y);
- else return basicXChooseY(x, y);
- }
- static double basicXChooseY(int x, int y) {
- if (x > 170 || y > 170) throw new IllegalArgumentException("Too large for factorial calculation");
- return factorialDouble(x) / (factorialDouble(y) * factorialDouble(x - y));
- }
- static double myXChooseY(int x, int y) {
- if (2*y >= x) {
- double result = 1;
- for (int i = x; i > y; i--) {
- result *= i;
- }
- return result / factorialDouble(x-y);
- } else {
- return myXChooseY(x, x-y);
- }
- }
- // Useful for comparing results between methods for correctness
- static void printHistogram(int[] hist, int n) {
- System.out.println("Successes: periods\n");
- int digits = new Double(Math.log10(n)).intValue() + 1;
- int idigits = new Double(Math.log10(hist.length)).intValue() + 1;
- for (int i = 0; i < hist.length; i++) {
- System.out.printf("%" + idigits + "d: %" + digits + "d\n", i, hist[i]);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment