Ich versuche mich gerade an einer Routine die Zufallszahlen zu Verfügung
stellen soll.
rand mit Referenz an srand(time) bringt keine zufriedenstellene
Ergebnisse, hier kann man ständing eindeutige Tendenzen erkennen.
Gibt es überhautp einigermaaßen funktionierende Lösungen?
Beim C64 konnte man afaik ein Rauschregister im SID auslesen :-) :-) :-)
Naja, dass die Zufallszahlenfolgen reproduzierbar sind, ist ja auch
gewollt, und wird bei jeder algorhytmik so sein.
Vielleicht bringt es mehr Chaos ins System, das tiefer zu schachteln
bzw. den seed nochmals zu verändern?
std::uniform_int_distribution<int>distr(0,5);// range is inclusive
6
returndistr(generator);
7
}
Was wird diese Funktion wohl liefern ;-)
Meine Frage, wie schreibe ich am besten eine Funktion, die von
verschiedenen Aufrufern aufgerufen wird, und jedem Aufrufer (unabhängig
von der Aufrufreihenfolge), eine Zahlenfolge liefert die die Kriterien
der "Pseudozufälligkeit" erfüllt.
Habe bis jetzt keine befriedigende Antwort gefunden. D.h. zur Zeit baue
ich jeweils einen neuen Generator/Distribution in die Verwenderfunktion
ein, so:
1
#include<random>
2
3
voidSomeFunction(/*params*/){
4
// need a random int 0..5
5
std::default_random_enginegenerator;
6
std::uniform_int_distribution<int>distr(0,5);// range is inclusive
Du initialisierst den Generator nur einmal und nimmst dann einfach immer
vom selben Generator Werte. Wenn du neu seedest mit der Zeit oder sowas,
kriegst du natürlich immer dieselben bis sich die Zeit ändert. Die
Verteilung ist nur dann gut, wenn du nur einmal seedest.
Frodo schrieb:> rand mit Referenz an srand(time) bringt keine zufriedenstellene> Ergebnisse, hier kann man ständing eindeutige Tendenzen erkennen.
Was verstehst du unter "eindeutige Tendenzen"? Normalerweise sind die
üblichen PRNGs gut genug, solange man es nicht als Basis für
Verschlüsselung oder ähnliches verwenden will.
Rolf M. schrieb:> Was verstehst du unter "eindeutige Tendenzen"?
Man muss aufpassen, dass man durch eine Skalierung die Verteilung nicht
verschiebt. Das klassische "rand() % 42" liefert keine Gleichverteilung.
Die C++ "random" Bibliothek macht es einfach, korrekt gleichverteilte
(oder anders verteilt, z.B. Normalverteilung) Zahlen zu erzeugen.
loeti2 schrieb:> Habe bis jetzt keine befriedigende Antwort gefunden. D.h. zur Zeit baue> ich jeweils einen neuen Generator/Distribution in die Verwenderfunktion> ein, so:
Das ist eigentlich genau richtig so. Die zwei Zeilen am Anfang
erscheinen zwar "überflüssig", aber sie definieren eben genau für
welchen Bereich die Zufallszahlen gelten.
Du kannst die Objekte global machen:
1
staticstd::default_random_enginegenerator;
2
staticstd::uniform_int_distribution<int>distr(0,5);// range is inclusive
3
4
intGetRandom0_5(){
5
returndistr(generator);
6
}
sodass die Verteilung für alle Aufrufer gilt. Finde ich aber nicht
wirklich besser.
ich hab noch weiter herumexperimientiert, bin aber bislang zu keinem
zufriedenstellenden Ergebnis gekommen.
Es gibt in einem Rechner dorch einige durchaus nicht vorhersehbare
Signale wie Microphone Eingang, Temperatur, Lüftergeschwindigkeit, Wlan
Signal Stärke, PSU Spannungen usw.
Warum nimmt man nicht die zur Hand, anstatt der Uhr, die sehr wohl
"vorhersehbar" ist...
Frodo schrieb:> ich hab noch weiter herumexperimientiert, bin aber bislang zu keinem> zufriedenstellenden Ergebnis gekommen.
Du hast leider deine Anforderungen immer noch nicht genannt, oder in
welcher Form die Ergebnisse diesen nicht genügen, oder wie dein Code,
der die Zahlen generiert, denn aussieht.
> Es gibt in einem Rechner dorch einige durchaus nicht vorhersehbare> Signale wie Microphone Eingang, Temperatur, Lüftergeschwindigkeit, Wlan> Signal Stärke, PSU Spannungen usw.>> Warum nimmt man nicht die zur Hand, anstatt der Uhr, die sehr wohl> "vorhersehbar" ist...
Weil es dabei nicht darum geht, ob die Zahl vorhersehbar ist, sondern
nur darum, dass sie nicht immer gleich ist. Die von dir genannten Dinge
sind alle umständlicher einzulesen und nicht zwingend bei jedem System
in gleicher Form vorhanden.
Und wenn deine Initialisierung nicht vorhersehbar ist, bringt dir das eh
nichts, weil sobald du die erste Zahl gesehen hast, alle weiteren doch
wieder vorhersehbar sind.
Wenn man höhere Qualität der Zufallszahlen will, muss man sowas nehmen:
https://de.wikipedia.org/wiki//dev/random
Ob's da ein vergleichbares Windows-Pendant gibt, weiß ich nicht.
Oder vielleicht auch das:
https://en.wikipedia.org/wiki/RdRand
Dafür gibt's auch eine Lib:
https://software.intel.com/en-us/articles/the-drng-library-and-manual
Das ist dann aber natürlich auf die Prozessoren beschränkt, die das
können.
Frodo schrieb:> ich hab noch weiter herumexperimientiert, bin aber bislang zu keinem> zufriedenstellenden Ergebnis gekommen.
Definiere "zufriedenstellend".
Frodo schrieb:> Warum nimmt man nicht die zur Hand, anstatt der Uhr, die sehr wohl> "vorhersehbar" ist...
Kann man. Es gibt aber durchaus Situationen bei denen die
"Zufalls"zahlen vorhersehbar sein sollen - daher nennen die sich auch
Pseudozufallszahlen. Die von rand() und "<random>" generierten Zahlen
fallen darunter. Diese sehen aber nicht vorhersehbar aus - sie sind
statistisch so verteilt wie "echte" gleichverteilte Zufallszahlen.
Aufgrund dieser Garantien ist es fragwürdig, wie du hier "eindeutige
Tendenzen" und "nicht zufriedenstellende" Zahlen erkennen willst - wenn
man den Algorithmus nicht kennt, kann man (gute) Pseudozufallszahlen
kaum von echten Zufallszahlen unterscheiden.
Typischerweise kann man viel mehr Pseudozufallszahlen viel einfacher pro
Sekunde erzeugen als echte Zufallszahlen. Für z.B. so etwas wie das
Verhalten NPC's in Computerspielen oder Simulation von Partikeln für
Grafikeffekte ist das genau richtig, für die Erzeugung von Passwörtern
eher nicht. Mit std::random_device bietet C++ auch die Möglichkeit,
echte Zufallszahlen zu erzeugen.
Daher: Du musst wissen was du überhaupt brauchst...
Nils schrieb:> Da Du eh unter Windows unterwegs bist, nimm einfach rand_s und gut.
Die liefert aber genauso eine Pseudozufallszahl wie rand() und die C++
random Bibliothek, ist nicht portabel, ermöglicht nicht die
Spezifikation von Min/Max und der Verteilung. Hat also keine Vorteile
gegenüber der Antwort von loeti2 (std::uniform_int_distribution und
std::default_random_engine).