Es gibt keine Zufälle

Zufallszahlen sind eine feine Sache und auch sehr einfach zu generieren. Die Random-Klasse des XNA-Framework liefert uns hier eine sehr gute Möglichkeit. Jedoch auch hier gibt es den ein oder anderen kleinen Fallstrick, der uns – wenn wir uns nicht mit der Materie befassen – das Leben schwer machen kann.

In diesem kleinen Artikel möchte ich ein paar Anmerkungen dazu machen und so eine Art Mini-Tutorial bereitstellen.

Das wichtigste erstmal vorweg:

Zufallszahlen sind nicht zufällig.

Zufallszahlen wirken lediglich zufällig, werden aber in Wirklichkeit von einem Algorithmus erzeugt. Dieser Algorithmus beginnt seine Arbeit bei einem Startwert, dem sogenannten Seed. Und damit kommen wir auch schon zur ersten Regel:

Gleicher Seed bedeutet gleiche Zahlenreihe.

Dies ist eine wichtige Erkenntnis, die durchaus nützlich sein kann. Wenn wir z.B. ein zufälliges Level generieren, dann können wir mittels des Seeds – ein Parameter des Konstruktors von Random – immer das gleiche Level erzeugen, wenn wir den gleichen Seed verwenden. In diesem Fall müssten wir nicht das gesamte Level speichern, sondern lediglich den Seed.

Der Standardwert für den Seed wird in der Regel aus der Systemzeit abgeleitet. Da diese selten exakt gleich ist zwischen zwei Programmausführungen, haben wir immer einen neuen Seed und damit eine neue „zufällige“ Zahlenreihe.

Mit diesem Wissen ausgerüstet kommen wir nun aber auch direkt zum ersten Fallstrick und einer sehr einfachen Lösungsmöglichkeit. Sollten wir auf die Idee kommen, mehrere Zufallsgeneratoren kurz hintereinander zu erzeugen, so kann das Problem auftreten, daß dies so schnell geschieht, daß alle den gleichen Seed erhalten. In diesem Fall liefern alle natürlich auch die gleiche Zahlenreihe und damit die gleichen Zufallszahlen, die dann garnicht mehr zufällig aussehen. Es ist also wichtig, daß wir möglichst wenige Instanzen, am besten nur eine einzige, erzeugen, damit dieses Problem nicht auftritt.

Der letzte, wichtige Punkt ist, daß Zufallszahlen nicht normalverteilt sind. Sie sind auch nicht so verteilt, daß ein Mensch diese Zahlen als besonders zufällig wahrnimmt (also z.B. weißes Rauschen). Die Zufallszahlen sind schlicht und einfach zufällig (naja, nicht wirklich, siehe oben). Es kann also durchaus passieren, daß 10x die gleiche Zahl kommt bei zehn Aufrufen. Das ist halt so und manchmal nicht wirklich zielführend. Wenn der Computergegner bei einem Kartenspiel 10x hintereinander die Joker bekommt, dann entsteht schnell der Eindruck, das geschummelt wird. Wir müssen uns darum also selbst kümmern, wie auch immer das im konkreten Fall aussehen mag.

Zum Abschluss noch der obligatorische Link auf die MSDN mit der Doku für die Random-Klasse.

Advertisements

Veröffentlicht am 19.01.2010 in Grundlagen, XNA und mit , , getaggt. Setze ein Lesezeichen auf den Permalink. 4 Kommentare.

  1. Hmm.. irgendwie ist ja dann nichts Zufall. Wenn du sagst, dass sei kein Zufall, dann gibt es doch auch im echten Leben keine Zufälle..

    Wenn ein Baum auf einen Menschen fällt, dann ist es doch auch nicht so wirklich ein Zufall gewesen. Bäume fallen ja in der Regel nicht aus Spaß um, sondern wegen einem starken Wind z.B.. Ob und wann dieser Wind kommt, ist ja kein Zufall.. sonst könnte man es ja nicht vorausberechnen. Es ist im Grunde dann auch kein Zufall, wann dieser Mensch unterm Baum steht.. vielleicht geht er ja gerade zur Arbeit .. zu einer festen Uhrzeit natürlich.. und diese Uhrzeit ist bestimmt auch nicht vom Chef oder so zufällig bestimmt worden..

    Das heißt, es gibt keine Zufälle.. da alles berechenbar ist. Und Zufälle kann man ja nicht wirklich berechnen.. und wenn es dann auch keine Zufälle gibt, dann ist das Wort doch auch sinnlos ^^
    Wofür braucht man Bezeichnungen/Wörter von Etwas, was es nicht gibt?

    • Jetzt wird’s philosophisch… *g*

      Man könnte „Zufall“ vielleicht mit „ohne erkennbaren Grund“ definieren. Selbstverständlich gibt es dann einen Zufall. Wenn man es aus Sicht der Chaostheorie sieht, dann könnte es tatsächlich sein, daß „Zufälle“ berechenbar sind, wenn man nur alle Parameter kennt.

      Keine Ahnung… 🙂 Ich wollte halt nur ein wenig was zu Zufallszahlen schreiben…

  2. Jedenfalls gibt es sogar Hardware, speziell für die Erzeugung von Zufallszahlen ..
    http://en.wikipedia.org/wiki/Hardware_random_number_generator
    Aber noch habe ich mir den Artikel nicht durchgelesen..

    mit den Zufallszahlen, die mir geliefert werden, kann ich leben ^^

  3. Für zufälligere (haha) Zahlen könnte man ja
    System.Security.Cryptography.RandomNumberGenerator.Create()
    verwenden.
    Die Klasse wurde zwar nicht für sowas vorgesehen, aber im Notfall tut sie es auch 😉

    Hier ein kurzes Konsolenprogramm:

    static void Main(string[] args)
    {
    var ran = System.Security.Cryptography.RandomNumberGenerator.Create();

    var ranNumbers= new byte[100];
    ran.GetBytes(ranNumbers);

    foreach (var b in ranNumbers)
    Console.WriteLine(b);

    Console.ReadLine();
    }

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: