mikrocontroller.net

Forum: PC Hard- und Software visual studio c++ Zufallszahlen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Frodo (Gast)
Datum:

Bewertung
-2 lesenswert
nicht 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?

Autor: Random .. (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
Autor: Dirk K. (merciless)
Datum:

Bewertung
1 lesenswert
nicht lesenswert

: Bearbeitet durch User
Autor: rbx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: loeti2 (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Weil hier es um Pseudozufallszahlen geht:
#include <random>

int GetRandom0_5 () {
  std::default_random_engine generator;
  std::uniform_int_distribution<int> distr(0, 5); // range is inclusive
  return distr(generator);
}

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:
#include <random>

void SomeFunction(/*params*/) {
  // need a random int 0..5
  std::default_random_engine generator;
  std::uniform_int_distribution<int> distr(0, 5); // range is inclusive
  for (;;) { // loop which need random numbers
     ...
     int r= distr(generator);
     ...
  }
}

Autor: Sven B. (scummos)
Datum:

Bewertung
1 lesenswert
nicht 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.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
static std::default_random_engine generator;
static std::uniform_int_distribution<int> distr(0, 5); // range is inclusive

int GetRandom0_5 () {
  return distr(generator);
}

sodass die Verteilung für alle Aufrufer gilt. Finde ich aber nicht 
wirklich besser.

Autor: Frodo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Sven B. (scummos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was willst du denn überhaupt? Willst du eine Sequenz zufällig verteilter 
Zahlen, oder willst du kryptographischen Zufall, oder ...?

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
1 lesenswert
nicht 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.

: Bearbeitet durch User
Autor: Dirk K. (merciless)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Warum sagst du uns nicht einfach, für was du die
Zufallszahlen benötigst und in welchem Wertebereich
die liegen sollen?

merciless

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Nils (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
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

Autor: Niklas G. (erlkoenig) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.