Twitter und Facebook-Anbindung
X
Tweet Follow @twitterapi
!!! Anbindung an twitter und facebook öffnen !!!

Wenn Ihnen mein Online-Buch gefällt,
dann bedanken Sie sich doch mit einer kleinen Spende...

11.2 Der zufällige Zufall

11.2 Der zufällige Zufall

Wie schaffen wSie es nun, immer eine andere Folge von zufälligen Zahlen zu erzeugen? Sicherlich wird man auf die Idee kommen, den Initialwert zufällig zu wählen, aber beißt sich da die Katze nicht in den Schwanz? Ohne weitere Überlegungen, würde sie das tun, aber es gibt Mittel und Wege einen zufälligen Initialwert zu bekommen, ohne "rand" aufrufen zu müssen. Der Trick ist, man benutzt das aktuelle Datum und die aktuelle Zeit. Vom Prinzip her könnte man zwar dann auch immer den gleichen Zufall bekommen, wenn man die Systemzeit zurück setzt, aber da die Uhrzeit auf die Millisekunde genau ist, ist es extrem schwer, es so zu organisieren, dass genau zu einem Zeitpunkt X der Computer die Funktion "srand" aufruft (um nicht zu sagen unmöglich).

Folgendes Beispiel wird wieder genau so sein wie eben, nur dass ich jetzt die Zeit für die Initialisierung des Zufalls verwenden werde.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
					
#include <stdlib.h>
#include <time.h>

// ...

srand((unsigned int)time(NULL));

// 5 Zufallszahlen erzeugen
for (int iCount = 0; iCount < 5; iCount++) {
	printf("%i ", rand());
} // end of for
					

In Zeile 6 sehen Sie jetzt, wie ich die aktuelle Zeit ermittle und das bringt mich auch gleich zu einem sehr wichtigen Hinweis. Bauten Sie die Funktion "srand" niemals in eine Schleife ein bzw. in eine rekursive Funktion. Jene werden meistens innerhalb einer Millisekunde ausgeführt, was zur Folge hat, dass man immer dieselbe Zeit ermittelt und somit immer den gleichen Startwert für den Zufall bekommt. Noch schlimmer wird es, wenn man in einer Schleife einmal "srand" und einmal "rand" aufruft. In diesem Fall bekommt man sogar immer die gleiche Zahl. Falls Sie sich also irgendwann mal wundern sollten, warum Ihtr zufällige Zahl gar nicht zufällig ist, dann liegt es an eben beschriebenem Szenario.

Zum Schluss möchte ich noch einen Lösungsansatz dafür aufzeigen, wie man zufällige Zahlen in einem bestimmten Intervall erzeugen kann, solange er unterhalb von 32767 liegt. Der Trick ist hier, dass man auf die zufällige Zahl den Modulo-Operator anwendet und anschließend das Ergebnis in den gewünschten Bereich verschiebt. Dies könnte z.B. so aussehen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
					
#include <stdlib.h>
#include <time.h>

// ...

srand((unsigned int)time(NULL));

int iVon	= 10;
int iBis	= 20;

// 5 Zufallszahlen erzeugen
for (int iCount = 0; iCount < 20; iCount++) {
	printf("%i ", rand() % (iBis-iVon+1) + iVon);
} // end of for
					

Ausgabe:

10 19 11 13 14 18 16 16 10 17 18 20 10 19 11 19 14 11 15 12
		

Wie mSie sehen, erzeuge ich mit obigen Code, 20 Zufallszahlen, welche im Bereich zwischen / einschließlich 10 und 20 liegen.

Eines sei an dieser Stelle noch erwähnt. Der intern verwendete Algorithmus zur Generierung der Zahlen ist zwar gut, aber nicht perfekt. Das heißt, manche Zahlen kommen öfters als andere vor. Die Gleichverteilung ist also nicht gegeben, sie kommt dem nur nahe. Wenn Sie es mir nicht glauben, können Sie ja mal ein Array von 1 bis 1000 bauen und eine Million mal eine zufällige Zahl erzeugen lassen und jene als Index für den Arrayzugriff benutzen, um den enthaltenen Wert zu inkrementieren. Wenn Sie sich jenes Array anschließend anschaut, werden Sie feststellen, dass die Werte teilweise stark variieren (was ja eigentlich nicht vorkommen dürfte) und dass sich bei mehrmaligem Ausführen ein Muster abzeichnet.

Zum Seitenanfang
Zum Inhaltsverzeichnis

© Copyright by Thomas Weiß, 2009 - 2012