~~NOTOC~~ ====== Simulation des Ziegenproblems ====== Das folgende Programm simuliert das Ziegenproblem bzw. genauer das "Monty-Hall-Standard-Problem" (siehe Abschnitt [[lehrkraefte:snr:informatik:glf22:python:simulationen:erwartungswerte-mathematisch#Weiteres|Weiteres]]). from random import * ANZAHL_SIMULATIONEN = 1000000 anzahl_gewinne_bei_wechselstrategie = 0 anzahl_gewinne_bei_verbleibstrategie = 0 for simulationsnummer in range(ANZAHL_SIMULATIONEN): auto = randrange(1, 4) kandidat = randrange(1, 4) if kandidat == auto: anzahl_gewinne_bei_verbleibstrategie = anzahl_gewinne_bei_verbleibstrategie + 1 else: anzahl_gewinne_bei_wechselstrategie = anzahl_gewinne_bei_wechselstrategie + 1 print(f'Relative Anzahl der Gewinne bei Wechselstrategie: {100 * anzahl_gewinne_bei_wechselstrategie / ANZAHL_SIMULATIONEN:.4f} %') print(f'Relative Anzahl der Gewinne bei Verbleibstrategie: {100 * anzahl_gewinne_bei_verbleibstrategie / ANZAHL_SIMULATIONEN:.4f} %') Wenn man zum Beispiel nur die Verbleibstrategie betrachtet, spart man 3 Codezeilen. Dann braucht man die Variablen ''auto'' und ''kandidat'' eigentlich gar nicht: Nochmal 2 Codezeilen gespart. from random import * ANZAHL_SIMULATIONEN = 1000000 anzahl_gewinne_bei_verbleibstrategie = 0 for simulationsnummer in range(ANZAHL_SIMULATIONEN): if randrange(1, 4) == randrange(1, 4): anzahl_gewinne_bei_verbleibstrategie = anzahl_gewinne_bei_verbleibstrategie + 1 print(f'Relative Anzahl der Gewinne bei Wechselstrategie: {100 * (ANZAHL_SIMULATIONEN - anzahl_gewinne_bei_verbleibstrategie) / ANZAHL_SIMULATIONEN:.4f} %') print(f'Relative Anzahl der Gewinne bei Verbleibstrategie: {100 * anzahl_gewinne_bei_verbleibstrategie / ANZAHL_SIMULATIONEN:.4f} %') from random import * ANZAHL_SIMULATIONEN = 1000000 # Man mag sich vorstellen, dass zwei Personen spielen. # Die eine Person spielt mit der Wechselstrategie, # d.h. sie wechselt stets zur anderen Tür, nachdem der # Showmaster eine Tür geöffnet hat. Sie zählt die Anzahl ihrer # Gewinne in der folgenden Variablen. anzahl_gewinne_bei_wechselstrategie = 0 # Die andere Person bleibt stets bei der Tür, die sie # zuerst gewählt hat. Sie zählt die Anzahl ihrer Gewinne # in der folgenden Variablen. # # Falls sich jemand wundert, warum wir diese beiden Strategien in # derselben Simulation gleichzeitig testen können: # Da die Wahl der ersten Tür zufällig geschieht, können wir einfach annehmen, # dass beide Personen dieselbe Tür wählen. anzahl_gewinne_bei_verbleibstrategie = 0 for simulationsnummer in range(ANZAHL_SIMULATIONEN): if simulationsnummer % 100000 == 0: print(f'Simulation: {simulationsnummer}') # Ermittle die Nummer der Tür, hinter der das Auto steht, # also 1, 2 oder 3, jeweils mit Wahrscheinlichkeit 1/3. auto = randrange(1, 4) # Zufällige Wahl der Türnummer durch den Kandidaten. # (Wer mag, kann auch den Kandidaten stets Tür Nummer 3 wählen lassen.) kandidat = randrange(1, 4) if kandidat == auto: # Das Auto befindet sich hinter der vom Kandidaten gewählten Tür. # Der Showmaster öffnet zufällig eine der beiden anderen Türen, # hinter denen sich jeweils eine Ziege befindet. # Bleiben führt zum Gewinn des Autos, Türwechsel zur Ziege. anzahl_gewinne_bei_verbleibstrategie = anzahl_gewinne_bei_verbleibstrategie + 1 else: # Das Auto befindet sich nicht hinter der vom Kandidaten gewählten Tür. # Der Showmaster muss die vom Kandidaten nicht gewählte Tür öffnen, # hinter der sich die Ziege befindet. # Türwechsel führt zu Auto, Bleiben zu Ziege. anzahl_gewinne_bei_wechselstrategie = anzahl_gewinne_bei_wechselstrategie + 1 print(f'\nAnzahl der Simulationen: {ANZAHL_SIMULATIONEN}\n') print(f'Anzahl der Gewinne bei Wechselstrategie: {anzahl_gewinne_bei_wechselstrategie}') print(f'Anzahl der Gewinne bei Verbleibstrategie: {anzahl_gewinne_bei_verbleibstrategie}\n') print(f'Relative Anzahl der Gewinne bei Wechselstrategie: {100 * anzahl_gewinne_bei_wechselstrategie/ANZAHL_SIMULATIONEN:.4f} %') print(f'Relative Anzahl der Gewinne bei Verbleibstrategie: {100 * anzahl_gewinne_bei_verbleibstrategie/ANZAHL_SIMULATIONEN:.4f} %\n') # Wer eine im Schweizer Stil formatierte Ausgabe möchte, verwende die folgenden Zeilen: # print(f'\nAnzahl der Simulationen: {ANZAHL_SIMULATIONEN:,}\n'.replace(',', "'")) # print(f'Anzahl der Gewinne bei Wechselstrategie: {anzahl_gewinne_bei_wechselstrategie:,}'.replace(',', "'")) # print(f'Anzahl der Gewinne bei Verbleibstrategie: {anzahl_gewinne_bei_verbleibstrategie:,}\n'.replace(',', "'")) # print(f'Relative Anzahl der Gewinne bei Wechselstrategie: {100 * anzahl_gewinne_bei_wechselstrategie/ANZAHL_SIMULATIONEN:.4f} %') # print(f'Relative Anzahl der Gewinne bei Verbleibstrategie: {100 * anzahl_gewinne_bei_verbleibstrategie/ANZAHL_SIMULATIONEN:.4f} %\n') ===== Bemerkungen ===== * Allein aus der Lektüre des obigen Programms wird mir klar, dass die Wechselstrategie doppelt so erfolgreich ist wie die Verbleibstrategie (denn der ''if''-Fall ''auto == kandidat'' tritt doppel so häufig auf wie der ''else''-Fall ''auto != kandidat''; insbesondere ist das klar, wenn der Kandidat stets dieselbe Tür wählt). * Der Ablauf des Programms bestätigt dies. * Als ich anfing, das Programm zu schreiben, dachte ich, ich müsse genau ermitteln, welche Tür der Moderator öffnet etc. Diese Zusatzarbeit ist aber vollkommen unnötig, wie hoffentlich aus den Kommentaren im Programm deutlich wird. Zusammengefasst führt das Schreiben des Programms (d.h. ein genaues Überlegen der Abläufe) sofort zur Lösung des Problems. ===== Weiteres ===== Laut https://de.wikipedia.org/wiki/Ziegenproblem ist das Original-Problem wohl nicht genau gestellt, weshalb die Präzisierung https://de.wikipedia.org/wiki/Ziegenproblem#Das_Monty-Hall-Standard-Problem formuliert wurde. Dieses Standard-Problem haben wir simuliert. Übrigens gibt es auf Wikipedia noch zwei weitere Ziegenprobleme: ein [[https://de.wikipedia.org/wiki/Ziegenproblem_(Geometrie)|geometrisches Ziegenproble]] und ein [[https://de.wikipedia.org/wiki/Fluss%C3%BCberquerungsr%C3%A4tsel|Flussüberquerungsproblem]] mit Ziege.