Paradoxe des anniversaires

Description

J'hésite entre la catégorie "Math" et "VbScript" pour cette source. Il s'agit d'un script traitant du Paradoxe Des Anniversaires. J'ai choisi le VbScript parce que je n'ai rien d'autre sous la main.

TRES IMPORTANT: j'utilise WScript.Echo, donc ne lancez pas le script en double-cliquant dessus mais il faut le lancer avec CScript en ligne de commandes (voir le ScreenShot).

Le paradoxe des anniversaires énonce que: si dans une pièce, il y a au moins 23 personnes, la probabilité qu'il y a au moins deux personnes dans cette pièce qui ont leur anniversaire le même jour (même jour, même mois) est de plus de 50%. Le paradoxe est qu'il suffise de 23 personnes, ce qui parait peu, mais pourtant...
Le script en fait l'expérience en remplissant un tableau avec des valeurs au hasard et ensuite il regarde s'il y en a des identiques. Ensuite, le script calcule et affiche la proba.

J'ai commenté la source.

En espérant que vous trouverez ça intéressant...

--
MisterWhiteLapin

Source / Exemple :


REM Forcer la déclaration des variables.
Option Explicit

REM Pour avoir une valeure de random différente à chaque fois.
Randomize

REM Nombre de jours sur lequel porte l'expérience.
Const nbJours = 365.0

REM Nombre de jours décrémenté. 365 puis 364 puis 363 puis ...
REM Utilisé ici comme un type float.
Dim nbJoursDec

REM i et j. Deux variables de boucles.
Dim i, j

REM Nombre de personnes concernés.
Dim n

REM Resultat recalculé à chaque itération. Utilisé comme un type float.
Dim res

REM Un string qui sert à accumuler le résultat avant de l'afficher.
Dim strTemp

REM Tableau contenant des valeures de 0 à (nbJours - 1).
Dim tabRandom

REM #############################################################################
REM #############################################################################
REM ################## Gestion des arguments (le nombre de personnes)############
REM Si il n'y a pas d'argument ou que l'argument n'est pas valide,
REM on le met arbitrairement à 25.
If (WScript.Arguments.Count >= 1) Then
	On Error Resume Next
	n = CInt(WScript.Arguments(0))
	If (Err.Number <> 0) Then
		n = 25
	End If
	On Error Goto 0
Else
	n = 25
End If
REM #############################################################################
REM #############################################################################
REM #############################################################################

REM #############################################################################
REM #############################################################################
REM ################## Tableau de random ########################################
ReDim tabRandom(n)

REM On initialise le tableau avec des valeures
REM aléatoires de 0 à (NbJours - 1) (364 dans notre cas).
strTemp = ""
i = 0
While (i < n)
	tabRandom(i) = Int(nbJours * Rnd)
	WScript.Echo "tabRandom(" & i & ") = " & tabRandom(i)
	i = i + 1
WEnd

REM On va parcourir le tableau avec une complexité en O(n²) pour chercher les
REM doublons et les stocker dans la variable strTemp en vue de les afficher plus tard.
i = 0
While (i < n)
	j = i + 1
	While (j < n)
		If (tabRandom(i) = tabRandom(j)) Then
			If (strTemp = "") Then
				strTemp = "Mêmes nombres aux indexes:" & VbCrlf
			End If
			strTemp = strTemp & "       " & i & " et " & j & "." & VbCrlf
		End If
		j = j + 1
	WEnd
	i = i + 1
WEnd

If (strTemp = "") Then
	strTemp = "Pas de doublon détécté." & VbCrlf
End If
REM #############################################################################
REM #############################################################################
REM #############################################################################

REM #############################################################################
REM #############################################################################
REM ################## Calcul de la probabilité #################################

REM   Explication du calcul (voir wikipedia et Internet pour
REM                          plus de renseignements).
REM   
REM   
REM   ######     Ici, nbJours vaut 365 (cas normal
REM              du paradoxe des anniversaires)   ######
REM   
REM   N.B.: Ici, 365^3 signifie 365 * 365 * 365 (c'est à dire "365 puissance 3")
REM   
REM   
REM   
REM   p_bar(n) = 1 - p(n)   et   p(n) = 1 - p_bar(n)
REM   
REM   p_bar(0) et p_bar(1): Pas de sens.
REM   p_bar(2) = 365 * (365 - 1) / (365^2)
REM            = 364 / 365
REM   p_bar(3) = 365 * (365 - 1) * (365 - 2) / (365^3)
REM            = 365 * 364 * 363 / (365^3)
REM            = p_bar(2) * 363 / 365
REM   p_bar(4) = 365 * (365 - 1) * (365 - 2) * (365 - 3) / (365^4)
REM            = 365 * 364 * 363 * 362 / (365^4)
REM            = p_bar(3) * 362 / 365
REM   
REM   p_bar(n) = p_bar(n - 1) * (365 - n + 1) / 365

If (n < 2) Then
	WScript.Echo "Pas de sens."
	WScript.Quit
End If

REM L'étape 1 est déjà faite car 365 / 365 = 1, on commance direct à 364 / 365.
res = 1.0
nbJoursDec = nbJours - 1.0
i = 1
While (i < n)
	res = res * (nbJoursDec) / nbJours
	nbJoursDec = nbJoursDec - 1.0
	i = i + 1
WEnd

REM On vient de calculer "p bar", on le transforme donc maintenant
REM en p, laprobabilité qui nous intéresse.
res = (1.0 - res) * 100.0

REM #############################################################################
REM #############################################################################
REM #############################################################################

REM Affichage de la probabilité.
strTemp = strTemp & "Nombre de personnes dans la salle: " & n & VbCrlf & _
                    "Probabilité de ""au moins 2 anniversaires le même jour"": " & res & "%"

REM Affichage de totue la string résultat (malheuresement, c'est trop
REM gros pour tenir dans une MsgBox).
WScript.Echo strTemp

Conclusion :


Un petit Script VBS qui illustre le "Paradoxe des anniversaires" découvert par Richard von Mises.
Page Wikipedia: http://fr.wikipedia.org/wiki/Paradoxe_des_anniversaires

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.