Don: srand()

Beitrag lesen

Folgende Funktion sollte immer unterschiedleche 'Zufallszahlen' erzeugen:

Die Funktion soll keinesfalls als wirklicher Zufallsgenerator fungieren. Hier wird nur das Problem immer wiederkehrender Zahlen ausgeräumt.

sub random {
»»  $random = int(rand $_[1]-$_[0])+$_[0];
»»  if($random >= $previous_rand) { $random++; }
»»  $previous_rand = $random;
}

random(a,b);

Kannst Du das mal erklaeren? Wieso sollte dies "immer" unterschiedliche Zahlen erzeugen? Und was soll die zweite Zeile der Funktion? Sie erhoeht $random, wenn es groesser oder gleich der vorher erzeugten Zahl ist? Die einzige Wirkung, die ich da sehe ist, dass eventuell die durch b gesetzt obere Grenze ueberschritten wird.

Ich hätte die Funktion vielleicht genauer beschreiben sollen:

Die Perl-Anweisung 'int(rand b)' erzeugt eine ganze Zahl zwischen 0 und b, b selbst kann dabei nicht auftreten (0<=x<b). Obige Funktion random(a,b) gibt eine Zahl a<=x<=b zurück. Die obere Grenze kann also erreicht werden.

In der ersten Zeile der Funktion
$random = int(rand $_[1]-$_[0])+$_[0];
wird eine ganze Zahl erzeugt, die zwischen a ($_[0]) und b-1 ($_[1]-1) liegt: a<=x<b. random() soll jedoch einen Wert a<=x<=b liefern. In diesem Bereich steht also ein Wert mehr zur Verfügung, als für rand() in Zeile 1 bereitgestellt wurde.

In der Variablen $previous_rand ist der Wert gespeichert, der im letzten Aufruf von random() erzeugt wurde. (Zeile 3: $previous_rand = $random;)

In Zeile 2 wird die aktuell erzeugte Zufallszahl mit $previous_rand verglichen. Wenn wieder dieselbe Zahl erzeugt wurde, soll der aktuelle Wert um 1 erhöht werden. Damit ist sichergestellt, daß bei zwei aufeinanderfolgenden Aufrufen von random() nicht derselbe Wert erzeugt wird.

Da wir uns vorher beim Aufruf von rand() einen Wert (b) aufgespart haben, müssen alle Werte größer oder gleich $previous_rand um 1 erhöht werden. Damit werden alle Zahlen x mit a<=x<=b erreicht.

Fazit: Beim Aufruf von rand() wird ein Wert aus dem gewünschten Bereich ausgespart, da wir beim zweiten Aufruf von random() ja eigentlich keine Zahl x mit a<=x<=b wollen, sonden a<=x<$previous_rand oder $previous_rand<x<=b. Also eine Zahl von möglichen a-b Werten.

Fehler: Ein kleiner Fehler ist allerdings im Script. Es kann beim ersten Aufruf von random() niemals die kleinste gewünschte Zahl (a) erzeugt werden. Dies könnte noch eingefügt werden.

Zusatz: random() funktioniert so nur für positive natürliche Zahlen. Bei negativen Werten wird der Zahlenbereich 'verschoben', kann aber noch korrigiert werden. Für reelle Werte ist die Funktion gänzlich ungeeignet!