Wichteln


Worum geht es?
Wir haben eine Gruppe an Mitspielern. Jeder stellt ein Geschenk bereit und erhält durch Zufallsauswahl ein Geschenk. Dabei kann es zu Kollisionen kommen, indem jemand sein eigenens Geschenk wieder erhält.
Wie wahrscheinlich ist dies denn?

Anzahl Mitspieler
n
Kombinationen
n!
Kollisionen
c
Verhältnis
x
1 1 1 1.0
2 2 1 0.5
3 6 4 0.6666667
4 24 15 0.625
5 120 76 0.6333333
6 720 455 0.6319444
7 5040 3186 0.63214284
8 40320 25487 0.63211805
9 362880 229384 0.6321208
10 3628800 2293839 0.63212055
11 39916800 25232230 0.63212055
12 479001600 302786759 0.63212055
13 6227020800 3936227868 0.63212055

x = c/n! = 1 - 1/e


if you want to execute it local

Download jar file and execute it like this: "java Wichtel 10"


Code listing

package wichtel;

/**
 *
 * @author Rolf
 */
public class Wichtel {

    static boolean inUse[] = null;          // is the number i in use?
    static int set[] = null;                // set at pos [] the number

    static long cnt = 0;                    // cnt for possible combinations
    static long collCnt = 0;                // cnt collisions
    static boolean verbose = false;         // more debug
    static int maxLvl = 0;                  // how many player
    
    static public void usage() {
        System.out.println("missing arguments");
        System.exit(1);
    }

    static int get(int i) {
        if (inUse[i] == false) {            
            return i;
        }
        return -1;
    }

    static boolean collision() {
        for (int i = 0; i < maxLvl; i++) {
            if (i == set[i]) {
                collCnt++;
                return true;
            }
        }
        return false;
    }

    static void display() {
        boolean isColl = collision();
        ++cnt;
        if (verbose) {
            System.out.print(cnt + "\t");
            for (int i = 0; i < maxLvl; i++) {
                System.out.print(set[i] + " ");
            }

            System.out.println(isColl);
        }
    }

    static void doit(int lvl) {
        if (lvl == maxLvl) {
            display();
        } else {
            for (int i = 0; i < maxLvl; i++) {
                int n = get(i);
                if (n >= 0) {
                    inUse[i] = true;
                    set[lvl] = n;
                    doit(lvl + 1);
                    inUse[i] = false;
                }
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 1) {
            usage();
        }
        int toMaxLvl = new Integer(args[0]);
        inUse = new boolean[toMaxLvl];
        set = new int[toMaxLvl];

        for (int m = 1; m < toMaxLvl; m++) {
            maxLvl = m;
            cnt=0;                                  // reset cnt
            collCnt=0;
            for (int i = 0; i < toMaxLvl; i++) {    // initialize
                inUse[i] = false;
            }

            doit(0);
            
            // report summary
            float r= (float) collCnt / (float) cnt;
            System.out.println("Final summary\t" + maxLvl + "\t" + cnt + "\t" + collCnt + "\t"+r);
        }
    }
}


Rolf LANG - Remsstr. 39 - 71384 Weinstadt | 07:59:03 up 29 days, 10:25, 1 user, load average: 0.06, 0.08, 0.08