Problème de Monty Hall

Fermé
maxos68000 Messages postés 1 Date d'inscription dimanche 3 octobre 2021 Statut Membre Dernière intervention 3 octobre 2021 - Modifié le 5 oct. 2021 à 13:05
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 6 oct. 2021 à 11:07
Bonjour,

Je souhaiterais programmer une illustration du phénomène de Monty Hall.

Cependant mes valeurs ne correspondent pas du tout aux résultats attendus. Je suis plutôt sur du 50/50.

Pouvez-vous regarder ce qu'il ne va pas dans mon code s'il vous plaît ?

Merci

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

def jeu(strategie):    
    portes = [i+1 for i in range(3)]
    choix_joueur = np.random.choice(portes)
    porte_gagnante = np.random.choice(portes)
    porte_eliminee = np.random.choice(portes)
    if choix_joueur == porte_eliminee:
        resultat = 0
    elif strategie == "garder" :
        portes.remove(porte_eliminee)
        if porte_gagnante == choix_joueur:
            resultat = 1
        else :
            resultat = 0
    else :
        portes.remove(porte_eliminee)
        portes.remove(choix_joueur)
        if porte_gagnante == portes:
            resultat = 1
        else :
            resultat = 0
    return resultat

garder = np.sum([jeu("garder") for i in range(1000)])
changer = np.sum([jeu("changer") for i in range(1000)])
print(garder)
print(changer)
plt.figure()
plt.bar(1, garder)
plt.bar(2, changer)


Configuration: Windows / Chrome 94.0.4606.61


Edit: ajout des balises de code et de la partie manquante du script

3 réponses

yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476
3 oct. 2021 à 21:36
bonjour,
peux-tu préciser le langage, python, quand tu utilises les balises de code? explications: https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

ton code donne des erreurs: es-tu certain d'avoir partagé le code complet?

à quoi sert la seconde ligne dans ce code?
    elif strategie == "garder" :
        portes.remove(porte_eliminee)

tu n'utilises plus
portes
par la suite.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 5 oct. 2021 à 13:17
Bonjour,

Si l'on s'en tient à la définition du problème de Monty Hall, la porte éliminée ne peut être ni la porte gagnante, ni la porte choisie par le joueur. Or dans ton code, rien n'empêche ces situations d'arriver, ce qui peut engendrer un biais statistiques sur tes simulations.
Le début du programme ressemblerait donc plus à ça :

...
    portes = [i+1 for i in range(3)]
    choix_joueur = np.random.choice(portes)
    porte_gagnante = np.random.choice(portes)
    portes_eliminables = [
        porte
        for porte in portes
        if porte != choix_joueur and porte != porte_gagnante
    ]
    porte_eliminee = np.random.choice(portes_eliminables)                   
    portes.remove(porte_eliminee)
...


Ensuite dans ton code, tu compares (l23) une liste à un entier, donc ce test est toujours faux. Il faudrait à la rigueur le comparer
portes[0]
(qui ne contient plus qu'une porte).

Enfin, comme le souligne yg_be, le contenu de
portes
ne sert pas à grand chose. Ton programme s'écrit bien plus simplement :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
import numpy as np
import matplotlib.pyplot as plt
 
def jeu (strategie):
    portes = [i+1 for i in range(3)]
    choix_joueur = np.random.choice(portes)
    porte_gagnante = np.random.choice(portes)
#    portes_eliminables = [
#        porte
#        for porte in portes
#        if porte != choix_joueur and porte != porte_gagnante
#    ]
#    porte_eliminee = np.random.choice(portes_eliminables)                   
#    portes.remove(porte_eliminee)
    return (
        int(porte_gagnante == choix_joueur) if strategie == "garder"
        else int(porte_gagnante != choix_joueur)
    )
 
garder = np.sum([jeu("garder") for i in range(1000)])
changer = np.sum([jeu("changer") for i in range(1000)])
print(garder)
print(changer)
plt.figure()
plt.bar(1, garder)
plt.bar(2, changer)


Bonne chance
0
yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476
Modifié le 5 oct. 2021 à 13:59
il me semble que la comparaison entre un entier et une liste à un élément fonctionne bien.
import numpy
p=[0]
i=numpy.random.choice(p)
print(i,p)
if i == p:
    print("ok")
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024
5 oct. 2021 à 15:07
Effectivement, car
i
est ici un
numpy.int64
qui supporte la comparaison avec un itérable, mais ça n'en reste pas moins un abus d'écriture qui selon moi nuit à la lisibilité du code : il faudrait en toute rigueur écrire
i == p[0]
sinon le test plante quand l'itérable a plusieurs éléments.
0
yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476 > mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024
5 oct. 2021 à 16:42
p[0]
plantera quand la liste est vide.
0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749 > yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024
Modifié le 6 oct. 2021 à 11:08
Oui, de même que
i == p
. Et c'est pour ça que dans le cas général, il faudrait vérifier si
p
est non vide. Mais bon, dans le code proposé ça ne peut pas arriver.
0
Yaronne_7561
5 oct. 2021 à 13:26
un sujet très intressant car ce petit souci peut bloqué tout le monde!! Merci à tous vos conseils!
0