La bonne paye et probas

La bonne paye et probas - Aide aux devoirs - Emploi & Etudes

Marsh Posté le 28-06-2019 à 19:42:33    

Bonjour à tous
Je viens demander de l'aide sur un devoir de maths donné par ..... moi-même.
Un peu de contexte, par ces chaleurs caniculaires, alerte rouge, 43-44 °C à l'ombre, petite partie (au frais ...) avec les enfants de "La bonne paye" auquel je n'avais joué.Apprentissage rapide des règles, et puis essais d'optimisations.
J'ai rapidement compris que les acquisitions/ventes étaient une clé pour avoir du cash sur le long terme, d'où ma question, en moyenne sur un tour de jeu, combien de fois je tombe sur case "Vente" ?
Il y a en tout 4 cas ventes (9, 20, 23 et 29) sur 31 en tout.
En première intuition, je pensais que cela devrait être un poil plus de 0.5 par rapport à mon vécu dans le jeu.
Mathématiquement, je traite le problème comme ceci :
Sachant que l'espérance du dé est 3.5, il y a donc en moyenne 31/3.5 coups dans un tour de jeu. Que la probabilité de tomber sur une case "Vente" est de 4/31, donc le nombre moyen devrait être de (31/3.5)*(4/31) soit environ 1.143 contredisant mon intuition.
J'ai donc réalisé un petit programme me permettant de simuler ce jeu, et je tombe sur environ 1.152, ce qui n'est certes pas loin sauf que j'ai lancé cette simulation avec un nombre de tours qui me donne un intervalle de fluctuation au seuil de 95 % à moins de 0.001 et donc que cela fait beaucoup d'écart.
 
 
Si quelqu'un a une idée ou peut confirmer ou infirmer mon raisonnement ?
Merci

Reply

Marsh Posté le 28-06-2019 à 19:42:33   

Reply

Marsh Posté le 29-06-2019 à 09:52:57    

C'est ça qui cloche.
 

Ze_Fab a écrit :


la probabilité de tomber sur une case "Vente" est de 4/31, donc le nombre moyen devrait être de (31/3.5)*(4/31)


 
Si tu ne vois pas pourquoi, essaie de simuler le jeu en changeant les cases "Vente" sur (1, 2, 3 et 4). Regarde le résultat.

Reply

Marsh Posté le 29-06-2019 à 11:23:36    

Je ne vois pas l'erreur dans mon raisonnement, il faudrait que tu m'expliques pourquoi cela cloche.
 
Je vais recommencer la simulation en changeant les paramètres et en utilisant un langage de programmation plus performant.

Reply

Marsh Posté le 29-06-2019 à 12:34:10    

C'est parce que tu pars du principe que la probabilité de tomber sur chaque case est la même.
 
Si tu changes les cases comme je te dis, tu verrais pourquoi.

Reply

Marsh Posté le 30-06-2019 à 11:46:51    

Après avoir codé le simulateur en python3, j'obtiens 1.143 environ après 10 000 000 de tours, ce qui correspond à ma prévision par le calcul de proba, mon écart venait sûrement du générateur pseudo aléatoire de scratch 1.4 que j'utilisais.
J'ai essayé comme tu m'as dit avec les nombres 1,2,3 et 4 à la place de 9, 20, 23 et 29, j'obtiens le même résultat à 10^-4 près.
Voilà le programme :

Code :
  1. tour = 0
  2. n = 0
  3. vendu =0
  4. caseven = [9,20,23,29]
  5. import random
  6. while True:
  7.     n+=random.randint(1,6)
  8.     if n>31:
  9.         n-=31
  10.         tour+=1
  11.         if tour % 1000000== 0:
  12.             print(tour," --> ",vendu/tour)
  13.     if n in caseven:
  14.         vendu+=1


Exécuté en python 3.7.3.
En laissant tourner jusqu'à 50 000 000, j'ai mon 4ème chiffre décimal et presque le cinquième.

Reply

Marsh Posté le 30-06-2019 à 13:18:45    

Je vais reprendre les points et les hypothèses un par un. Comme fil rouge, je vais simplifier le problème et réduire le nombre de cases à 7 (au lieu de 31), avec une seule case "Vente" en [1], et ça va servir de contre-exemple tout du long du post.
 

Citation :

Sachant que l'espérance du dé est 3.5, il y a donc en moyenne 31/3.5 coups dans un tour de jeu.


 
Non, ce n'est pas exact. Tu pars de la case départ, imagine combien de coups tu as besoin pour arriver à 7. Avec ton raisonnement, ça fait 7/3.5 = 2 en moyenne.  
Sauf que c'est faux, puisque dans tous les cas, tu as besoin au minimum de deux lancers pour atteindre 7. Et en réalité, souvent tu auras besoin de plus de 2 (comme 7 lancers de 1, 4 lancers de 2, 2 lancers de 3 + 1 autre de 1 ou 2, etc.).  
Donc en réalité, tu as en moyenne plus de 2 coups (en réalité, environ 2.5 coups), ce que ton raisonnement ne permet pas de déduire.
 

Citation :

Que la probabilité de tomber sur une case "Vente" est de 4/31


 
La raison pour laquelle j'ai proposé de changer les cases "Vente", c'était pour montrer que la probabilité de tomber sur chaque case n'est pas la même.
Ta dernière simulation n'a pas trouvé de différence, mais c'est parce qu'elle n'est pas bonne. J'y viens plus tard.
Dans le contre-exemple, avec ton raisonnement, comme il y a 1 case "Vente" sur 7, ça fait une probabilité de 1/7.
Or, il n'y a qu'une seule façon d'atteindre la case [1]. C'est de faire 1 avec le dé au premier tour. Donc une probabilité de 1/6, et non pas 1/7.
 

Citation :

donc le nombre moyen devrait être de (31/3.5)*(4/31) soit environ 1.143 contredisant mon intuition.


 
Ben du coup, c'est pas bon parce que les deux nombres sont mauvais.
 

Citation :

Voilà le programme :  
#Code#


 
Ta simulation a plusieurs défauts, ce qui te fait trouver une probabilité différente de la vraie probabilité.
 
1) Dans un tour de jeu, tu débutes toujours et tu termines toujours par la case [Départ] ou [31]. Les deux cases sont équivalentes puisque lorsque que tu atteins [31], tu te retrouves sur la case [Départ].
Dans ta simulation, tu ne prends pas ça en compte, et donc ça donne un résultat différent.
Tu mets les tours à la suite des autres et tu ne t'arrêtes pas sur [31/Départ].
 
2) Tu ne prends pas en compte la case [26] (changement d'heure). La case te fait reculer, ce qui augmente la probabilité de tomber plus tard sur la case "Vente" en [29].
 
3) Les autres joueurs peuvent aussi tomber sur la case [26] et te faire reculer. Mais le modèle devient compliqué, alors que les deux règles précédentes sont simples à implémenter.
 
J'ai fait un calcul théorique avec les 2 premières hypothèses et je tombe sur 1.150. Normalement, la 3e règle devrait aussi faire augmenter la probabilité, mais ça dépend du nombre de joueurs.

Reply

Marsh Posté le 30-06-2019 à 14:27:53    

N'empêche, je suis admiratif que vous vous posiez ces questions (et que vous essayez d'y répondre :-) )

Reply

Marsh Posté le 30-06-2019 à 17:54:42    

Plusieurs choses :
- D'abord merci pour le temps passé à me répondre, j'apprécie d'avoir un interlocuteur qui sait de plus de quoi il parle.
- Ensuite plusieurs mea culpa :
Un pour lequel je plaide pleinement coupable, la case "Changement d'heure" qui modifie la probabilité pour chaque case, la case 25 a une probabilité plus élevée que les autres, ce qui faussement pleinement mon raisonnement.
Un pour lequel je plaide coupable mais pas responsable, ce sont mes enfants qui m'ont expliqué les règles, et en fin de mois d'après eux lorsque l'on arrive au niveau de la case 31, on continue à avancer, comme le monopoly par exemple, ce qui fausse complètement le résultat. Là où je voyais une probabilité uniforme, c'est beaucoup plus complexe, et donc mon raisonnement tombe à plat en prenant les vraies règles.
J'ai donc repris mon raisonnement à 0, j'ai d'abord commencé par prendre un jeu avec 7 cases, et en définissant la variable aléatoire X qui donne le nombre de coups pour arriver à la case 7 ou plus.
P(X=7) =  1 /6^6 ça reste facile
P(X=1) = 0 là, ça va
P(X=2) = .....1 et 6 -> p = 1/36
2 et (5 ou 6) -> p = 2/36
3 et (4, 5 ou 6) -> p = 3/36
etc
P(X=2 )= 7/12
A partir de là, j'ai automatisé les choses

Code :
  1. def reste(case,coup):
  2.     if case<=0:
  3.         if coup==0:
  4.             return 1
  5.         else:
  6.             return 0
  7.     if coup==0:
  8.         return 0
  9.     r=0
  10.     for i in range(1,7):
  11.         r+=reste(case-i,coup-1)/6
  12.     return r
  13. verif=0
  14. t = 0
  15. moyenne = 0
  16. nbrcase = int(input("Nombre de cases ";))
  17. for i in range(1,nbrcase+1):
  18.     t= reste(nbrcase,i)
  19.     verif+= t
  20.     moyenne+=i*t
  21.     print("P(X=",i,";)=",t)
  22. print("E(X) = ",moyenne)
  23. print(verif)


Message édité par Ze_Fab le 30-06-2019 à 17:57:04
Reply

Marsh Posté le 30-06-2019 à 18:04:22    

Ayant buggué sur mon post, je continue ici
Je trouve

Nombre de cases 7
P(X= 1 )= 0.0
P(X= 2 )= 0.5833333333333333
P(X= 3 )= 0.324074074074074
P(X= 4 )= 0.08101851851851852
P(X= 5 )= 0.010802469135802467
P(X= 6 )= 0.0007501714677640601
P(X= 7 )= 2.143347050754458e-05
E(X) =  2.521626371742112
0.9999999999999998


 
J'ai donc lancé mon programme avec 31 cases, et là, je savais que cela allait faire mal en temps de calcul  .....
Je l'ai donc joué à façons Loi des Grands Nombres

Code :
  1. tour = 0
  2. n = 0
  3. totalcoup = 0
  4. coup = 0
  5. import random
  6. nbrcase = int(input("Entrer le nombre de case " ))
  7. while True:
  8.     n+=random.randint(1,6)
  9.     coup+=1
  10.     if n>=nbrcase:
  11.         n=0
  12.         tour+=1
  13.         totalcoup+=coup
  14.         coup=0
  15.         if tour % 1000000== 0:
  16.             print(tour," --> ",totalcoup/tour)


Après plusieurs centaines de millions de tours, j'oscille autour de 9,33335
Au moment où j'écris ces lignes, mon programme de calcul "théorique" est à P(X=18)=5.89996...e-6 avec une espérance partielle de 9.33331...., on n'est pas loin.


Message édité par Ze_Fab le 30-06-2019 à 18:05:22
Reply

Marsh Posté le 30-06-2019 à 18:12:18    

Je n'ai pas tenu compte de la case "Changement d'heures", en modifiant le script précédent, je trouve : 9.43901
Dans les deux cas loin de mon 31/3.5.
Devant la complexité de la situation, j'ai laissé tomber une approche théorique, donc en exécutant :

 
Code :
  1. tour = 0
  2. n = 0
  3. vendu =0
  4. caseven = [9,20,23,29]
  5. import random
  6. while True:
  7.     n+=random.randint(1,6)
  8.     if n>=31:
  9.         n=0
  10.         tour+=1
  11.         if tour % 1000000== 0:
  12.             print(tour," --> ",vendu/tour)
  13.     if n in caseven:
  14.         vendu+=1
 

On trouve environ 1.13739
Et si on modifie en tenant compte de la case 26, c'est 1.15035, le tout simulé près de 500 millions de fois.

 

J'avoue que je n'ai pas cherché à rajouter la présence d'autres joueurs.....
Merci à ceux qui ont eu le courage de me lire jusqu'au bout.


Message édité par Ze_Fab le 30-06-2019 à 18:12:56
Reply

Marsh Posté le 30-06-2019 à 18:12:18   

Reply

Marsh Posté le 30-06-2019 à 21:44:18    

Comme tu as maintenant trouvé la réponse, je joins le code que j'ai utilisé pour calculer la probabilité théorique.
 

Code :
  1. import numpy as np
  2. nombre_case = 31
  3. #Remplissage de Q matrice de transition
  4. Q = np.zeros((nombre_case+1,nombre_case+1))
  5. i = 0
  6. for row in range(Q.shape[0]):
  7.   if row < Q.shape[0]-6:
  8.     for column in range(row+1, row+7):
  9.       Q[row, column] = 1/6
  10.   elif row == Q.shape[0]-1:
  11.     Q[row, row] = 1
  12.   else:
  13.     i += 1
  14.     for column in range(row+1, row+6-i):
  15.       Q[row, column] = 1/6
  16.     Q[row, row+6-i] = (1+i)/6
  17.    
  18. #Correction case 26
  19. for row in range(20,26):
  20.   Q[row, 25] += 1/6
  21.   Q[row, 26] = 0
  22. Q[26,:] = np.zeros(nombre_case+1)
  23. #Probabilités marginales
  24. margs = []
  25. margs.append(np.zeros((1,nombre_case+1)))
  26. margs[0][0,0] = 1
  27. for step in range(50):
  28.   margs.append(np.matmul(margs[step], Q))
  29. proba = np.zeros((1,nombre_case+1))
  30. for marg in margs:
  31.   proba += marg
  32.  
  33. #Cases d'intérêt
  34. cases = [9, 20, 23, 29]
  35. expect = 0
  36. for case in cases:
  37.   expect += proba[0,case]
  38. print(expect)

