Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Wie Zufällig ist die Funktion Random?
BoerseMan79 - Mi 12.12.12 23:39
Titel: Wie Zufällig ist die Funktion Random?
Hallo
ich habe mal aus Neugierde die Funktion Random() analysiert und festgestellt, dass die Zahlen sich wiederholen:
mit diesem selbst-geschriebenen Programm:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Timer1Timer(Sender: TObject); begin Edit1.Left:=Edit1.Left+Random(3); Edit1.Text:=IntToStr(Edit1.Left); Edit2.Left:=Edit2.Left+Random(3); Edit2.Text:=IntToStr(Edit2.Left); Edit3.Left:=Edit3.Left+Random(3); Edit3.Text:=IntToStr(Edit3.Left); Edit4.Left:=Edit4.Left+Random(3); Edit4.Text:=IntToStr(Edit4.Left); if (Edit1.Left>1032) or (Edit2.Left>1032) or (Edit3.Left>1032) or (Edit4.Left>1032) then Timer1.Enabled:=false; end;
end. |
egal wie oft ich das Programm laufen lasse oder mit unterschiedlichen Intervelen von Timer, das Ergebnis ist immer gleich:
Sind die "zufälligen" Zahlen schon vordefiniert? :gruebel:
Gibt es einen Richtigen Zufallsgenerator der aus CPU-Zeit oder sonstigen Variablen die Zahl generiert?
jaenicke - Mi 12.12.12 23:49
Wo hast du denn Randomize aufgerufen? Das sollte nur genau einmal beim Programmstart aufgerufen werden um den Zufallsgenerator zu initialisieren, nicht mehrfach.
Wenn du das gar nicht aufrufst, bekommst du keine guten Zufallszahlen. Wenn du immer die gleiche Zufallszahlenfolge haben willst, kannst du den gleichen RandSeed setzen.
BoerseMan79 - Mi 12.12.12 23:53
wie meinst du das genau? Wo genau im Programm soll ich Randomize; einfügen? Am anfang von der Timer-Prozedur?
Mathematiker - Do 13.12.12 00:19
Hallo,
BoerseMan79 hat folgendes geschrieben : |
Wo genau im Programm soll ich Randomize; einfügen? Am anfang von der Timer-Prozedur? |
Würde ich nicht machen. Randomize füge ich entweder in der Create- oder Activate-Methode des Formulars ein. Darüber hinaus kannst Du es auch im Initialization-Bereich der Unit aufrufen:
Delphi-Quelltext
1: 2: 3:
| initialization randomize; end. |
Übrigens ist der Zufallsgenerator von Delphi gar nicht so schlecht. Die generierten Pseudozufallszahlen sind gut verteilt.
Allerdings. Solltest Du eine Monte-Carlo-Simulation oder sogar eine kryptografische Anwendung mit dem Delphi-Random planen, würde ich doch zu einem eigenen Zufallsgenerator raten. Im Netz findet man dort genügend.
Der "Nachteil" der Delphi-Zufallszahlen ist, dass sie sich zum einen nach 2^32 wiederholen (stört im Allgemeinen nicht), zum anderen die nächste Zufallszahl immer von der vorhergehenden abhängt.
Beste Grüße
Mathematiker
GuaAck - Do 13.12.12 00:47
Hallo,
die Zufallszahlen werden im Prinzip folgendermaßen erzeugt:
Randomseed := komplizierte_Funktion (Randomseed);
Zufallszahl := andere_komplizierte_Funktion(Randomseed);
Mit Programmstart ist Randomseed := 0 initialisert (oder man kann der Variablen einen eigenen Wert zuweisen), deshalb ergibt jeder Durchlauf immer exakt die gleiche Zahlenfolge. Das ist sehr nützlich für das Debuggen.
Mit Randomize wird Randomseed aus der aktuellen Uhrzeit ermittelt, dann sind alle Durchläufe unterschiedlich.
Wie gut die "Zufälligkeit" ist, das ist eine ganz andere Frage. Da ja die Variable Randomseed nur eine durch die Bitzahl bestimmte Anzahl von diskreten Werten annehmen kann, wiederholen sich die Zahlen spätestens, wenn alle Zahlen "gelost" wurden.
Erfahrung: Nur bei sehr hohen Ansprüchen an die Zufälligkeit reicht die Standardfunktion nicht aus.
Gruß
GuaAck
Martok - Do 13.12.12 13:56
Und um mal etwas Werbung für Pi zu machen, welches das ganz normale Delphi-Random verwendet (einmalig beim Programmstart mit Randomize initialisiert) 8)
Verteilung
1: 2: 3: 4: 5: 6: 7: 8: 9:
| > liste=each(range(1,100000,1),i,random()) = {0.880 556 680 262 088 776, ..........., 0.046 298 111 556 097 865 1, ... (99993)}
> buck:=bucket(liste, 0,1,10)
> show(histogram(buck),yrange={9500,11000}) Bucket Width: 0,10 Bucket Width: 0,10 = [Graph 6] |
:arrow:
Verteilungs-Histogramm (png, 3.82 KB)
2D-Spektralanalyse
1: 2:
| > show(xyplot(each(range(1,100000,1),i,{random(),random()}))) = [Graph 9] |
:arrow:
2D-Spektralanalyse-Plot (png, 179.99 KB)
Sagt einigentlich nicht viel aus, da 100k Werte etwas wenig sind für eine Statistik. Aber immerhin sieht man nichts offensichtlich seltsames, das ist doch was.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!