Freitag, 19. März 2010

 

Probleme mit python's random

Wenn man Zufallszahlen benötigt oder Funktionen, die auf zufällige Zahlenfolgen basieren, verwendet man in Python das Modul random (ähnliche Module, Klassen oder Libraries gibt es im Prinzip für alle Programmiersprachen). Dahinter steckt keine echte Zufallszahlenerzeugung sondern vielmehr eine Funktion, welche Pseudozufallszahlen liefert, die sich statistisch wie Zufallszahlen verhalten.
Manchmal benötigt man immer wieder die selbe Zahlenfolge (z.B. beim Testen). Das erreicht man durch Angabe eines "seeds" (Samen) bei der Methode random.seed(), z.B. random.seed(23). Damit wird der Zufallsgenerator mit diesem Wert initialisiert. Bei selbem seed bekommt man immer die selbe Folge von Pseudozufallszahlen. Verwendet man diese Funktion nicht, so wird (zumindest bei Python) automatisch die Systemzeit als Anfangswert genommen. Damit kann man die Folge nicht vorhersagen (für einen bestimmten Zeitpunkt schon, dann nimmt man diesen Zeitstempel einfach als seed).

Nun zu meinem Problem mit random:
Python 2.5.2 auf meinem Debian- Rechner, den ich regelmäßig auf neuen Stand bringe
>>> from random import seed, random
>>> seed("23")
>>> random()
0.41111702255082994
Python 2.5.1 auf der Dreambox
>>> from random import seed, random
>>> seed("23")
>>> random()
0.09256672412670508

Bis vor Kurzem waren die beiden Werte identisch. Mein Python-Programm verhielt sich auf der Dreambox genauso wie auf meinem Entwicklungsrechner.

Offensichtlich gab es da Änderungen (Korrekturen) in der Python-Bibliothek.

In der Dokumentation von Python kann man lesen, dass für den seed ganze Zahlen (long, int) oder jedes "hashable" Objekt verwenden kann. Und dort dürfte das Problem liegen:
Python 2.5.2
>>> "23".__hash__()
6400038450057767
Python 2.5.1
>>> "23".__hash__()
308105767

Es ist einiges an Zeit vergangen, bis ich dieses Problem identifizieren konnte, denn der Bytecode von Python ist auf jeder Maschine gleich (ähnlich der VM von Java). Es muss also m.E. an der Version liegen.

Als Lösung bietet sich an, direkt eine Zahl zu verwenden:
Python 2.5.2
>>> seed(23)
>>> random()
0.92486525162594524
Python 2.5.1
>>> seed(23)
>>> random()
0.92486525162594524

Quellen:

Labels: , ,


Kommentare:

Kommentar veröffentlichen

Abonnieren Kommentare zum Post [Atom]





<< Startseite

This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]