C++: Eigener "Zufallsgenerator"?

3 Antworten

Ahoi, versuch's ggf. mal hiermit:

long random(long min, long max){
static long seed = time(0);
seed += time(0);
return seed % (max - min) + min;
}

alternativ auch damit:

//xorshift-prng
long random(long min, long max){
static long seed = time(0);
seed ^= seed << 13;
seed ^= seed >> 7;
seed ^= seed << 17;
return seed;
}

P.S.: Das Problem mit der geringen "Zufälligkeit" dürfte damit zusammenhängen, dass der Rückgabewert von "time" sich nur einmal pro Sekunde verändert. Wenn du diesen also ohne weiteres benutzt, gibt's innerhalb derselben Sekunde auch immer dieselben Zahlen.

Nenrel 
Fragesteller
 03.08.2016, 22:42

Hallo, erstmal danke für deine Antwort und die Lösungsvorschläge, ich benutze jedoch bewusst nicht die time(0) Funktion von ctime sondern eine Funktion innerhalb von Chrono (die ich in meiner eigenen "time()" Funktion eingebaut habe), da diese genauere Werte liefert (Millisekunden) und somit jedes mal ein neuer Seed rauskommen müsste. Sorry für die Schreibweise musste diesen Kommentar am Handy schreiben.

0
Isendrak  03.08.2016, 22:50
@Nenrel

Mkay... Das würde trotzdem die geringe "Zufälligkeit" im ersten Code erklären: Ohne Textausgabe kann es durchaus sein, dass die Generatorfunktion mehrmals innerhalb einer Millisekunde durchläuft, während die Textausgabe im zweiten Code den Ablauf ausreichend verzögert...

Trotzdem könnten meine beiden Beispiele die "Zufälligkeit" erhöhen, ersetze einfach das "time(0)" durch deine eigene "time()" Funktion.

P.S.: Siehe auch: https://de.wikipedia.org/wiki/Static_%28Schl%C3%BCsselwort%29#Beispiel_in_C.2C_C.2B.2B_oder_Java

0

Du nimmst die Zeit in Millisekunden und bildest den Rest bzgl. Max.

In deinem Beispiel ist Max=6. Wenn du max=100000 wählst, sind deine Zufallszahlen wahrscheinlich aufsteigend geordnet , also gar nicht zufällig.

In den meisten Programmiersprachen sind linearer Kongruenzgeneratoren eingebaut, die für die meisten praktischen Zwecke reichen. Sie funktionieren nach der Formel

Xneu = (Xalt * m + a) % p

Mit geeigneten Werten für m, a und p.

Wenn du durch p teilst, erhältst du einen Wert zwischen 0 und 1.

Oder du nimmst die eingebaute Version. Da haben sich Leute Gedanken gemacht, die etwas von ihrem Handwerk verstehen.

seed wird nur einmal beim Initialisieren des Random-Objekts verwendet.

Danach wird nicht auf die Zeit zurückgegriffen - wie du vermutest, führt das leicht zu vorhersehbaren Ergebnissen -, sondern eine interne Variable des Random-Objekts wird verändert.

Anscheinend willst du einen "Kongruenz-Generator" bauen. Siehe hierzu https://de.wikipedia.org/wiki/Kongruenzgenerator , https://www.c-plusplus.net/forum/244661-full , http://www.heise.de/forum/heise-online/News-Kommentare/JavaScript-Engine-V8-Vorsicht-vor-Math-random/Re-c-rand/posting-23944840/show/ und ander Suchergebnisse zum Thema "linearer kongruenzgenerator c++"

Woher ich das weiß:Berufserfahrung – Software-Entwickler