Sampling

Problem: Given an urn with N+Q balls, N of which are one colour (desirable balls) and Q of which are another (undesirable balls), determine the probability of getting i desirable balls when sampling K balls from the urn.

Note: Depending on the problem description, either with or without replacement may be specified. Both solutions are provided on this page; use the correct one!

Java
public static zerg choose_no_replace_with_probs(int N, int Q, int K, double p)    { // p is the probability of choosing items from N instead of Q        if (prob_choose[N][Q][K].init) return prob_choose[N][Q][K] ; if (K == 0 || N == 0) {            double[] a = {1.0} ; return new zerg(a,true) ; }        int n = Math.min(N,K) ; if (Q == 0) {            double[] a = new double[n+1] ; a[n] = 1.0 ; return new zerg(a, true); }        double[] ans = new double[n+1] ; double[] suc = choose_no_replace_with_probs(N-1,Q,K-1,p).arr ; for (int i = 0 ; i < suc.length; i ++) {ans[i+1] += suc[i] * N/(N+(1-p)/p*Q+0.0);} double[] fail = choose_no_replace_with_probs(N,Q-1,K-1,p).arr ; for (int i = 0 ; i < fail.length ; i ++) {ans[i] += fail[i] * (1.0-N/(N+(1-p)/p*Q+0.0)) ; } return prob_choose[N][Q][K] = new zerg(ans,true) ; } static class zerg {        double[] arr ; boolean init ; public zerg(double[] p, boolean v) {arr = p ; init = v ;} } public static double[] choose_no_replace(int N, int Q,int K)    { // generate an array with probabilities p[0]...p[k] ; // choosing K items from N desirable items and Q undesirable items, with equal probability assigned to each double[] res = new double[K+1] ; if (K >= N+Q){res[N] = 1.0 ; return res ;} for (int i = 0 ; i <= K ; i ++) {            // get i desirable items if (i > N){ res[i] = 0 ; continue ;} if (i < K-Q){res[i] = 0 ; continue ;} res[i] = nCk(N,i)*nCk(Q,K-i)/nCk(N+Q,K) ; }        return res ; }    public static double[] choose_with_replace(int N, int Q, int K)     { // generate an array with probabilities p[0]...p[k] // choosing K items from N desirable items and Q undesirable items, with replacement and all equal probabilities double[] res = new double[K+1] ; double x,y,z ; x = N ; y = Q ; z = K ; for (int i = 0 ; i <= K ; i ++) {            // get i desirable items res[i] = nCk(K,i)*Math.pow((N+0.0)/(Q+N),i)*Math.pow(1.0-(N+0.0)/(Q+N),K-i) ; }        return res ; } public static void init(int N)    { lfact = new double[N+1] ; lfact[0] = 0 ; for (int i = 1 ; i <=N ; i ++) lfact[i] = lfact[i-1]+Math.log(i) ; }    public static double nCk(int N, int K)     { return Math.exp(lfact[N]-lfact[K]-lfact[N-K]) ; }