Contenu principal
Chapitre 7 · Les listes › Leçon 8 sur 8

Le paradoxe des anniversaires

D'après-toi si 30 personnes sont réunies dans une pièce, quelle est la probabilité que deux d'entre elles soient nées le même jour ?

Note ton estimation sur le côté car dans la suite de cette leçon nous allons modéliser cette situation. Et la réponse est peut-être surprenante !

  1. 1

    Tout d'abord il nous faut une liste contenant les jours de naissance des 30 personnes. On modélise la par une liste d'entiers aléatoires pris entre 1 et 365.

    Importe la fonction randint du module random puis crée une variable anniversaires dans l'éditeur. Assigne à cette variable une liste en compréhension qui génère 30 dates anniversaires aléatoires.

    Solution

    On commence par importer la fonction randint du module random.

    Ensuite on définit la variable anniversaires, elle doit contenir une liste de 30 dates aléatoires. On construit la liste en compréhension en appelant randint(1, 365) trente fois :

    from random import randint
    
    anniversaires = [randint(1, 365) for i in range(30)]
  2. 2

    J'ai défini pour toi une fonction doublons contenant la variable anniversaires ainsi qu'une boucle for. Cette fonction n'est pas tout à fait correcte.

    Pour détecter si la liste anniversaires contient des doublons, l'idée est la suivante : pour chaque date de la liste anniversaires, si cette date apparaît plus d'une fois dans la liste on revoie 1. Si aucun doublon n'est détecté on renvoie 0.

    Modifie la condition du if pour renvoyer 1 si la date apparaît plus d'une fois dans la liste. Tu peux utiliser la méthode count pour compter le nombre de fois qu'un élément apparaît dans une liste.

    Rappel : la méthode count s'utilise sur une liste en lui passant en argument la valeur à compter :

    >>> [1,3,1,5].count(1)
    2
    Solution

    Pour chaque date de la liste, on compte le nombre de fois qu'elle apparaît en faisant anniversaires.count(date)

    Il faut renvoyer 1 si ce nombre est supérieur à 1. Si aucun élément de la liste n'apparaît en double, c'est que la liste n'a pas de doublon. Dans ce cas on renvoie 0.

    from random import randint
    
    def doublons():
    	anniversaires = [randint(1, 365) for i in range(30)]
    
    	for date in anniversaires:
    		if anniversaires.count(date) > 1:
    			return 1
    
    	return 0
  3. 3

    Appelle la fonction doublons plusieurs fois dans la console. Quelle semble être la probabilité d'avoir des doubles ?

    Solution

    On appelle la fonction doublons dans la console. Les probabilités de faire 0 ou 1 semblent assez équilibrées.

    >>> doublons()
    0
    >>> doublons()
    1
  4. 4

    Pour obtenir la probabilité d'avoir deux personnes ayant le même anniversaires, on va faire une moyenne des résultats de la fonction doublons

    L'idée est la suivante : créer une liste en compréhension qui appelle la fonction doublons 1000 fois. Chacun des éléments de cette liste est donc 0 ou 1 et on obtient facilement la moyenne en s'aidant de la fonction sum

    Ajoute dans l'éditeur une variable p en dehors de la fonction doublons qui calcule la probabilité avec la méthode précédente. Puis affiche cette probabilité à l'aide d'un print

    Solution

    Pour calculer la valeur de la variable p il nous faut tout d'abord une liste de 1000 éléments qui correspondent aux résultats de la fonction doublons

    On obtient cette liste en compréhension en faisant [doublons() for i in range(1000)]

    Il nous reste à calculer la moyenne de cette liste à l'aide de la fonction sum, sans oublier de diviser par 1000.

    On assigne le résultat à la variable p qu'on affiche ensuite à l'aide d'un print

    from random import randint
    
    def doublons():
    	anniversaires = [randint(1, 365) for i in range(30)]
    
    	for date in anniversaires:
    		if anniversaires.count(date) > 1:
    			return 1
    
    	return 0
    
    p = sum([doublons() for i in range(1000)]) / 1000
    print(p)
  5. 5

    Ce résultat nous interroge : à partir de quelle taille de groupe a-t-on 50% de chances d'avoir des anniversaires le même jour ?

    Dans un groupe de 1 personne la probabilité est 0 et dans un groupe de 366 personnes la probabilité est 1 (il n'y a que 365 jours par an). Comment évolue cette probabilité ? Nous allons faire un graphique pour la représenter.

    Il faudrait faire le calcul de la question précédente pour chaque taille de groupe entre 1 et 366.

    Pour commencer, modifie la fonction doublons pour qu'elle prenne un argument correspondant à la taille du groupe. Modifie en conséquence le calcul de p pour que la probabilité obtenue corresponde au cas du groupe de 30 personnes.

    Solution

    Il faut modifier l'en tête de la fonction doublons que l'on fait dépendre d'un argument n, ainsi que la variable anniversaires qui doit contenir n dates.

    On adapte ensuite le calcul de p pour appeler la fonction doublons avec l'argument 30

    from random import randint
    
    def doublons(n):
    	anniversaires = [randint(1, 365) for i in range(n)]
    
    	for date in anniversaires:
    		if anniversaires.count(date) > 1:
    			return 1
    
    	return 0
    
    p = sum([doublons(30) for i in range(1000)]) / 1000
    print(p)
  6. 6

    Pour faire la représentation graphique il nous faut une liste d'abscisses X qui correspond aux différentes tailles de groupes et une liste d'ordonnées Y qui correspond aux probabilités que des gens aient leurs anniversaires le même jour pour chacune des tailles de groupe.

    Pour t'aider j'ai transformé le calcul de p en une fonction. Elle prend en argument le nombre de personnes dans le groupe et renvoie la probabilité que deux personnes aient leur anniversaire le même jour pour un groupe de la taille donnée.

    Défini une liste X de nombres allant de 1 à 70, qui correspond aux différentes tailles de groupes possibles (il n'est pas utile d'aller jusqu'à 365). Défini ensuite une liste Y qui calcule la probabilité p d'avoir des anniversaires le même jour pour chacune de ces tailles de groupe.

    Solution

    Pour définir X le plus simple est de convertir en liste une séquence renvoyée par range à l'aide de la fonction list

    On définit Y en compréhension en calculant la probabilité p pour chacune des tailles de groupes de la liste X.

    from random import randint
    import matplotlib.pyplot as plt
    
    def doublons(n):
    	anniversaires = [randint(1, 365) for i in range(n)]
    
    	for date in anniversaires:
    		if anniversaires.count(date) > 1:
    			return 1
    
    	return 0
    
    def p(n):
    	return sum([doublons(n) for i in range(1000)]) / 1000
    
    X = list(range(1, 71))
    Y = [p(x) for x in X]
  7. 7

    Il ne reste plus qu'à faire le graphique à l'aide du module pyplot de la librairie matplotlib. J'ai déjà importé pyplot sous l'alias plt

    Utilise les fonctions plot et show du module pyplot pour voir comment évolue la probabilité que deux personnes aient leur anniversaire le même jour en fonction de la taille du groupe.

    Solution

    On trace le graphique à l'aide de la fonction plot. Pour obtenir des points rouges on peut passe l'option 'r.' dans l'appel de la fonction plot

    La fonction show nous affiche le graphique.

    from random import randint
    import matplotlib.pyplot as plt
    
    def doublons(n):
    	anniversaires = [randint(1, 365) for i in range(n)]
    
    	for date in anniversaires:
    		if anniversaires.count(date) > 1:
    			return 1
    
    	return 0
    
    def p(n):
    	return sum([doublons(n) for i in range(1000)]) / 1000
    
    X = list(range(1, 71))
    Y = [p(x) for x in X]
    
    plt.plot(X, Y, "b.")
    plt.show()

Bonus : tu peux modifier la liste X pour qu'elle ne contienne que des tailles de groupes entre 20 et 30 et ainsi mieux voir pour quelle taille de groupe la probabilité est 1/2.

Cette approche numérique est très puissante et nous permet d'obtenir une bonne intuition des phénomènes en modélisant les situations.

Chargement...

Collecte des fichiers...

>>>