dev-c++ und zufallszahlen (random_device) c++11



  • Hallo,
    wenn ich folgende Methode unter Microsoft VS 2015 ausführe funktioniert es Problemlos:

    int zufall(int  anfang, int  ende) {
    
    	int z;
    	random_device dev;
    	auto seed = dev();
    	default_random_engine engine(seed);
    	uniform_int_distribution<unsigned int> numbers_dist(anfang, ende);
    	(z) = numbers_dist(engine);
    
    	return z;
    }
    

    wenn ich es aber unter dev-c++ verwende kommen immer nur die gleichen Zahlen raus.
    Kann mir bitte einer helfen, damit die Methode auch mal unterschiedliche Zahlen unter dev-c++ ausgibt.

    p.s. Ich verwende dev-c++ 5.8.2 und hab schon -std=c++11 unter den Compiler-Options verwendet.



  • http://en.cppreference.co schrieb:

    std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.



  • manni66 schrieb:

    http://en.cppreference.co schrieb:

    std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.

    ok danke

    kann mir dann jemand einen guten Ersatz, weil ich mit srand eher nicht so gute Erfahrungen habe.


  • Mod

    win8789 schrieb:

    manni66 schrieb:

    http://en.cppreference.co schrieb:

    std::random_device may be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case each std::random_device object may generate the same number sequence.

    ok danke

    kann mir dann jemand einen guten Ersatz, weil ich mit srand eher nicht so gute Erfahrungen habe.

    Erklär mal, wofür du meinst, echte Zufallszahlen zu benötigen. Oder besser: Erklär, wozu du Zufallszahlen brauchst und wir erklären dir, wieso du keine echten Zufallszahlen brauchst.

    Falls es sich wirklich herausstellen sollte, dass du echte Zufallszahlen brauchst, bist du unter Windows mit Bordmitteln soweit ich weiß ziemlich aufgeschmissen.


  • Mod

    SeppJ schrieb:

    Falls es sich wirklich herausstellen sollte, dass du echte Zufallszahlen brauchst, bist du unter Windows mit Bordmitteln soweit ich weiß ziemlich aufgeschmissen.

    Können wir das Program absichtlich die CPU stressen lassen und die Temperatur dann als gleichverteilt in einem entsprechenden Interval betrachten? Das gibt sicherlich 4-5 Bits pro Mess-Interval. 🤡



  • SeppJ schrieb:

    Erklär mal, wofür du meinst, echte Zufallszahlen zu benötigen. Oder besser: Erklär, wozu du Zufallszahlen brauchst und wir erklären dir, wieso du keine echten Zufallszahlen brauchst.

    Falls es sich wirklich herausstellen sollte, dass du echte Zufallszahlen brauchst, bist du unter Windows mit Bordmitteln soweit ich weiß ziemlich aufgeschmissen.

    also ich will ein Musiklehrprogramm entwickeln. Und eine Aufgabe in diesem Programm soll sein, dass man eine Note bekommt z.B. des und einen Intervall z.B gr.Terz und num muss man Eingeben welcher ton raus kommt wenn man von des eine gr.Terz hoch geht (in diesem Fall f) oder man bekommt zwei noten z.B c und gis und muss den Intervall bestimmen (in diesem Fall kl.sexte). Welche Note und welcher Intervall kommt sollte natürlich zufallig sein.
    Außerdem will ich, dass sich die Zufallszahlen immer wieder änderen wenn das Programm neu gestartet wird.


  • Mod

    Also praktisch überhaupt 0 Anforderung an irgendeine Qualität der Zufallszahlen, du möchtest bloß jedes Mal einen neuen Seed, für egal welchen Generator. Du brauchst bloß ein paar Zahlen, die bei jedem Start des Programms unterschiedlich sind. Die Uhrzeit wird gerne genommen, ändert sich aber nur einmal pro Sekunde, was bedeutet, dass ein Programm, wenn es mehrmals pro Sekunde neu gestartet wird, die gleichen Zahlen bekommt. Deine Anwendung klingt nicht so, als wäre dies ein echtes Problem. Vom Betriebssystem kannst du auch eine Prozessnummer bekommen, die sich nur alle paar zigtausend Starts wiederholt. Wenn du beide Zahlen (Uhrzeit und Prozessnummer) miteinander verwurstest (z.B. mittels std::seed_seq), dann müsste das Programm schon mehrere zehntausend Mal pro Sekunde neu gestartet werden, damit man Wiederholungen bekommt.
    Das Betriebssystem selbst bietet in aller Regel auch einen globalen Zufallsgenerator an. Unter Windows ist dieser (angeblich) nicht kryptografisch sicher, daher habe ich ihn dir oben nicht empfohlen, als du nach echten Zufallszahlen fragtest. Aber als Seedgenerator für ein Spielchen ist er 100% geeignet.



  • SeppJ schrieb:

    Also praktisch überhaupt 0 Anforderung an irgendeine Qualität der Zufallszahlen, du möchtest bloß jedes Mal einen neuen Seed, für egal welchen Generator. Du brauchst bloß ein paar Zahlen, die bei jedem Start des Programms unterschiedlich sind. Die Uhrzeit wird gerne genommen, ändert sich aber nur einmal pro Sekunde, was bedeutet, dass ein Programm, wenn es mehrmals pro Sekunde neu gestartet wird, die gleichen Zahlen bekommt. Deine Anwendung klingt nicht so, als wäre dies ein echtes Problem. Vom Betriebssystem kannst du auch eine Prozessnummer bekommen, die sich nur alle paar zigtausend Starts wiederholt. Wenn du beide Zahlen (Uhrzeit und Prozessnummer) miteinander verwurstest (z.B. mittels std::seed_seq), dann müsste das Programm schon mehrere zehntausend Mal pro Sekunde neu gestartet werden, damit man Wiederholungen bekommt.
    Das Betriebssystem selbst bietet in aller Regel auch einen globalen Zufallsgenerator an. Unter Windows ist dieser (angeblich) nicht kryptografisch sicher, daher habe ich ihn dir oben nicht empfohlen, als du nach echten Zufallszahlen fragtest. Aber als Seedgenerator für ein Spielchen ist er 100% geeignet.

    nur das ich hier nichts falsch verstehe: Ist seed der Startwert für den Algorithmus, welcher dann die "Zufallszahlen" berechnet? Und kommt daher auch der Name seed (=Samen)?.

    p.s. Wie komme ich an die Daten wie Uhrzeit oder Prozessnummer?

    p.p.s Danke 👍


  • Mod

    win8789 schrieb:

    nur das ich hier nichts falsch verstehe: Ist seed der Startwert für den Algorithmus, welcher dann die "Zufallszahlen" berechnet? Und kommt daher auch der Name seed (=Samen)?.

    So ist es.

    p.s. Wie komme ich an die Daten wie Uhrzeit oder Prozessnummer?

    Die time-Funktion liefert die Uhrzeit in Form eines Integers, also genau das was du als seed haben möchtest:

    std::default_random_engine rng(std::time(0));
    

    Prozessnummern sind betriebssystemabhängig. Unter Windows gibt es die Funktion GetProcessId .



  • win8789 schrieb:

    nur das ich hier nichts falsch verstehe: Ist seed der Startwert für den Algorithmus, welcher dann die "Zufallszahlen" berechnet? Und kommt daher auch der Name seed (=Samen)?.

    ein Pseudo-Zufallsgenerator kann z.B. so implementiert sein:

    (xi+1=xia+b)modN(x_{i+1} = x_i \cdot a + b) \quad mod \quad N
    wobei es sich bei a, b, x und N um natürliche Zahlen handelt

    Du siehst, das Ding ist rekursiv - irgendwo musst du eben mal anfangen. Dafür legt du ein x0x_0 fest, deinen "Seed". Von dem ausgehend werden dann Pseudozufallszahlen berechnet. Und du siehst auch, warum das Ding Pseudo im Namen hat: die Rechenvorschrift ist nämlich alles andere als zufällig, nur die dabei rauskommenden Zahlen wirken zufällig.



  • fsdfsdfs schrieb:

    ein Pseudo-Zufallsgenerator kann z.B. so implementiert sein:

    (xi+1=xia+b)modN(x_{i+1} = x_i \cdot a + b) \quad mod \quad N
    wobei es sich bei a, b, x und N um natürliche Zahlen handelt

    gibt es eine Möglichkeit, durch die Manipulation von zwei Variablen, einen minimum und Maximum Wert zu definieren?



  • win8789 schrieb:

    fsdfsdfs schrieb:

    ein Pseudo-Zufallsgenerator kann z.B. so implementiert sein:

    (xi+1=xia+b)modN(x_{i+1} = x_i \cdot a + b) \quad mod \quad N
    wobei es sich bei a, b, x und N um natürliche Zahlen handelt

    gibt es eine Möglichkeit, durch die Manipulation von zwei Variablen, einen minimum und Maximum Wert zu definieren?

    durch oben angegebene Formel rechnest du im Restklassenring() Z/(NZ), d.h. die Zahlen (Klassen) {0, 1, ..., N-1} sind möglich.

    z.B. N=16
    a=3
    b=4
    x0=7

    ==>

    (x1=73+4=25=9) mod 16
    (x2=9
    3+4=31=1) mod 16
    ...

    (*) https://de.wikipedia.org/wiki/Restklassenring


  • Mod

    Bastel jetzt aber bloß keinen eigenen Zufallszahlengenerator! Das erste Beispiel von fsdfsdfs beschreibt, wie (eine gewisse Klasse von) Zufallszahlengeneratoren intern aufgebaut sind (weil du gefragt hast, wozu der Seed nötig ist), das zweite Beispiel von fsdfsdfs demonstriert, wie man gegebene Zufallszahlen auf einen gewissen Bereich abbilden kann. Wenn du einen eigenen Zufallszahlengenerator (von der gezeigten Klasse) mit einem kleinen N implementieren würdest, würde dieser schrecklich schlechte Ergebnisse liefern.



  • SeppJ schrieb:

    Bastel jetzt aber bloß keinen eigenen Zufallszahlengenerator! Das erste Beispiel von fsdfsdfs beschreibt, wie (eine gewisse Klasse von) Zufallszahlengeneratoren intern aufgebaut sind (weil du gefragt hast, wozu der Seed nötig ist), das zweite Beispiel von fsdfsdfs demonstriert, wie man gegebene Zufallszahlen auf einen gewissen Bereich abbilden kann. Wenn du einen eigenen Zufallszahlengenerator (von der gezeigten Klasse) mit einem kleinen N implementieren würdest, würde dieser schrecklich schlechte Ergebnisse liefern.

    ja klar, also auch von mir in aller Deutlichkeit: das war nur zur Demonstration wie man das grundsätzlich aufbauen kann! Selber basteln um das mal zu lernen: ja - selber basteln für den Produktiveinsatz: nein!!!

    Warum die Parameterwahl recht heikel ist siehst du z.B., wenn du in obigen Beispiel a=b=8 und N=16 setzt und dir mal ansiehst, wie die Zufallszahlenfolgen aussehen, die du für die Seedwerte {0, 1, ..., 15} rausbekommst.



  • fsdfsdfs schrieb:

    SeppJ schrieb:

    Bastel jetzt aber bloß keinen eigenen Zufallszahlengenerator! Das erste Beispiel von fsdfsdfs beschreibt, wie (eine gewisse Klasse von) Zufallszahlengeneratoren intern aufgebaut sind (weil du gefragt hast, wozu der Seed nötig ist), das zweite Beispiel von fsdfsdfs demonstriert, wie man gegebene Zufallszahlen auf einen gewissen Bereich abbilden kann. Wenn du einen eigenen Zufallszahlengenerator (von der gezeigten Klasse) mit einem kleinen N implementieren würdest, würde dieser schrecklich schlechte Ergebnisse liefern.

    ja klar, also auch von mir in aller Deutlichkeit: das war nur zur Demonstration wie man das grundsätzlich aufbauen kann! Selber basteln um das mal zu lernen: ja - selber basteln für den Produktiveinsatz: nein!!!

    Warum die Parameterwahl recht heikel ist siehst du z.B., wenn du in obigen Beispiel a=b=8 und N=16 setzt und dir mal ansiehst, wie die Zufallszahlenfolgen aussehen, die du für die Seedwerte {0, 1, ..., 15} rausbekommst.

    ok danke für die Antworten euch beiden.

    ich werde dann am besten so was verwenden:

    #include <iostream>
    #include <windows.h>
    #include <random>
    #include <time.h>
    
    using namespace std;
    
    int main(){
    
    	unsigned int current_time = time(0);
    
    	srand(current_time);
    
    	int anfang = 1;
    	int ende = 12;
    
    	while(true){		
    
    	int ausgabe = rand()%ende + anfang;
    	cout << ausgabe << endl;
    	Sleep(1000);
    	}
    
    }
    

Log in to reply