Bei diesem Würfelspiel gewinnt man praktisch nie, oder? |
| 02.11.2024, 09:18 | Integer21 | Auf diesen Beitrag antworten » | |||||||||||||||
| Bei diesem Würfelspiel gewinnt man praktisch nie, oder? anbei ein Bild des Spiels um das es geht. Ziel des Spiels: Jede Ganze Zahl von 1-12 einmal abhaken, bzw. umklappen Die Regeln: - Man Würfelt mit zwei Würfeln - Die gewürfelte Augenzahl kann entweder abgehakt werden, oder es können zwei Zahlen abgehakt werden, deren Summe der Augenzahl entspricht - Jede Zahl darf nur einmal abgehakt werden - Kann man keine Zahl abhaken, endet das Spiel Wenn man beispielsweise eine 4 würfelt, kann man die 4 oder die 3 und die 1 abhaken. Sind diese Zahlen bereits angehakt, ist das Spiel vorbei. Ich habe ca. 20 Runden gespielt und nie das Ziel erreicht. Nun frage ich mich, wie hoch die Wahrscheinlichkeit ist, zu gewinnen. Ich hatte in der Schule keine Stochastik und habe daher nur ein Grundlegendes Verständnis davon. Ich wäre über Hinweise dankbar, wie man an dieses Problem herangeht und welche Methoden ich benötige. Liebe Grüße und vielen Dank! |
|||||||||||||||||
| 02.11.2024, 12:46 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Wenn du von "Augenzahl" redest, meinst du jeweils die Summe der beiden gewürfelten Augenzahlen oder? D.h., wenn man eine 2 und eine 5 würfelt, d.h., Augenzahlsumme 7, darf man nach dieser Regel auch eine 3 und 4 wegstreichen (sofern noch übrig), oder?
Diese Wahrscheinlichkeit hängt auch davon ab, welche Strategie man fährt: Gerade am Anfang hat man (bei zwei unterschiedlichen gewürfelten Augenzahlen) ja die Wahl, ob man die beiden Augenzahlen einzeln oder aber die Summe abhakt. Je nach Wahl der Strategie ergibt sich eine unterschiedliche Siegwahrscheinlichkeit. Jetzt kann man natürlich auch noch danach fragen, was die optimale Strategie ist, um die Gewinnwahrscheinlichkeit zu maximieren. Das macht das Problem noch mal um einiges komplizierter. Letzteres Problem wird man aber mit einem Backward-Algorithmus lösen können, der die optimalen Siegwahrscheinlichkeiten (und auch zugehörige Strategien!) für alle Teilmengen berechnet, ausgehend von der leeren Menge und dann Stück für Stück aufbauend bis zur "vollen" Menge . P.S.: Wenn ich mich beim zugehörigen Python-Programm nicht vertan habe, dann ist selbst bei optimaler Spielweise die Siegwahrscheinlichkeit nur , also etwas weniger als 1 Promille.
|
|||||||||||||||||
| 02.11.2024, 14:08 | Integer21 | Auf diesen Beitrag antworten » | |||||||||||||||
Genau. Ca. 1:1000 wäre das also. Vielen Dank für deine Hilfe! Schade nur, dass ich so gar nichts über die Herangehensweise erfahre. Sieht so aus, als wäre das Thema zu anspruchsvoll, um da an einem Nachmittag durchzusteigen. |
|||||||||||||||||
| 02.11.2024, 14:13 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Ich kann dir noch das Python-Programm listen:
|
|||||||||||||||||
| 02.11.2024, 14:38 | Integer21 | Auf diesen Beitrag antworten » | |||||||||||||||
1000 Dank, das ist wirklich großartig! Ich weiß sehr zu schätzen, dass du dir diese Zeit genommen hast. Ich wünsche dir ein tolles Wochenende! |
|||||||||||||||||
| 02.11.2024, 16:19 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Hab mal die zweite Spielregel etwas abgewandelt - verschärft, um es genauer zu sagen:
In dem Fall sinkt natürlich die Gewinnwahrscheinlichkeit noch weiter, und zwar auf . |
|||||||||||||||||
| Anzeige | |||||||||||||||||
|
|
|||||||||||||||||
| 02.11.2024, 17:15 | Integer21 | Auf diesen Beitrag antworten » | |||||||||||||||
Meine Tochter hat vorher nach dem 5. Spiel gewonnen, mit Sicherheit ohne optimale Strategie...
Selbst habe ich jetzt schon bestimmt 40 Mal gespielt. Die beste Strategie, die ich bisher ausarbeiten konnte, ist, nur zwei Zahlen abzuhaken, wenn es nicht anders geht. Damit komme ich meistens ziemlich weit, aber eine Zwölf habe ich in den 40 Spielen vieleicht 4 Mal gewürfelt. Sowas könnte mich ewig beschäftigen... |
|||||||||||||||||
| 02.11.2024, 17:32 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Stimmt oft, aber nicht immer: In der Startkonfiguration 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 sowie gewürfelter Augensumme 6 ist es günstiger das Paar 1,5 wegzustreichen statt der 6 - sagt zumindest mein Python-Script. Oder ein Beispiel in der Endphase des Spiels: Sind noch 2, 4, 5, 6 übrig und man würfelt Augensumme 6, dann ist es besser 2,4 zu streichen als die 6. Mit der einfachen Strategie
EDIT: Anbei die kompletten Resultate für die optimale Strategie: Sowohl die Siegwahrscheinlichkeiten für sämtliche Restmengen von verfügbaren Zahlen, als auch die zugehörigen optimalen Auswahlen dafür - allerdings nur für die Fälle, wo noch eine Siegchance besteht. [attach]57975[/attach] |
|||||||||||||||||
| 03.11.2024, 13:13 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Nachgeschoben noch den theoretischen Unterbau: Die Teilmenge repräsentiere die Menge der noch nicht abgehakten Zahlen, und die zugehörige Siegwahrscheinlichkeit ausgehend von dieser Situation und bei optimaler Spielweise. Dann kann man dieses folgendermaßen rekursiv bestimmen: 1) Augensumme im nächsten Wurf erscheint mit (Fall-)Wahrscheinlichkeit . 2) Für jedes solche führt man nun folgendes durch: 2.1) Gilt , so können wir Zahl streichen und bekommen Wahrscheinlichkeit für die Restmenge an Zahlen. Wir setzen in diesem Fall ; für hingegen . 2.2) Jetzt betrachten wir noch die evtl. Möglichkeiten, dass wir zwei verschiedene Zahlen aus streichen können. Es reicht, den Fall zu betrachten, das führt zu . Andererseits müssen natürlich auch sowie (umgestellt ) gelten. Für jedes mit prüfen wir daher nun, ob gilt. Falls ja, dann setzen wir . 2.3) Ist , so ist das Spiel an dieser Stelle verloren, wir haben in diesem Fall die bedingte Siegwahrscheinlichkeit . Andernfalls setzen wir . 3) Wir bekommen über alle Fälle summiert nun einfach die totale Wahrscheinlichkeit . Das ganze funktioniert, weil die Mengen, für die in 2.1) bzw. 2.2) bestimmt werden muss, immer kleiner werden, so dass man in maximal 12 Schritten auf stößt, und dieser Anfangswert ist (das ist, wenn alle Zahlen abgehakt sind, die sichere Gewinnsituation). P.S.: Ein Teil des Pythoncodes ist nur dazu da, die Maximumbildung in 2.3) sowie auch die Rechnung (*) exakt mit rationalen Zahlen durchzuführen. Wenn man zusätzlich die optimale Strategie erfahren will, muss man in 2.3) noch mitloggen, ob nun in 2.1) oder welches in 2.2) zu dem Maximum gehört. |
|||||||||||||||||
| 03.11.2024, 21:41 | Integer21 | Auf diesen Beitrag antworten » | |||||||||||||||
Wow, danke für die ausführliche Erklärung
Python kann ich nicht besonders gut, und ich war überrascht, dass die zugrundeliegende Logik gar nicht so kompliziert war. Ich habe die Formeln und Umstellungen nachvollzogen und habe denke ich fast alles verstanden. Wie du allerdings von Zu Kommst habe ich nicht verstanden. Ich komme bei an. Grüße! |
|||||||||||||||||
| 04.11.2024, 06:10 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
für ganze (!) Zahlen ist gleichbedeutend mit , und das ergibt umgestellt . P.S.: Mit (statt ) als letzter -Index würde man im Fall gerader falsch liegen, Beispiel: Für bedeutet das Paar , aber wir wollen hier ja nur verschiedene Zahlen haben. Kleine Testfrage am Rande: Bei wie vielen Mengen gibt es keine Zugmöglichkeit mehr, egal was man würfelt? Und wie sehen diese Mengen aus?
|
|||||||||||||||||
| 10.11.2024, 20:10 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Als Abrundung (und Kontrolle) habe ich die ganze Sache auch mal simuliert: Die Einzelspiele umfassende Simulation ergab 729344 Siege mit der naiven Strategie (s.o.), 951940 Siege mit der optimalem Strategie. In 557906 Spielen führten beide Strategien zum Erfolg - das ergibt dann einen Korrelationskoeffizient . |
|||||||||||||||||
| 12.11.2024, 12:32 | graugraugrau | Auf diesen Beitrag antworten » | |||||||||||||||
„Zuerst möchte ich sagen, dass ich die Logik und die Ideen in Deinen Programmen wirklich sehr schätze. Es ist deutlich, dass Du viele Gedanken investiert hast, um eine funktionale Lösung zu kreieren! Ich habe über einige Möglichkeiten nachgedacht, wie das Programm weiter optimiert werden könnte, falls es Dir recht ist. Eine Option wäre die Verwendung des lru_cache-Features aus dem functools-Modul, um den Cache effizienter zu gestalten. Das könnte die Leistung des Programms mit vielen Funktionsaufrufen verbessern. Mit lru_cache wird die Verwaltung des Caches einfacher und effizienter, da es automatisch die Prüfung vornimmt. Hier ist ein Vorschlag, wie wir den Cache umsetzen könnten: CopyReplit from functools import lru_cache @lru_cache(maxsize=None) # Unbegrenzt, kannst maxsize für eine bestimmte Anzahl an Caches anpassen def prob_rec(v): # ... der restliche Code bleibt unverändert ... Ich würde mich freuen, deine Meinung dazu zu hören oder wenn andere im Forum Anmerkungen haben. Ich hoffe, dass diese Idee hilfreich ist!“ |
|||||||||||||||||
| 12.11.2024, 13:01 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Hast du ausprobiert, ob dieser Cache effizienter als der obige ist? Im übrigen habe ich das ganze (der Simulation wegen - die Wahrscheinlichkeits- und Strategienberechnung war auch in Python schon schnell genug) sowieso nach C++ portiert, und jede Zustandsmenge dort als Integerzahl 0..4095 kodiert - denke nicht, dass das noch wesentlich effizienter geht: Auf einem halbwegs aktuellen i7-Notebookprozessor hat die obige Simulation von Spielen 10,6 Sekunden gedauert (bei Nutzung von 20 Threads), also knapp 100 Millionen Spiele pro Sekunde - das ist schon ganz schön flott. |
|||||||||||||||||
| 12.11.2024, 13:15 | graugraugrau | Auf diesen Beitrag antworten » | |||||||||||||||
Nein, habe ich nicht. Funktioniert eh nicht. |
|||||||||||||||||
| 12.11.2024, 13:17 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Du machst Vorschläge, die nicht funktionieren? Das klingt jetzt ziemlich befremdlich.
|
|||||||||||||||||
| 12.11.2024, 13:54 | graugraugrau | Auf diesen Beitrag antworten » | |||||||||||||||
Bin davon ausgegangen, daß Du das Programm ausprobierst und mit Deiner Erfahrung sofort erkennst daß was nicht stimmt. Bin noch auf der Suche, es sollte eigentlich gehen, gibt aber immer nur (0,1) zurück. |
|||||||||||||||||
| 12.11.2024, 14:07 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Das Problem wird sein, dass die Zeile
Das wird natürlich nicht adäquat ersetzt durch bloßes
|
|||||||||||||||||
| 12.11.2024, 16:39 | graugraugrau | Auf diesen Beitrag antworten » | |||||||||||||||
Ja, das geht. Kannst Du die beiden Versionen testen, ich habe kein reines Testequipment. Da wären die Ergebnisse verfälscht, glaube aber daß Deine Version schneller ist |
|||||||||||||||||
| 12.11.2024, 16:52 | HAL 9000 | Auf diesen Beitrag antworten » | |||||||||||||||
Hmm, ich hab mal die Zeiten gemessen, mit je 5 Wiederholungen: 1) Meine Originalversion: Zeiten zwischen 69 und 71ms 2) lru_cache-Version: Zeiten zwischen 66 und 70ms 2) scheint eine Nuance schneller zu sein, aber so richtig signifikant sieht das nicht aus. |
|||||||||||||||||
| 13.11.2024, 10:15 | graugraugrau | Auf diesen Beitrag antworten » | |||||||||||||||
Ja, stimmt, danke für die Tests |
|||||||||||||||||
|
|
Verwandte Themen
| Die Beliebtesten » |
|
| Die Größten » |
|
| Die Neuesten » |
