Random Nummer zwischen 1 und 100 generieren



  • Wie generiert man einen Integer zwischen 1 und 100?



  • int a = 50;
    

    edit:
    ok, sorry. das ist wahrscheinlich was du suchst:

    #include <ctime>
    #include <cstdlib>
    
    int main()
    {
        std::srand(std::time(0));
        int a = std::rand() % 100 + 1;
    }
    


  • std::srand hat keinen tatsächlichen Member "srand"



  • Die bessere Methode nach C++11 wäre

    #include <random>
    
    std::default_random_engine e;
    std::uniform_int_distribution<int> d(1, 100);
    int a =  d(e);
    


  • TNA schrieb:

    Die bessere Methode nach C++11 wäre

    #include <random>
    
    std::default_random_engine e;
    std::uniform_int_distribution<int> d(1, 100);
    int a =  d(e);
    

    Warum ist sie besser?



  • volkard schrieb:

    TNA schrieb:

    Die bessere Methode nach C++11 wäre

    #include <random>
    
    std::default_random_engine e;
    std::uniform_int_distribution<int> d(1, 100);
    int a =  d(e);
    

    Warum ist sie besser?

    Die Zahlen sind wirklich gleichverteilt, was bei der Modolovariante nicht der Fall ist (weitverbreiteter fehler). Zudem ist der Seed nicht global, man kann die Random Engine austauschen und vieles mehr.


  • Mod

    volkard schrieb:

    Warum ist sie besser?

    Vielleicht ein besserer PRNG. default_random_engine ist ja nicht standardmäßig der lineare Kongruenzgenerator.



  • Arcoth schrieb:

    Vielleicht ein besserer PRNG. default_random_engine ist ja nicht standardmäßig der lineare Kongruenzgenerator.

    Muss nicht unbedingt sein. Die C PRNG taugt aber tatsächlich nicht viel. Wenn es wirklich gut sein soll würde ich den Mersenne-Twister empfehlen. Der erzeugt qualitativ sehr hochwertige Zufallszahlen, und dabei sogar noch sehr performant. Nur für Kryptografie eignet er sich nicht. Der hätte meiner Meinung nach der Standard sein sollen.



  • TNA schrieb:

    Die Zahlen sind wirklich gleichverteilt, was bei der Modolovariante nicht der Fall ist (weitverbreiteter fehler).

    Weitverbreiteter Fehler, daß man echte Gleichverteilung überall brauchen würde.

    TNA schrieb:

    Zudem ist der Seed nicht global, man kann die Random Engine austauschen und vieles mehr.

    Zu >99% meines Zufallszahlenbedarfs auch irrelevant, genauso wie die genaue Gleichverteilung, sorry.

    Sagem wir, die C++11-Variante ist "moderner", klingt auch toll positiv. So ein hartes "besser" würde ich da meiden.



  • TNA schrieb:

    Arcoth schrieb:

    Vielleicht ein besserer PRNG. default_random_engine ist ja nicht standardmäßig der lineare Kongruenzgenerator.

    Muss nicht unbedingt sein. Die C PRNG taugt aber tatsächlich nicht viel. Wenn es wirklich gut sein soll würde ich den Mersenne-Twister empfehlen. Der erzeugt qualitativ sehr hochwertige Zufallszahlen, und dabei sogar noch sehr performant. Nur für Kryptografie eignet er sich nicht. Der hätte meiner Meinung nach der Standard sein sollen.

    Der MT ist nach meinen Messungen einfach nur lahm. Schon immer.
    Hat's nur zu was gebracht, weil auf seiner Homepage ultra-schnelle Messungen standen. Und die lange Periode beeindruckt natürlich.
    Ich bevorzuge Multiply-With-Carry, ja ich kenne seine Schwäche, und dennoch.



  • volkard schrieb:

    Weitverbreiteter Fehler, daß man echte Gleichverteilung überall brauchen würde.

    Man kann sich sicherlich darüber streiten, wie störend das im Einzelfall ist, aber Menschen die so etwas hinschreiben wie

    int a = std::rand() % 100 + 1;
    

    erwarten davon doch in aller Regel, dass die Zahlen 1 bis 100 mit der gleichen Wahrscheinlichkeit auftreten. Das markt man insbesondere bei der üblichen Implementierung des Würfelwurfs.



  • Arcoth schrieb:

    volkard schrieb:

    Warum ist sie besser?

    Vielleicht ein besserer PRNG. default_random_engine ist ja nicht standardmäßig der lineare Kongruenzgenerator.

    In der nächsten GCC-Version ist aber default_random_engine der der verhasste lineare Kongruenzgenerator und rand einer, an dem Du mehr Freude hast.



  • Das tolle an std::random ist ja, dass jeder die Engine wählen kann, die er möchte. Was auch sehr praktisch bei den Engines ist ist, das sich der State speichern und wiederherstellen lässt. Das ist bei der Spieleprogrammierung recht hilfreich.


  • Mod

    Das ist bei der Spieleprogrammierung recht hilfreich.

    Bei Spieleprogrammierung reicht fast immer rand() . Da braucht keiner einen Mersenne-Twister.

    Der MT ist nach meinen Messungen einfach nur lahm. Schon immer.

    👍



  • Arcoth schrieb:

    Bei Spieleprogrammierung reicht fast immer rand() . Da braucht keiner einen Mersenne-Twister.

    Es ging bei der Aussage um das Wiederherstellen des States. Viele Spieleprogrammierer programmieren tatsächlich noch C++ wie vor 20 Jahren üblich, aber nicht, weil das besser wäre.





  • TNA schrieb:

    Menschen die so etwas hinschreiben wie

    int a = std::rand() % 100 + 1;
    

    erwarten davon doch in aller Regel, dass die Zahlen 1 bis 100 mit der gleichen Wahrscheinlichkeit auftreten. Das markt man insbesondere bei der üblichen Implementierung des Würfelwurfs.

    Merkt man das??? Lass uns das mal testen.

    Ich habe mal den alten und neuen Weg programmiert und 10-mal laufen lassen. 5-mal alt, 5-mal neu.
    Wie http://ideone.com/Z93nQd aber anderer Steuerstring p.
    Meine Ausgabe ist

    166759 165815 166622 166696 167660 166448
    166321 167016 166208 167186 166949 166320
    166396 165704 167432 166344 167246 166878
    165775 166800 167044 166489 167100 166792
    167233 166934 166505 166346 166438 166544
    166270 167389 166803 166002 166313 167223
    166976 166806 166511 166162 167146 166399
    166702 166154 166646 167392 167004 166102
    166114 166453 166813 166996 166401 167223
    166452 166328 167152 166764 166371 166933
    

    Würdest Du mir bitte sagen, was in p stand, und wie Du es abgelesen hast?



  • Wenn dein Hauptkriterium Geschwindigkeit ist, dann wird wohl alles langsamere eben immer schlecht dastehen. Der grosse Nachteil mit rand/srand fuer mit ist, dass der Zufallsgenerator global ist. Das vertraegt sich schlecht mit mehreren Threads.



  • dsdsds schrieb:

    std::srand hat keinen tatsächlichen Member "srand"

    richtig, funktionen können nie member haben!

    volkard schrieb:

    TNA schrieb:

    Die Zahlen sind wirklich gleichverteilt, was bei der Modolovariante nicht der Fall ist (weitverbreiteter fehler).

    Weitverbreiteter Fehler, daß man echte Gleichverteilung überall brauchen würde.

    TNA schrieb:

    Zudem ist der Seed nicht global, man kann die Random Engine austauschen und vieles mehr.

    Zu >99% meines Zufallszahlenbedarfs auch irrelevant, genauso wie die genaue Gleichverteilung, sorry.

    Sagem wir, die C++11-Variante ist "moderner", klingt auch toll positiv. So ein hartes "besser" würde ich da meiden.

    das hat mir gerade die worte aus dem mund genommen.



  • volkard schrieb:

    TNA schrieb:

    Menschen die so etwas hinschreiben wie

    int a = std::rand() % 100 + 1;
    

    erwarten davon doch in aller Regel, dass die Zahlen 1 bis 100 mit der gleichen Wahrscheinlichkeit auftreten. Das markt man insbesondere bei der üblichen Implementierung des Würfelwurfs.

    Merkt man das??? Lass uns das mal testen.

    Lies bitte nochmal was ich geschrieben habe. Man merkt daran, dass eigentlich eine Gleichverteilung erwartet wurde.

    volkard schrieb:

    Ich habe mal den alten und neuen Weg programmiert und 10-mal laufen lassen. 5-mal alt, 5-mal neu.
    Wie http://ideone.com/Z93nQd aber anderer Steuerstring p.
    Meine Ausgabe ist

    166759 165815 166622 166696 167660 166448
    166321 167016 166208 167186 166949 166320
    166396 165704 167432 166344 167246 166878
    165775 166800 167044 166489 167100 166792
    167233 166934 166505 166346 166438 166544
    166270 167389 166803 166002 166313 167223
    166976 166806 166511 166162 167146 166399
    166702 166154 166646 167392 167004 166102
    166114 166453 166813 166996 166401 167223
    166452 166328 167152 166764 166371 166933
    

    Würdest Du mir bitte sagen, was in p stand, und wie Du es abgelesen hast?

    N=5 ist hier viel zu klein, als das man das statistisch mit genügender Wahrscheinlichkeit bestimmen könnte. Ändert allerdings trotzdem nichts daran, das deine alte Methode unfaire Ergebnisse produziert. Jetzt kann man sich lange darüber streiten, wie praxisrelevant das in konkreten Fällen ist. Für mich wäre es allerdings nicht ausreichend, dass ein Programm nur ein bisschen falsch ist.


Anmelden zum Antworten