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?
:
Bearbeitet durch User
https://xkcd.com/221/ Und um was hilfreiches beizusteuern: https://en.cppreference.com/w/cpp/numeric/random http://www.cplusplus.com/reference/random/ merciless
:
Bearbeitet durch User
noch mehr zu lesen: https://www.c-plusplus.net/forum/topic/172876/zufälle-gibt-s-funktionen-rund-um-rand-random-und-den-zufall
rbx schrieb: > noch mehr zu lesen: > https://www.c-plusplus.net/forum/topic/172876/zufälle-gibt-s-funktionen-rund-um-rand-random-und-den-zufall cstdlib und rand sind allerdings eher C auch wenn es im C++ Standard steht. merciless hat die relevanten C++ Links gepostet.
Weil hier es um Pseudozufallszahlen geht:
1 | #include <random> |
2 | |
3 | int GetRandom0_5 () { |
4 | std::default_random_engine generator; |
5 | std::uniform_int_distribution<int> distr(0, 5); // range is inclusive |
6 | return distr(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 | void SomeFunction(/*params*/) { |
4 | // need a random int 0..5
|
5 | std::default_random_engine generator; |
6 | std::uniform_int_distribution<int> distr(0, 5); // range is inclusive |
7 | for (;;) { // loop which need random numbers |
8 | ...
|
9 | int r= distr(generator); |
10 | ...
|
11 | }
|
12 | }
|
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 | static std::default_random_engine generator; |
2 | static std::uniform_int_distribution<int> distr(0, 5); // range is inclusive |
3 | |
4 | int GetRandom0_5 () { |
5 | return distr(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...
Was willst du denn überhaupt? Willst du eine Sequenz zufällig verteilter Zahlen, oder willst du kryptographischen Zufall, oder ...?
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.
:
Bearbeitet durch User
Warum sagst du uns nicht einfach, für was du die Zufallszahlen benötigst und in welchem Wertebereich die liegen sollen? merciless
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...
Da Du eh unter Windows unterwegs bist, nimm einfach rand_s und gut. https://docs.microsoft.com/de-de/cpp/c-runtime-library/reference/rand-s?view=vs-2019
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).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.