Qu'est ce que ça fait quoi ?

Portrait de mickeymouse

Tout est dans le titre, qu'est ce que ce programme calcule ?

from random import random
 
n = 10000000
res = 1
 
for _ in range(n):
    r1 = random()
    r2 = random()
    k = 1
    while r1 < r2:
        r1 = r2
        r2 = random()
        k+=1
    res += k/n
 
print(res)

Dans le meme genre il y a aussi :

n = 10000000
res = 0
for _ in range(n) : 
	x = random()
	y = random()
	if (x**2+y**2)**(1/2) < 1 :
	    res+=1/n
 
print(res*4)

Oui je sais c'est du python à l'arrache :p .

EDIT : J'ai pas précisé, j'utilise python3 pour exécuter ce code.

Commentaires

Portrait de trax

Ça me semble équivalent à:

from random import random
 
n = 10000000
res = 1
 
for _ in range(n):
    r1 = random()
    r2 = random()
    k = 1
    if r1 < r2:
        k+=1
    res += k/n
 
print(res)

Supposons que la répartition des nombres aléatoire() soit linéaire (il y a sûrement un meilleurs mot)

soit une chance sur deux de rentrer dans le corps du "if"

res = \sum k = 1 => n/2 1/n
=> 1 ?

2B G33K || !2B

Portrait de mickeymouse

Je pense que tu voulais dire que la répartition est uniforme. On peut considérer qu'elle l'est (en fait elle semble pas l'être réellement au vu de la courbe de la fonction de répartition que j'avais tracé pendant des essaies mais elle s'en approche suffisamment).

Et sinon ton code n'est pas équivalent, tu peux essayer tu verras qu'on obtiendra pas la même chose.
On voit que dans mon code on a r2 = r1 soit l'ancienne valeur, et on sait par le test de la boucle que r2 > r1 donc le nouveau nombre aléatoire doit être plus grand que ce r2 qui lui même est plus grand que r1 et ainsi de suite. En gros plus on itère dans la boucle et moins on a de chance d'avoir un nombre qui respecte la condition.

Portrait de paul

Vu que n et k sont un int, n est toujours >> k (vu la répartition du random dont tu parles) et donc k/n vaut systématiquement 0.

Donc ça retourne 1.

Pour que ça retourne autre chose que 1 il faudrait que au moins n calls successifs de random() forment une suite strictement croissante.

Portrait de mickeymouse

En fait en python quand on fait k/n ça te donne un float. Ce que tu dis serait vrai si j'avais mis k//n.

Portrait de mickeymouse

Je viens d'y penser dans le même genre en encore plus couillons mais bien rigolo il y a cette méthode

def foo(n = 10000000) :
    res = 1
 
    for _ in range(n):
        r1 = random()
        r2 = random()
        k = 1
        while r1 < r2:
            r1 = r2
            r2 = random()
            k+=1
        res += k/n
    return res
 
def bar(n = 10000000) :
    res = 0
 
    for _ in range(n):
        r1 = random()
        r2 = random()
        while r1 < r2:
            r1 = r2
            r2 = random()
        r1 = r2
        r2 = random()
        k = 1
        while r1 < r2:
            r1 = r2
            r2 = random()
            k += 1
        res += k/n
    return (res + 2*foo(n))**(0.5)

foo() et bar() calculent exactement la même chose mais l'une appelle l'autre, c'est plutôt marrant bien que complètement inutile.

Sinon en bonus, http://fr.wikipedia.org/wiki/M%C3%A9thode_de_Monte-Carlo .