Reply

Marsh Posté le 01-07-2019 à 10:30:54    

Merci pour ce script, je n'étais pas allé jusqu'à modéliser le problème par une matrice stochastique, je suis étonné de voir qu'avec seulement 50 itérations on ait déjà une bonne estimation de la limite.
Par curiosité, j'ai simulé l'impact de cette case 26 quand on joue avec plusieurs joueurs, intuitivement, la probabilité doit augmenter.

Code :
  1. import random
  2. import numpy
  3. def testevente(joueur):
  4.     if case[joueur] in casevente:
  5.         vendu[joueur]+=1
  6.     elif case[joueur]==26:
  7.         for joueur2 in range(nbrjoueur):
  8.             if case[joueur2]!=0:
  9.                 case[joueur2]-=1
  10.             else:
  11.                 case[joueur2]=31
  12.                 tour[joueur2]-=1
  13.         for joueur2 in range(nbrjoueur):
  14.             testevente(joueur2)
  15. nbrjoueur=0
  16. while not(nbrjoueur in range(1,7)):
  17.     nbrjoueur= int(input("Nombre de joueurs ";))
  18. case = numpy.zeros(nbrjoueur,dtype=int)
  19. vendu = numpy.zeros(nbrjoueur,dtype=int)
  20. tour = numpy.zeros(nbrjoueur,dtype=int)
  21. nbrcoups = 0
  22. casevente = [9,20,23,29]
  23. while True:
  24.     nbrcoups+=1
  25.     for joueur in range(nbrjoueur):
  26.         case[joueur]+=random.randint(1,6)
  27.         if case[joueur]>=31:
  28.             case[joueur]=0
  29.             tour[joueur]+=1
  30.         else:
  31.             testevente(joueur)
  32.     if nbrcoups % 1000000 ==0:
  33.         tours=0
  34.         vendus=0
  35.         for joueur in range(nbrjoueur):
  36.             print("joueur ",joueur," moyenne : ",vendu[joueur]/tour[joueur])
  37.             tours+=tour[joueur]
  38.             vendus+=vendu[joueur]
  39.         print("Nombre de coups : ",nbrcoups," moyenne joueurs : ", vendus/tours,"n";)


Je suis étonné des résultats, je m'attendais à une augmentation mais pas aussi substantielle :
 
1 joueur : 1.1503
2 joueurs : 1.2095
3 joueurs : 1.2757
4 joueurs : 1.3512
5 joueurs : 1.4364
6 joueurs : 1.5345
 
Sans vouloir être indiscret, j'aimerais connaître ta formation/emploi car tu as l'air de bien maîtriser le sujet.


Message édité par Ze_Fab le 01-07-2019 à 10:31:58
Reply

Marsh Posté le 01-07-2019 à 11:58:53    

En fait, les itérations de mon script représentent le nombre de lancers de dés pour finir un tour. Il est techniquement possible de terminer un tour en plus de 50 lancers (en tombant infiniment sur [26]), mais c'est tellement peu probable que ça ne change pas le résultat à la précision du float près.  
 
Je suis ingé en informatique, mais je m'intéresse aux maths ;)  
 
 
Enfin, peut-être encore quelques axes d'amélioration :
 
1) Comme la case [31] et [0] sont équivalentes, on peut simplifier et tout simplement enlever la case [31]. Dans ce cas là, le joueur arrive sur [0] lorsqu'il dépasse [30] et il ne bouge pas lorsqu'un autre le joueur arrive sur [26].
Je me trompe peut-être, mais il me semble que dans ton code, si un joueur recule alors qu'il est en [0], il va en [31] et "gâche" un lancer supplémentaire pour revenir en [0].
Il me semble que le joueur qui recule en [31] doive réaliser les actions "Jour de paye" et donc retourner directement en [0].
 
2) Si un joueur est en [27], si quelqu'un le fait reculer, il doit sauter la case [26] et se retrouve en [25] (donc pas de changements d'heure "à la chaîne" ).
 
Je pense que 1) ne devrait pas avoir trop d'impact sur les chiffres.
2) devrait faire un peu baisser les probabilités lorsque le nombre de joueurs augmente.

Reply

Marsh Posté le 01-07-2019 à 13:44:16    

Effectivement, il y a un bug et je "gâche" un tour, j'ai corrigé et j'a relancé :  
 
1 joueur  : idem (normal)
2 joueurs : 1.2082
3 joueurs : 1.2733
4 joueurs : 1.3463
5 joueurs : 1.4287
6 joueurs : 1.5270
 
La proba baisse légèrement et quand le nombre de joueur augmente l'écart aussi, ça reste cohérent.
 
Tu t'intéresses aux maths avec efficacité apparemment .....

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed