Autor |
Beitrag |
BoerseMan79
Hält's aus hier
Beiträge: 9
|
Verfasst: Mi 12.12.12 23:39
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?
Gibt es einen Richtigen Zufallsgenerator der aus CPU-Zeit oder sonstigen Variablen die Zahl generiert?
Einloggen, um Attachments anzusehen!
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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.
Für diesen Beitrag haben gedankt: BoerseMan79
|
|
BoerseMan79 
Hält's aus hier
Beiträge: 9
|
Verfasst: 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
      
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: 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
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Für diesen Beitrag haben gedankt: BoerseMan79
|
|
GuaAck
      
Beiträge: 378
Erhaltene Danke: 32
Windows 8.1
Delphi 10.4 Comm. Edition
|
Verfasst: 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
Für diesen Beitrag haben gedankt: BoerseMan79
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 13.12.12 02:12
Um den Beitrag von GuaAck zu ergänzen:
Delphi-Random ist im Grunde nichts anderes als ein Linearer Kongruenzgenerator. 
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: 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)
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] |
Verteilungs-Histogramm (png, 3.82 KB)
2D-Spektralanalyse 1: 2:
| > show(xyplot(each(range(1,100000,1),i,{random(),random()}))) = [Graph 9] |
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.
Einloggen, um Attachments anzusehen!
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|