Aléatoire : test du poker | effectifs vers probabilités

Aide à la résolution d'exercices ou de problèmes de niveau Lycée.

Modérateur: gdm_aidesco

Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser le mode LaTeX (voir ici) afin de rendre vos formules plus lisibles.
> Ne poster qu'un exercice (ou problème) par sujet et indiquer son niveau précis dans le titre du message.

Aléatoire : test du poker | effectifs vers probabilités

Messagepar SimonPaulL » Mercredi 31 Janvier 2018, 20:25

Bonsoir tout le monde !

Dans le cadres de mon TPE, je suis amené à faire le test du poker sur la fonction randint() de python.

Ce test travail par bloc de 4 nombres qu'il classe dans une des catégorie suivante :
- les quatres chiffres sont différents. probabilité = 0,504
- il y a une pair et deux chiffres différents. probabilité=0,432
- il y a deux pair. probabilité=0,027
- il y a 3 chiffres identiques. probabilité=0,036
- il y a 4 chiffres identiques. probabilité=0,001
Ce lien explique comment il est réalisé et explique d'où viennent les probabilitées : https://univers-ti-nspire.fr/files/pdf/ ... -TNS21.pdf

J'arrive très bien a avoir une liste final avec le nombre de fois qu’apparaît chaque configuration mais je n'arrive pas à en tiré les probabilités.
Les chiffres que je trouve sont très loin des probabilité théoriques auquel c'est sensé se rapproché.
Voici l'algorithme écris sur le lien précédent : https://www.noelshack.com/2018-05-3-151 ... 201427.png

Et voici mon code actuel écris en python :
Code: Tout sélectionner
from random import randint
from functools import reduce
from operator import mul

def poker(nbChiffre=1000):
   '''Test du poker'''
   count = {"AAAA":0,"AAAB":0,"AABB":0,"AABC":0,"ABCD":0}
   values = [[randint(0,9),randint(0,9),randint(0,9),randint(0,9)] for i in range(nbChiffre//4)] # Je remplis une liste de paquet contenant 4 chiffres aléatoires
   for paquet in values:
               # Je test la configuration du paquet et j'ajoute un a la clé correspondante dans le dictionnaire
      paquet = [paquet.count(valeurPaquet) for valeurPaquet in paquet]
      paquet = reduce(mul,paquet)
      if paquet == 1:
         count["ABCD"]+=1
      elif paquet == 4:
         count["AABC"]+=1
      elif paquet == 16:
         count["AABB"]+=1
      elif paquet == 27:
         count["AAAB"]+=1
      elif paquet == 256:
         count["AAAA"]+=1
   return count # retourne le dictionnaire avec les effectifs pour chaque configuration (donc pas une probabilité)


Voilà j'espère que vous pourrais l'aider a comprendre comment passé des effectifs au probabilité.
Merci par avance de votre aide,
Simon
SimonPaulL
Déca-utilisateur
 
Messages: 20
Inscription: Vendredi 06 Janvier 2017, 19:09
Statut actuel: Lycée | 2nde

Publicité

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar rebouxo » Mercredi 31 Janvier 2018, 22:51

Que fait reduce ? Que fait mul ?
Olivier
A line is a point that went for a walk. Paul Klee
Par solidarité, pas de MP
rebouxo
Modérateur
 
Messages: 6901
Inscription: Mercredi 15 Février 2006, 13:18
Localisation: le havre
Statut actuel: Actif et salarié | Enseignant

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar SimonPaulL » Jeudi 01 Février 2018, 07:10

rebouxo a écrit:Que fait reduce ? Que fait mul ?
Olivier

Je ne sais pas ce que fait reduce en temps normal mais dans ce cas ci, reduce(mul, une_liste) mais multiplier tout les termes de la liste entre eux. Cela permet d'avoir un nombre unique lié à la configuration pour pouvoir la reconnaître.

EDIT : La fonction reduce applique en faite une fonction (ici mul, la multiplication) au premier et second élement de la liste, puis au résultat obtenu avec le troisème élement et ainsi de suite jusqu'à ce qu'il ne reste plus d'un seul nombre.
Cette fonction vient du paquet functools
SimonPaulL
Déca-utilisateur
 
Messages: 20
Inscription: Vendredi 06 Janvier 2017, 19:09
Statut actuel: Lycée | 2nde

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar rebouxo » Vendredi 02 Février 2018, 11:30

J'ai abondamment commenté ton code. Maintenant je suis à peu près persuadé qu'il fait ce que tu cherches à faire.
Cela dit je ne vois pas pourquoi tu n'utilises pas des noms différents pour tes variables (et des noms plus explicites).
Tu simules 1000 mains, pourquoi alors diviser par le nombre de cartes distribuées ?
C'est bien pratique de regarder le contenu des différentes variables.

Code: Tout sélectionner
from random import randint
from functools import reduce
from operator import mul

def poker(nbChiffre=1000):
    '''
    Test du poker Construit 1000 mains de poker,
    puis tests si les mains sont constituées de la même
    carte, ou d'un brelan de 2 pairs, 4 cartes identiques
    '''
    count = {"AAAA":0,"AAAB":0,"AABB":0,"AABC":0,"ABCD":0}
    # Je remplis une liste de paquet contenant 4 chiffres aléatoires
    ## pourquoi ne pas pas partir sur 1000 mains au lieu de 250 ?
    values = [[randint(0,9),randint(0,9),randint(0,9),randint(0,9)] for i in range(nbChiffre)]
    for paquet in values: ## pourquoi paquet au lieu de main
        print(paquet,reduce(mul,paquet))
        # Je test la configuration du paquet et j'ajoute un a la clé correspondante dans le dictionnaire
        ## tu utilises un paquet (une main) de tes 1000 tirages
        ## et tu réécris tout de suite dessus.
        ## C'est voulu ?
        ## Que fais-tu ici ?
        paquet = [paquet.count(valeurPaquet) for valeurPaquet in paquet]
        print(paquet)
        ## Pareil pourquoi garder le même nom ?
        paquet = reduce(mul,paquet) ## pourquoi pas typeMain ?
        print(paquet)
        if paquet == 1:
            count["ABCD"]+=1
        elif paquet == 4:
            count["AABC"]+=1
        elif paquet == 16:
            count["AABB"]+=1
        elif paquet == 27:
            count["AAAB"]+=1
        elif paquet == 256:
            count["AAAA"]+=1
        # retourne le dictionnaire avec les effectifs pour chaque configuration
        #(donc pas une probabilité)
    return count

print poker(10)
A line is a point that went for a walk. Paul Klee
Par solidarité, pas de MP
rebouxo
Modérateur
 
Messages: 6901
Inscription: Mercredi 15 Février 2006, 13:18
Localisation: le havre
Statut actuel: Actif et salarié | Enseignant

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar SimonPaulL » Samedi 03 Février 2018, 16:35

Bonjour et merci de ton aide.

1) Il est vrai que 1000 mains est mieux que seulement 250 mains. En faite, j'avais raisonné sur le nombre de chiffres (raisonnement faux). Dans mon doc final, je l'avais fait avec 1 million de chiffres (donc 250000 mains)

2) J'ai appelé paquet au lieux de mains de façon arbitraire, les deux fonctionnes mais tu as raison qu'avec "poker" on à tendance à penser "main"

3) Ce que je réécris dessus c'est en faite le nombre de fois où la valeurs apparaît dans la mains. Donc [7,7,7,3] devient [3,3,3,1] par exemple. C'est le rôle de :
Code: Tout sélectionner
paquet = [paquet.count(valeurPaquet) for valeurPaquet in paquet]

Ensuite je les multiplies entre eux pour avoir un identifiant unique de la configuration : 3*3*3*1=27 donc la configuration AAAB. C'est le rôle de :
Code: Tout sélectionner
paquet = reduce(mul,paquet)

Tu as raisons que pour la lisibilité du code, il vaudrait mieux que je mette typeMain. J'avais bêtement réfléchi sur le nombre de variables que j'utilise. Quand j'écris par dessus à partir de la valeurs précédente, c'est parce que je n'ai justement plus besoin de la valeur précédente (c'est pourquoi ma variable s'appelle paquet tout au long de la boucle)

4) Et c'est justement là que tu touches le cœur du problème : je me retrouve avec des effectifs alors que je veux des probabilités. J'ai pensé dans un premier temps qu'il fallait diviser chaque valeurs du dictionnaire par le nombre de chiffre total. Mais cela ne correspond pas au valeurs que je suis sensé trouver et je ne sais pas par quoi diviser. Cela dit, l'ordre de grandeur est respecté quand je divise chaque valeurs par le nombre de chiffre (ABCD>AABC>AAAB>AABB>AAAA)

Mon problème est donc bien de trouver comment passer des effectifs aux probabilités...
Merci de tes conseil cela va améliorer la compréhension.
Simon.
SimonPaulL
Déca-utilisateur
 
Messages: 20
Inscription: Vendredi 06 Janvier 2017, 19:09
Statut actuel: Lycée | 2nde

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar rebouxo » Samedi 03 Février 2018, 18:45

Ben c'est là que le nombre de tirage est important. Si tu as 1000 mains, tes valeurs sont conformes à ce que tu attends (enfin sur un essai). Les probas se faisant par rapport aux mains et non aux cartes distribuées. C'est bien les différents types de mains que tu étudies ?

Je ne suis pas certain que de réécrire dans des variables parce que l'on n'en a plus besoin soit une très bonne idée. Certes tu économises quelques octets, mais la lisibilité du code est catastrophique.

Personnellement sur ton code, je lui reproche sa mauvaise lisibilité. C'est du au peu de commentaires et aussi au fait que tu réutilises des variables. Très clairement, j'aurais pris : main pour paquet, puis cartes pour paquet, enfin le dernier je l'aurais appelé type ou discriminant (très clairement cela discrimine ta main).

Les probas en découlent immédiatement.

Olivier
A line is a point that went for a walk. Paul Klee
Par solidarité, pas de MP
rebouxo
Modérateur
 
Messages: 6901
Inscription: Mercredi 15 Février 2006, 13:18
Localisation: le havre
Statut actuel: Actif et salarié | Enseignant

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar SimonPaulL » Samedi 03 Février 2018, 18:58

Je te remercie beaucoup celà fonctionne !

Je vais modifié mon code suite à tes conseil. En effet je ne l'avais pas commenté pour moi par soucis de timing et je ne l'ai fait que dans mon document final.
Je vais aller changer le nom des variables et commenter tout ça de suite :D

Encore merci à toi Olivier et bonne continuation :)
Cordialement,
Simon.
SimonPaulL
Déca-utilisateur
 
Messages: 20
Inscription: Vendredi 06 Janvier 2017, 19:09
Statut actuel: Lycée | 2nde

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar MB » Samedi 03 Février 2018, 19:00

SimonPaulL a écrit:4) Et c'est justement là que tu touches le cœur du problème : je me retrouve avec des effectifs alors que je veux des probabilités. J'ai pensé dans un premier temps qu'il fallait diviser chaque valeurs du dictionnaire par le nombre de chiffre total. Mais cela ne correspond pas au valeurs que je suis sensé trouver et je ne sais pas par quoi diviser.


Il faut bien effectuer cette division. Par exemple en remplaçant la dernière commande par la suivante.

Code: Tout sélectionner
return {k:v/nbChiffre for k,v in count.items()}


En faisant une tentative avec nbChiffre valant 50000 et j'ai trouvé.

Code: Tout sélectionner
{'AAAA': 0.00082, 'AAAB': 0.03612, 'AABB': 0.02784, 'AABC': 0.4305, 'ABCD': 0.50472}
MB (Pas d'aide en Message Privé)
Merci d'utiliser $\LaTeX$ (voir ici) et d'éviter le style SMS pour la lisibilité des messages.
MB
Administrateur
 
Messages: 6873
Inscription: Samedi 28 Mai 2005, 13:23
Localisation: Créteil
Statut actuel: Actif et salarié | Enseignant

Re: Aléatoire : test du poker | effectifs vers probabilités

Messagepar SimonPaulL » Samedi 03 Février 2018, 19:43

Entre temps j'ai modifié mon code pour qu'il fasse les probabilités :

Code: Tout sélectionner
from random import randint
from functools import reduce
from operator import mul
from decimal import Decimal as d

compteur = {"AAAA":0,"AAAB":0,"AABB":0,"AABC":0,"ABCD":0}
# On crée une liste de n mains de 4 chiffres
listeMains = [[randint(0,9),randint(0,9),randint(0,9),randint(0,9)] for i in range(n)]
for main in listeMains:
  # On remplace chaque valeur par le nombre de fois que cette valeur existe dans la main
  typeConfig = [main.count(carte) for carte in main]
  typeConfig = reduce(mul, typeMain) # On multiplie chaque nombre entre eux
  # On traîte chaque cas
  if typeConfig == 1:
    compteur["ABCD"]+=1
  elif typeConfig == 4:
    compteur["AABC"]+=1
  elif typeConfig == 16:
    compteur["AABB"]+=1
  elif typeConfig == 27:
    compteur["AAAB"]+=1
  elif typeConfig == 256:
    compteur["AAAA"]+=1
# Enfin, on passe des effectifs au probabilités
for config,valeur in compteur.items():
  compteur[config] = valeur/nbChiffre
return compteur


Et je préférerais sans doute cette façon de faire les probabilités (voir ma dernière boucle for) car je la pense plus lisible (remarque je ne m'avance pas trop sur la lisibilité de mon code :lol: )

Néanmoins je te remercie MB car je ne connaissais pas du tout cette syntaxe ! Enfin je la connaissais pour les listes mais pas pour les dico...
Je vais changer avec ta façon dans le code source qui sera disponible avec mon dossier final.
Et oui c'est exactement ce que je dois trouver :D

Encore merci à vous deux,
Simon.
SimonPaulL
Déca-utilisateur
 
Messages: 20
Inscription: Vendredi 06 Janvier 2017, 19:09
Statut actuel: Lycée | 2nde


Retourner vers Exercices et problèmes : Lycée

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 4 invités