0

Le paradoxe des deux enfants en Python

Quand j’ai vu la vidéo suivante, j’ai eu envie de tester en utilisant un programme, comme je l’avais fait pour le paradoxe du monthy hall. J’ai eu envie de vous le partager et avec la compréhension du problème qu’il apporte.

Bien évidement, je vais donner tout les codes sources en python. Mais vous n’êtes pas obligé de comprendre le python pour lire cet article.

Le problème peut-être posé avec des enfants garçons et filles. Mais cela porte des préjugés sexistes. Notamment, dans le fait que cela induit une délimitation évidente entre les sexe. Ce qui n’est pas le cas dans la réalité. J’utiliserais donc l’énoncé en terme de jeu de cartes. En plus, c’est plus dans le thème du blog.

A ce sujet je vous conseille de voir cette vidéo de l’excellente chaîne YouTube Esprit Critique sur le sujet du sexe pas si facile à définir.

Début de la programmation

Première chose, il faudrait une fonction pour construire l’ensemble des possibilités. Vu que j’aime les statistiques et que j’en aurais sans doute l’utilité plus tard, voilà une fonction très générique en python qui permet cela.

def all_possible(nb_var, values):
    result = []
    if nb_var >= 2:
        for value in values:
            result += [value + prev_el
                       for prev_el in all_possible(nb_var-1, values)]
    else:
        return values
    return result

J’ai ensuite construit à l’aide de cette fonction, tout les cas possibles pour les mains. Alors on va construire ça en utilisant la lettre N pour noir et R pour rouge.

all_possible(2, ["R", "N"])

Commençons par tester le premier cas qui consiste a choisir un cas possible puis regarder une carte au hasard et si elle est noire on vérifie si l’autre l’est aussi. Pour cela une boucle de 100 000 exemples pour se rapprocher de la valeur réelle est un bon exemple.

import random

def version_1(list_elements=all_possible(2, ["R", "N"]), tested_element="N"):
    nb_ok = 0
    nb_tested = 0
    for _ in range(100000):
        hand = random.choice(list_elements)
        # choix d'un tas dont l'une des carte est noirs.
        if random.choice(hand) == tested_element:
            nb_tested += 1
            # verification que les deux cartes sont noires.
            if hand == 'NN':
                nb_ok += 1
    # calcule de la proportion sur les 100000 tirage
    return nb_ok/nb_tested

print(version_1())

J’obtiens bien un nombre proche de 1/2. Pour mon test, j’obtiens : 0.5005701938659144. Pour la deuxième version, voilà le code :

import random

def version_2(list_elements=all_possible(2, ["R", "N"]), tested_element="N"):
    nb_ok = 0
    nb_tested = 0
    for _ in range(100000):
        hand = random.choice(list_elements)
        # choix d'un tas dont l'une des carte est noirs.
        if tested_element in hand:
            nb_tested += 1
            # verification que les deux cartes sont noires.
            if hand == 'NN':
                nb_ok += 1
    # calcule de la proportion sur les 100000 tirage
    return nb_ok/nb_tested

print(version_2())

On obtient bien un résultat proche de 1/3. Pour mon test, j’obtiens : 0.3316908817301674.

Si on regarde les deux programmes, il n’y a qu’une ligne qui les différencie. Il s’agit du choix d’un tas dont l’une des carte est noire. Dans la première version, on prend une carte au hasard (random.choice) et si elle est noire on teste si les deux sont noir. Dans la deuxième, on regarde si le jeu contient une carte noire (l’opérateur in du python).

Si on regarde les deux programmes, il n’y a qu’une ligne qui les différencie. Il s’agit du choix d’un tas dont l’une des carte est noire. Dans la première version, on prend une carte au hasard (random.choice) et si elle est noire on teste si les deux sont noirs. Dans la deuxième, on regarde si le jeu contient une carte noire (l’opérateur in du python).

Résultat détaillé

Pour un peu mieux comprendre, on peut modifier la dernière ligne pour avoir directement le nombre d’essais et le nombre de tests. Pour cela on remplace la dernière ligne des deux fonctions par :

return (nb_ok, nb_tested)

Mon résultat pour la première version est (25008, 50039). Pour la seconde version, j’obtiens (25015, 75016).

Conclusion

Pour résumer, il y a toujours au début un quart des cas qui contient deux cartes noires. Mais, dans un cas, on sélectionne tous les paquets mixtes et dans l’autre que la moitié. Bref, dans un cas, on a toujours l’info d’une carte noire quand le paquet et mixte et dans l’autre une fois sur deux.

Le piège est donc que si l’on a l’info par la première méthode et qu’on est dans le cas mixte, une foi sur deux on aura l’information. Dans le cas de la deuxième méthode ont aura, au contraire, systématiquement l’information.

Partagez

Gaël

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *