# Wahrscheinlichkeit bei 3 Würfeln



## WhiteFang (24. Sep 2010)

Hallo Leute,
ich habe mich hier mal angemeldet, weil ich im Moment vor einem Problem stehe und nicht weiter komme.
Meine letzten praktischen Erfahrungen (in der Schule) mit Java liegen mittlerweile 2 Jahre zurück und ich bin ein wenig eingerostet. Jetzt hat mich ein Lehrer gefragt, ob ich mal ein Java Programm schreiben könnte, mit dem man Wahrscheinlichkeiten aurechnen kann. Ich habe aber jetzt gemerkt, dass mir irgenwie der Ansatz fehlt und ich ein wenig Hilfe brauche.

Problem:
Es soll mit 3 Würfeln gewürfelt werden. Die Ergebnisse der 3 Würfe sollen addiert werden und dann soll die Wahrscheinlichkeit errechnet werden, mit der bestimmte Ergebnisse (Summen der 3 Würfelaugen) auftreten. Außerdem sollte auch wählbar sein, wie oft man würfeln möchte.

Zum Beispiel liegt die Wahrscheinlichkeit mit 2 Würfeln eine 7 zu würfeln am höchsten. (Bei 16,666... %)
Die Wahrscheinlichkeit eine 3 zu würfeln liegt allerdings nur bei 8,3333...%

Genau das Gleiche mit 3 Würfeln ist das Ziel meines Programmes.
Ich hoffe ihr könnt mir helfen, den "Wiedereinstieg zu schaffen".

Das habe ich bisher gemacht:

```
public class DreiWuerfel {

    public static void main(String[] args) {

        float Wahrscheinlichkeit; // Soll die Wahrscheinlichkeit darstellen.
        long Versuche;            // Soll die Anzahl der Versuche beinhalten (Durch Eingabe wählbar)
        int Zahl1 = 1;            // Augen des Würfels Nr.1
        int Zahl2 = 2;            // Augen des Würfels Nr.2
        int Zahl3 = 3;            // Augen des Würfels Nr.3
        
        

        int a = 0;// Anzahl für Ergebnis 3
        int b = 0;// Anzahl für Ergebnis 4
        int c = 0;// Anzahl für Ergebnis 5
        int d = 0;// Anzahl für Ergebnis 6
        int e = 0;// Anzahl für Ergebnis 7
        int f = 0;// Anzahl für Ergebnis 8
        int g = 0;// Anzahl für Ergebnis 9
        int h = 0;// Anzahl für Ergebnis 10
        int i = 0;// Anzahl für Ergebnis 11
        int j = 0;// Anzahl für Ergebnis 12
        int k = 0;// Anzahl für Ergebnis 13
        int l = 0;// Anzahl für Ergebnis 14
        int m = 0;// Anzahl für Ergebnis 15
        int n = 0;// Anzahl für Ergebnis 16
        int o = 0;// Anzahl für Ergebnis 17
        int p = 0;// Anzahl für Ergebnis 18


        System.out.println ("Bitte geben sie die Anzahl der Versuche ein: ");
        
        // Anzahl der Versuche Einlesen und nach int Versuche schreiben
        
        // Zufallsgenerator für 3 Würfel mit Zuweisung zu Zahl1, Zahl2 und Zahl3
        
        
        
        int Summe = Zahl1 + Zahl2 + Zahl3;
        System.out.println ("Die Summe aus den 3 Würfelergebnissen lautet: ");
        System.out.println (Summe);
        
        switch (Summe)
        {
        case 3 : ++a;
        case 4 : ++b;
        case 5 : ++c;
        case 6 : ++d;
        case 7 : ++e;
        case 8 : ++f;
        case 9 : ++g;
        case 10 : ++h;
        case 11 : ++i;
        case 12 : ++j;
        case 13 : ++k;
        case 14 : ++l;
        case 15 : ++m;
        case 16 : ++n;
        case 17 : ++o;
        case 18 : ++p;
        
        //System.out.println(d); Zum ersten Test 
        
        }
        
        
    }

}
```

So weit bin ich bisher gekommen. Ja ich weiß, dass es bestimmt auch einfacher ginge, aber ich wollte euch nur zeigen, dass ich schon versucht habe, etwas zu machen.

Mir fehlt: 

Der Zufallsgenerator, der eine Zahl zwischen 1 und 6 generiert.
Der Algorythmus, der die Anzahl der Versuche einließt.

Ich verlasse mich jetzt mal ganz fest auf euch!
WhiteFang

PS: Bitte schreibt mir jetzt nicht, dass "Google mein Freund ist" oder die Forensuche. Da habe ich bisher nichts gefunden. Wenn es doch was gibt, dann war ich zu blöd es zu finden oder zu verstehen...


----------



## Michael... (24. Sep 2010)

WhiteFang hat gesagt.:


> ... ob ich mal ein Java Programm schreiben könnte, mit dem man Wahrscheinlichkeiten aurechnen kann. Ich habe aber jetzt gemerkt, dass mir irgenwie der Ansatz fehlt und ich ein wenig Hilfe brauche.
> ...
> Es soll mit 3 Würfeln gewürfelt werden. Die Ergebnisse der 3 Würfe sollen addiert werden und dann soll die Wahrscheinlichkeit errechnet werden


Naja, Wahrscheinlichkeiten ausrechnen ist was anderes als zu versuchen durch Simulation Häufigkeiten zu ermitteln und daraus Wahrscheinlichkeiten abzuleiten ;-)

Hattest Du schonmal mit Arrays oder Listen zu tun? Die würden den Code extrem verkürzen und vereinfachen.

Um Zufallszahlen zu generieren gibt's die Klasse Random oder die Methode Math.random(). Einfach mal in die API
Doku schauen. Man muss nicht immer gleich googlen ;-)


----------



## Michael... (24. Sep 2010)

Zum Einlesen von der Konsole gibt's mittlerweile die Klasse Scanner. Ansonsten gibt's immer noch System.in.read()


----------



## noobadix (24. Sep 2010)

Finde das interessant und werde mich gleich daran machen, auch sowas zu schreiben.  Dazu werde ich mir nochmal *die mathematischen Grundlagen der Wahrscheinlichkeitsrechnung für diesen Fall zu Gemüte führen *und mit mir selbst streiten, ob Wahrscheinlichkeiten in einer Welt, die schon determiniert scheint, weil Ursache/Wirkung gilt, überhaupt praktisch zielführend ist oder ob nicht die Differenzierung der beteiligten Kräfte/Energien viel anstrebenswerter ist, was dann ein Programm zur Folge hätte, das Parameter wie Raumtemperatur, Schüttelstärke und -dauer, Ausgangs- und Wurfwinkel etc. übernehmen würde, dazu die Wahrscheinlichkeiten berechnen und ad absurdum führen könnte.


----------



## ARadauer (24. Sep 2010)

> Der Algorythmus, der die Anzahl der Versuche einließt.


schleife drum herum... und das mit deinen a,b,c... Variablen ist natürlich furchtbar, aber das macht jeder so der noch nie mit arrays gearbeitet hat...

man kann das sehr flexibel machen...

zb


```
import java.util.Random;


public class Wuerfeln {
	public static void main(String[] args) {
			
		Random rnd = new Random();
		int würfe = 1000000;
		int würfel = 3;
		int[] anzahl = new int[würfel*6+1]; //max 6*würfel,+1 da wir ja bei 0 anfangen
		
		//so oft wir würfeln wollen
		for(int i = 0;i < würfe; i++){
			int augen =0;
			for(int j = 0; j < würfel; j++){
				//augenzahl erhöehen
				augen += rnd.nextInt(6)+1;
			}
			//bei der augenanzahl erhöhen wir
			anzahl[augen]++;
			
		}
		
		System.out.println(würfe+" mal mit "+würfel+" gewürfelt:");
		
		for(int i=1; i< anzahl.length; i++){
			double prozent = anzahl[i]*100/(double)würfe;
			System.out.println(i+"\t"+anzahl[i]+"\t"+(prozent)+" %");
		}
		
	}
}
```


----------



## WhiteFang (24. Sep 2010)

ARadauer hat gesagt.:


> schleife drum herum... und das mit deinen a,b,c... Variablen ist natürlich furchtbar, aber das macht jeder so der noch nie mit arrays gearbeitet hat...
> 
> man kann das sehr flexibel machen...
> 
> ...



Jo dann erstmal ein richtig verdammt großes DANKE! :applaus:
Ich habe selbst gemerkt, dass ich seeeehhhrrr eingerostet bin. Ich hab den Quellcode jetzt mal ausprobiert und bin gerade dran, ihn komplett zu verstehen. Jetzt werde ich noch versuchen, dass man die Zahl der Würfe noch per Tastatur eingeben kann, aber das werde ich bestimmt mit ein bisschen Probieren wieder hin bekommen. Das war übrigens das Schwierigste, was ich je Programmiert habe. 
Falls ich etwas nicht verstehen sollte, kann ich bestimmt noch mal die eine oder andere Frage stellen, oder?
Ist übrigens ne gute Übung, weil ich nach meinem Abitur eine Anstellung als Fachinformatiker anstrebe.


----------



## ARadauer (24. Sep 2010)

> Falls ich etwas nicht verstehen sollte, kann ich bestimmt noch mal die eine oder andere Frage stellen, oder?


natürlich... jederzeit!


----------



## Illuvatar (24. Sep 2010)

Und hier das ganze noch etwas objektorientierter... was es in meinen Augen lesbarer macht.
Die einzelnen Befehle bleiben natürlich die gleichen, die musst du immernoch genauso verstehen.


```
import java.util.*;

class Die {
  private Random myRandom;
  private int max;
  
  public Die() {
    this(6);
  }
  
  public Die(int numberOfSides) {
    this.max = numberOfSides;
    this.myRandom = new Random();
  }
  
  public int getNumberOfSides() {
    return max;
  }
  
  public int roll() {
    return myRandom.nextInt(max) + 1;
  }
}

class DiceCup {
  private Die[] dice;
  
  public DiceCup(int diceCount, int numberOfSides) {
    this.dice = new Die[diceCount];
    for (int i = 0; i < diceCount; i++) {
      dice[i] = new Die(numberOfSides);
    }
  }
  
  public DiceCup(Die... dice) {
    this.dice = dice.clone();
  }
  
  public int getDiceCount() {
    return dice.length;
  }
  
  public int rollAll() {
    int result = 0;
    for (Die die : dice) {
      result += die.roll();
    }
    return result;
  }
}

public class DiceCounter {
  private int[] counter;

  public DiceCounter(int maxValue) {
    this.counter = new int[maxValue + 1];
    reset();
  }

  public void reset() {
    Arrays.fill(counter, 0);
  }
  
  public void countResult(int result) {
    counter[result]++;
  }
  
  public int getCounter(int number) {
    return counter[number];
  }
  
  public static void main(String[] args) {
    int DICE_COUNT = 3;
    int NUMBER_OF_SIDES = 6;
    int MAX_VALUE = DICE_COUNT * NUMBER_OF_SIDES;
    
    System.out.println("Anzahl Würfe:");
    Scanner sc = new Scanner(System.in);
    int rollCount = sc.nextInt();

    DiceCup cup = new DiceCup(DICE_COUNT, NUMBER_OF_SIDES);
    DiceCounter counter = new DiceCounter(MAX_VALUE);
    
    for (int i = 0; i < rollCount; i++) {
      counter.countResult(cup.rollAll());
    }
    
    for (int i = 0; i <= MAX_VALUE; i++) {
      int cnt = counter.getCounter(i);
      double percent = 100.0 * cnt / rollCount;
      System.out.println("Anzahl " + i + ":\t " + cnt + "\t " + percent + '%');
    }
  }
}
```


----------



## noobadix (25. Sep 2010)

> Die Wahrscheinlichkeit eine 3 zu würfeln liegt allerdings nur bei 8,3333...%



Bei 2 Würfeln liegt die Wsk. des Ergebnisses 3 bei 5,55...% , für 4 bei 8,33...%.  Nicht, dass jemand viel Geld verliert ^^.


----------



## noobadix (26. Sep 2010)

So, folgendes Programm berechnet die Wahrscheinlichkeiten, jedoch kann ich oder mein PC (P3) nicht mit so vielen Nachkommastellen umgehen, sodass ab 10 Durchgängen mir die Wartezeit auf das Ergebnis von "kombiniereDurchgang()" zu lang wird. Hat jemand eine Idee, wie ich das Problem (Zahlen um 0,00042 ^ 10)  lösen kann? So richtig interessant wird es ja erst ab ca. 1.000.000 Durchgängen...

Gruß n.


```
import java.io.*;
import java.util.*;

class WuerfelErgebnisGenerator{
	int WUERFE = 0,WUERFEL=0;
	Random RNDM = new Random();
	int[] AUGEN = {1,2,3,4,5,6};
	public static void main(String[] args){
		WuerfelErgebnisGenerator weg = new WuerfelErgebnisGenerator();
		weg.init();
	}
	
	public void init(){
		WUERFEL = getInteger("Wie viele Wuerfel sollen pro Wurf geworfen werden?");
		WUERFE = getInteger("Wie oft soll gewuerfelt werden?");
		System.out.println("Simuliere "+WUERFE+" mal "+WUERFEL+" geworfene(n) Wuerfel(n)");
		int ereignis = summe();
		Wahrscheinlichkeit wkt = new Wahrscheinlichkeit();
		System.out.println("Wahrscheinlichkeiten der Ergebnisse pro Wurf: ");
		wkt.wskWurf();
		System.out.println("Wahrscheinlichkeiten der Ergebnisse pro Durchgangs-Summe: ");
		try{
			wkt.wskDurchgang();
		}
		catch(Exception e){e.printStackTrace();}
		System.out.println("wahrscheinlichstes Ereignis: "+wkt.getWahrscheinlichstesErgebnis());
		System.out.println("Summe der Augen: "+ereignis+wkt.getWsk(ereignis));
	}
	
	public int getInteger(String frage){
		System.out.println(frage);
		System.out.println("Geben Sie eine Zahl>0 oder 'q' zum Beenden ein:");
		BufferedReader t = new BufferedReader(new InputStreamReader(System.in));
		String input = "";
		int result=0;
		while(result<=0){
			try{
				input = t.readLine();
				if(input.equals("q")) System.exit(0);
				try{
					result = java.lang.Integer.parseInt(input);
					if(result>0) return result;
					else{
						System.out.println("Eingabe muss hoeher als 0 sein!");
						System.out.println(frage);
						System.out.println("Geben Sie eine Zahl>0 oder 'q' zum Beenden ein:");
					}
				}
				catch(NumberFormatException e){
					System.out.println("Eingabe war keine Zahl!");
					System.out.println(frage);
					System.out.println("Geben Sie eine Zahl>0 oder 'q' zum Beenden ein:");
				}
			}
			catch(IOException e){
				e.printStackTrace();
			}
		}
		return 1;
	}
	
	public int wuerfeln(){
		int counter=0;
		for(int i=0;i<WUERFEL;i++){
			counter+=RNDM.nextInt(5)+1;
		}
		return counter;
	}
	
	public int summe(){
		int counter = 0;
		for(int i=0;i<WUERFE;i++){
			counter += wuerfeln();
		}
		return counter;
	}
	
	class Wahrscheinlichkeit{
		HashMap<Integer,Double> wskDurchgangHM = new HashMap<Integer,Double>();
		HashMap<Integer,Double> wurfWskHM = new HashMap<Integer,Double>();
		Vector<Integer> wskWurfVector = new Vector<Integer>();
		
		public String getWahrscheinlichstesErgebnis(){
			double hoechsterWert=0;
			Integer key=0;
			Integer[] keys = wskDurchgangHM.keySet().toArray(new Integer[wskDurchgangHM.keySet().size()]);
			for(Integer k : keys){
				double val = wskDurchgangHM.get(k);
				if(hoechsterWert<val){
					key=k;
					hoechsterWert=val;
				}
			}
			return key+" ("+Math.rint(hoechsterWert*10000)/100+"%)";
		}
		
		public String getWsk(Integer key){
			return " ("+Math.rint(wskDurchgangHM.get(key)*10000)/100+"%)";
		}
		
		public void wskWurf(){
			int[][] arg = new int[WUERFEL][6];
			for(int i = 0; i<WUERFEL;i++){
				arg[i] = AUGEN;
			}
			kombiniere(arg,0);
			HashMap<Integer,Integer> wskWurfHM = new HashMap<Integer,Integer>();
			for(int i=0;i<wskWurfVector.size();i++){
				Integer element = wskWurfVector.elementAt(i);
				if(wskWurfHM.containsKey(wskWurfVector.elementAt(i))){
					 wskWurfHM.put(element,(wskWurfHM.get(element)+1));
				}
				else wskWurfHM.put(wskWurfVector.elementAt(i),1);
			}
			Integer[] keys = wskWurfHM.keySet().toArray(new Integer[wskWurfHM.keySet().size()]);
			for(int k : keys){
				double val = wskWurfHM.get(k);
				wurfWskHM.put(k,(val/wskWurfVector.size()));
				System.out.println(k+": ca. "+ Math.rint((val/wskWurfVector.size())*10000)/100+"%");
			}
		}
		
		public void kombiniere(int[][] wuerfelArray, int wurfCounter){
			for(int[] i : wuerfelArray){
				for(int j : i){
					if(wuerfelArray.length==1) {
						wskWurfVector.add(j+wurfCounter);
					}
					else{
						int[][] newWuerfelArray = new int[wuerfelArray.length-1][6];
						for(int k = 0; k<newWuerfelArray.length;k++){
							newWuerfelArray[k] = AUGEN;
						}
						kombiniere(newWuerfelArray,j+wurfCounter);
					}
				}
			}
		}
		
		public void wskDurchgang(){
			Integer[] keys = wurfWskHM.keySet().toArray(new Integer[wurfWskHM.keySet().size()]);
			kombiniereDurchgang(keys,1,0,1);
			Integer[] keysSorted = wskDurchgangHM.keySet().toArray(new Integer[wskDurchgangHM.keySet().size()]);
			java.util.Arrays.sort(keysSorted);
			for(Integer k : keysSorted){
				System.out.println(k+ ": " +  (wskDurchgangHM.get(k)*100) );
			}	
		}
		
		public void kombiniereDurchgang(Integer[] keys,int stufe,int counter,double wskCounter){
			for(Integer k : keys){
				if(stufe==WUERFE){
					if(wskDurchgangHM.containsKey(k+counter)) wskDurchgangHM.put(k+counter,wskDurchgangHM.get(k+counter)+((wskCounter*wurfWskHM.get(k))));
					else wskDurchgangHM.put(k+counter,(wskCounter*wurfWskHM.get(k)));
				}
				else kombiniereDurchgang(keys,stufe+1,k+counter,wskCounter*wurfWskHM.get(k));
			}
		}
	}
}
```


----------

