Created
October 12, 2012 21:09
-
-
Save joriki/3881546 to your computer and use it in GitHub Desktop.
Calculation and simulation of the probability of a relatively uniform draw; see http://math.stackexchange.com/questions/211687
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.math.BigInteger; | |
import java.util.Random; | |
public class Question211687 { | |
final static int n = 100; | |
final static int m = 10; | |
final static int perKind = 100; | |
final static int min = 8; | |
final static int max = 12; | |
final static int total = m * perKind; | |
final static int R = max - min; | |
final static int [] counts = new int [m]; | |
final static Random random = new Random (); | |
static int count = 0; | |
static BigInteger sum = BigInteger.ZERO; | |
static void recurse (int index,int left) { | |
if (left < min * (m - index) || left > max * (m - index)) | |
return; | |
if (index == m) { | |
if (left == 0) { | |
count++; | |
BigInteger product = BigInteger.ONE; | |
for (int i = 0;i < m;i++) | |
for (int j = min;j < max;j++) | |
product = product.multiply (BigInteger.valueOf (counts [i] <= j ? j + 1 : perKind - j)); | |
sum = sum.add (product); | |
} | |
return; | |
} | |
for (counts [index] = min;counts [index] <= max;counts [index]++) | |
recurse (index + 1,left - counts [index]); | |
} | |
static BigInteger binomial (int n,int k) { | |
BigInteger binomial = BigInteger.ONE; | |
for (int i = 0;i < k;i++) { | |
binomial = binomial.multiply (BigInteger.valueOf (n - i)); | |
binomial = binomial.divide (BigInteger.valueOf (i + 1)); | |
} | |
return binomial; | |
} | |
static BigInteger factorial (int n) { | |
BigInteger factorial = BigInteger.ONE; | |
for (int i = 2;i <= n;i++) | |
factorial = factorial.multiply (BigInteger.valueOf (i)); | |
return factorial; | |
} | |
public static void main (String [] args) { | |
recurse (0,n); | |
BigInteger numerator = factorial (perKind); | |
BigInteger denominator = factorial (max).multiply (factorial (perKind - min)); | |
BigInteger num = sum; | |
BigInteger den = binomial (total,n); | |
for (int i = 0;i < m;i++) { | |
num = num.multiply (numerator); | |
den = den.multiply (denominator); | |
} | |
BigInteger gcd = num.gcd (den); | |
num = num.divide (gcd); | |
den = den.divide (gcd); | |
System.out.println (num + " / " + den); | |
int precision = 1000000; | |
System.out.println ("p = " + num.multiply (BigInteger.valueOf (precision)).add (BigInteger.valueOf (precision / 2)).divide (den).doubleValue () / precision); | |
System.out.println (count + " admissible combinations"); | |
final int ntrials = 10000000; | |
int nsuccesses = 0; | |
outer: | |
for (int i = 0;i < ntrials;i++) { | |
boolean [] used = new boolean [total]; | |
int [] npebbles = new int [m]; | |
for (int j = 0;j < n;j++) { | |
int pebble; | |
do | |
pebble = random.nextInt (total); | |
while (used [pebble]); | |
used [pebble] = true; | |
npebbles [pebble / perKind]++; | |
} | |
for (int np : npebbles) | |
if (min > np || np > max) | |
continue outer; | |
nsuccesses++; | |
} | |
System.out.println ("p ~ " + nsuccesses / (double) ntrials); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment