La procédure à produce an unbiased coin from a biased one a d'abord été attribuée à Von Neumann (un gars qui a fait un travail énorme en mathématiques et de nombreux domaines connexes). La procédure est super simple:
- Lancez la pièce deux fois.
- Si les résultats correspondent, recommencer en oubliant les deux résultats.
- Si les résultats diffèrent, utilisez le premier résultat, en oubliant le second.
La raison fonctionne cet algorithme est parce que la probabilité d'obtenir HT est p(1-p)
, qui est la même chose que de TH (1-p)p
. Ainsi, deux événements sont également probables.
Je lis aussi ce livre et il demande le temps de fonctionnement prévu. La probabilité que deux lancements ne soient pas égaux est z = 2*p*(1-p)
, par conséquent, la durée d'exécution attendue est 1/z
.
L'exemple précédent semble encourageante (après tout, si vous avez une pièce de monnaie biaisée avec un parti pris de p=0.99
, vous devez jeter votre pièce environ 50 fois, ce qui est pas beaucoup). Donc vous pourriez penser que c'est un algorithme optimal. Malheureusement, ce n'est pas le cas.
Voici comment il se compare avec le Shannon's theoretical bound (l'image est tirée de ce answer). Cela montre que l'algorithme est bon, mais loin d'être optimal.
Vous pouvez trouver une amélioration si vous considérerez que HHTT sera mis au rebut par cet algorithme, mais en fait, il a la même probabilité que TTHH. Donc, vous pouvez aussi arrêter ici et retourner H. La même chose est avec HHHHTTTT et ainsi de suite. L'utilisation de ces cas améliore le temps de fonctionnement prévu, mais ne le rend pas théoriquement optimal.
Et à la fin - code python:
import random
def biased(p):
# create a biased coin
return 1 if random.random() < p else 0
def unbiased_from_biased(p):
n1, n2 = biased(p), biased(p)
while n1 == n2:
n1, n2 = biased(p), biased(p)
return n1
p = random.random()
print p
tosses = [unbiased_from_biased(p) for i in xrange(1000)]
n_1 = sum(tosses)
n_2 = len(tosses) - n_1
print n_1, n_2
Il est assez explicite, et est un résultat exemple ici:
0.0973181652114
505 495
Comme vous le voyez, néanmoins nous avions un biais de 0.097
, nous avons eu environ le même nombre de 1
et 0
Je suppose que la réponse a à voir avec l'utilisation du générateur polarisé une fois la méthode standard et une fois comme une fonction inverse de sorte que vous ayez une probabilité AP d'une fois 0 et une probabilité (1-p) d'un 0 la deuxième itération et mélange les deux résultats pour équilibrer la distribution. Je ne connais pas les mathématiques exactes. –
Eric- ouais, si vous l'avez fait (rand() + (1-rand()))/2, vous pouvez raisonnablement espérer obtenir un résultat non biaisé. Notez que dans ce qui précède, vous devriez appeler deux fois rand() sinon vous obtenez toujours.5 – JohnE
@JohnE: Essentiellement c'est ce que je pensais, mais cela ne vous laisse pas avec un droit 0 ou 1, ce qui est demandé. Je pense que pau a frappé le clou sur la tête avec sa réponse. –