Zufallszahl generieren.



  • std::mt19937 create_seeded_rng() 
    { 
        std::random_device rd; 
        std::array<std::mt19937::result_type, std::mt19937::state_size> seed_data; 
        std::generate(seed_data.begin(), seed_data.end(), std::ref(rd)); 
        std::seed_seq seq(seed_data.begin(), seed_data.end()); 
        return std::mt19937(seq); 
    } 
    
    int main() 
    { 
        std::mt19937 rng = create_seeded_rng(); 
        std::uniform_int_distribution<int> dist(0, 100);
    
        for (unsigned i = 0; i != 100; ++i) 
            std::cout << dist(rng) << '\n'; 
    }
    

    Damit kann ich nichts anfangen.



  • ist Chechen65 der neue frühlingstroll? 🙂



  • Jetzt siehst du mal den Unterschied zwischen C mit cout (das Programm das du gepostet hast) und modernen C++.

    Hast du den Link aus der ersten Zeile des Posts von cooky451 verfolgt?



  • Ich weis nicht was euer Problem ist 😞
    Man kann einfach keine normal Antwort hier erwarten.

    Wenn ich sage das ich ein Anfänger bin. Dann muss man damit rechnen das ich nicht mit so einem Script klar komme.

    Ich schaue mir gerade die Seite an.



  • DirkB schrieb:

    Jetzt siehst du mal den Unterschied zwischen C mit cout (das Programm das du gepostet hast) und modernen C++.

    Jo, 2 Zeilen C == 17 Zeilen C++.



  • unterscheider schrieb:

    DirkB schrieb:

    Jetzt siehst du mal den Unterschied zwischen C mit cout (das Programm das du gepostet hast) und modernen C++.

    Jo, 2 Zeilen C == 17 Zeilen C++.

    Genau das hab ich mit auch gedacht.
    Modernes C++ macht alles komplexer.



  • Vereinfachen wir das mal.

    int main()
    {
        std::mt19937 rng(time(NULL));//initialisiere einen Zufallszahlengenerator mit namen rng mit dem seed der aktuellen zeit.
        std::uniform_int_distribution<int> dist(0, 100);//dist stellt gleichverteilte Zufallszahlen zwischen 0 und 100 dar. Aufpassen: die 100 ist auch drin.
    
        for (unsigned i = 0; i != 100; ++i)
            std::cout << dist(rng) << '\n';//benutze den rng um eine Zufallszahl zwischen 0 und 100 zu erzeugen.
    }
    

    Der Rest von cooky war so Profi zeugs, welches die meisten Leute nicht brauchen 🤡



  • Chechen65 schrieb:

    Und wie bekomme ich das so hin das nur die Zahlen 1 - 3 generiert werden?

    rand()%3 ergibt Zahlen 0-2
    rand()%3+1 ergibt Zahlen 1-3



  • als würde man das so direkt gegenüber stellen können...
    die zufallszahlen aus dem mersenne twister sind viel besser als die mit einem kongruenzgenerator + modulo. wenn man monte carlo simulationen macht, dann wird man das schon merken.



  • asfdlol schrieb:

    als würde man das so direkt gegenüber stellen können...
    die zufallszahlen aus dem mersenne twister sind viel besser als die mit einem kongruenzgenerator + modulo. wenn man monte carlo simulationen macht, dann wird man das schon merken.

    Nö, eigentlich nicht. Wer an die Ausnahmen gerät, der wird eh schon seinen Lieblingsgenerator aussuchen gefunden haben.

    Ich denke nicht, daß es schon polizeilich verboten wäre, daß Chechen65 und ich gerne rand() benutzen.



  • volkard schrieb:

    asfdlol schrieb:

    als würde man das so direkt gegenüber stellen können...
    die zufallszahlen aus dem mersenne twister sind viel besser als die mit einem kongruenzgenerator + modulo. wenn man monte carlo simulationen macht, dann wird man das schon merken.

    Nö, eigentlich nicht. Wer an die Ausnahmen gerät, der wird eh schon seinen Lieblingsgenerator aussuchen gefunden haben.

    Ich denke nicht, daß es schon polizeilich verboten wäre, daß Chechen65 und ich gerne rand() benutzen.

    nein, verboten ist es logisch nicht, lol.
    du nutzt direkt rand() für alle viele (edit 3, zu doof das geschriebene richtig zu interpretieren) anwendungen? wusste ich nicht. ich glaubte mal aus einem anderen thread aufgeschnappt zu haben, dass du eine modifizierte multiply-with-carry-version nimmst.

    edit: ich wollte mich nur gegen die aussage wehren, dass c++ sinnlos verkompiziert. dabei bieten die c++11 prngs viel mehr möglichkeiten.

    edit 2: in spielen oder so was nutze ich auch rand(), gar keine frage.



  • DirkB schrieb:

    Jetzt siehst du mal den Unterschied zwischen C mit cout (das Programm das du gepostet hast) und modernen C++.
    Hast du den Link aus der ersten Zeile des Posts von cooky451 verfolgt?

    Der ist in dem Kontext ungefähr so sinnvoll wie

    "
    Ich hab Die mal eine Zusammenstellung der wichtigsten Buchstaben gesucht, damit kannste Dir die richtigen Antworten dann selber zusammenbauen: http://us.123rf.com/400wm/400/400/artenot/artenot0909/artenot090900131/5521213-isolated-cartoon-color-plasticine-alphabet-on-a-white-background.jpg
    "



  • asfdlol schrieb:

    du nutzt direkt rand() für alle anwendungen?

    Nicht für alle.

    asfdlol schrieb:

    ich glaubte mal aus einem anderen thread aufgeschnappt zu haben, dass du eine modifizierte multiply-with-carry-version nimmst.

    Jo, sobald rand nicht mehr reicht.

    asfdlol schrieb:

    edit 2: in spielen oder so was nutze ich auch rand(), gar keine frage.

    Genau, meine ich doch. Gut zu wissen, daß im Standard-C++ auch die Kanonen zu finden sind.



  • volkard schrieb:

    Jo, sobald rand nicht mehr reicht.

    Also immer.

    Ich glaube ihr würdet rand auch benutzen, wenn das so implementiert wäre:

    int rand() { return 42; }
    

    Liefert ja auch eine zufällig ausgewählte Zahl.



  • Das Problem ist doch eher, dass es in C++ keine Funktion gibt, um direkt eine gleichverteilte Zufallszahl (Ganz- oder Fliesskommazahl) in einem beliebigen Intervall zu erzeugen. Man muss dazu jeweils die Distributions und Engines nehmen, teilweise braucht man sie aber gar nicht. Für C++14 wurde daher auch std::pick_a_number() vorgeschlagen.

    rand() % anzahl hat den entscheidenden Nachteil, dass die Gleichverteilung kaputt ist. Da könnte rand() selbst noch so gut implementiert sein.



  • TyRoXx schrieb:

    volkard schrieb:

    Jo, sobald rand nicht mehr reicht.

    Also immer.

    Also fast nie.



  • Nexus schrieb:

    rand() % anzahl hat den entscheidenden Nachteil, dass die Gleichverteilung kaputt ist. Da könnte rand() selbst noch so gut implementiert sein.

    Dieser "entscheidende" Nachteil hat bei mir noch nie dazu geführt, daß der Benutzer den "Zufall" vorhersehen konnte oder daß die Monster eine sichtbare Tendenz dazu hatten, sich am linken Bildschirmrand aufzuhalten.



  • Nexus schrieb:

    Das Problem ist doch eher, dass es in C++ keine Funktion gibt, um direkt eine gleichverteilte Zufallszahl (Ganz- oder Fliesskommazahl) in einem beliebigen Intervall zu erzeugen. Man muss dazu jeweils die Distributions und Engines nehmen, teilweise braucht man sie aber gar nicht. Für C++14 wurde daher auch std::pick_a_number() vorgeschlagen.

    So etwas gehört nicht in den Standard. Die Bandbreite der möglichen Implementationen so einer Funktion würde dazu führen, dass sie für jeden speziellen Zweck nutzlos wäre.
    Es gibt diese Möglichkeiten:
    - Naiv wie rand . Schnelle, aber nutzlose Ergebnisse.
    - Mit Pseudozufall wie zum Beispiel Mersenne-Twister. Der Standard wird den Algorithmus nicht vorschreiben. Je nach tatsächlich verwendetem Algorithmus kann das zu langsam werden für viele Anwendungen. Der Punkt ist, dass ich als Benutzer keine Ahnung habe wie lange die Funktion auf der CPU herumeiern könnte. -> Energieverschwendung.
    - Zufall. Benötigt einen Systemaufruf oder eine spezielle Hardware-Instruktion. Der Systemaufruf kann zu teuer sein. Die Instruktion kann Marke NSA sein und die meisten Prozessoren haben die noch gar nicht.

    Es gibt keinen universellen Zufallsgenerator. In jedem wichtigen Programm wird diese Funktion also von vornherein verboten sein und man wird bewusst die Algorithmen je nach Anforderung wählen. In einer Hobby-Spielerei kann man sich die Funktion einfach selbst zusammenkloppen.

    Das Implementierungsbeispiel im Proposal ist obendrein auch noch falsch, weil nicht threadsafe.
    Selbst bei korrekter Implementierung würde der globale Pseudozufallsgenerator zu sicherheitsrelevanten Defekten führen. Implementierung A liefert Zufall; Programmierer verlassen sich darauf; Programmierer machen Crypto damit; Implementierung B liefert Pseudozufall; Programmierer portieren 1:1 von A nach B; fail.



  • TyRoXx schrieb:

    - Mit Pseudozufall wie Mersenne-Twister. Je nach verwendetem Algorithmus kann das zu langsam werden für viele Anwendungen. Der Punkt ist, dass ich als Benutzer keine Ahnung habe wie lange die Funktion auf der CPU herumeiern könnte. -> Energieverschwendung.

    Was heisst hier "je nach verwendetem Algorithmus"? Der Algorithmus für den Mersenne-Twister ist genau definiert. (Ja, die default_random_engine ist unnötig.)


  • Mod

    TyRoXx schrieb:

    - Naiv wie rand . Schnelle, aber nutzlose Ergebnisse.

    Ich habe mal das strittige Wort hervor gehoben. rand ist nicht nutzlos. rand ist für alle Anwendungen ausreichend, bei denen der Programmierer sich nicht mit den Feinheiten von Zufallszahlgeneratoren auseinander setzt. Und das ist der überwiegende Teil. Du bist da vielleicht einem falschen Bias ausgesetzt, wenn du im Bereich des wissenschaftlichen Rechnens oder der Kryptografie tätig bist. Wer keine Ahnung von PRNGs hat, für den ist rand (und auch die modulo-Methode) absolut ausreichend. Ein nutzerfreundlicheres Interface für eine solche Funktionalität ist durchaus zu begrüßen.


Anmelden zum Antworten