visual studio c++ Zufallszahlen

Gast #5962798
Lesenswert?

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?
Gast #5963139
Lesenswert?

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
}
#5963153
Lesenswert?

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.
Persönliche Seite #5963589
Lesenswert?

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.
Gast #5969039
Lesenswert?

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...
#5969667
Lesenswert?

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.
Persönliche Seite #5969918
Lesenswert?

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...
Persönliche Seite #5969936
Lesenswert?

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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren