Gleichverteilung Random


  • Mod

    Erhard Henkes schrieb:

    Ich erinnere mich dunkel, dass Volkard, Marcus und ich einen gleichverteilten Zufallszahlengenerator gebastelt haben. Muss hier irgendwo vergraben sein (Suchfunktion findet ihn nicht), sobald ich ihn gefunden habe, zeige ich ihn. Da waren die Zahlenhäufigkeiten im Milliardenbereich absolut gleich.

    Dann waren die Zufallszahlen aber nicht gleichverteilt in dem Sinne, wie man das Wort normalerweise verwendet, da sie irgendwie korreliert wären. Siehe Arcoths Rechnung.



  • Wenn du ne Reihe willst wo alle Zahlen exakt gleich oft vorkommen dann nimm halt random_shuffle .

    Ist dann aber wie SeppJ schon impliziert hat kein so guter Zufall mehr wie wenn du die "Fehler" in der Gleichverteilung akzeptierst.



  • Erhard Henkes schrieb:

    Ich erinnere mich dunkel, dass Volkard, Marcus und ich einen gleichverteilten Zufallszahlengenerator gebastelt haben. Muss hier irgendwo vergraben sein (Suchfunktion findet ihn nicht), sobald ich ihn gefunden habe, zeige ich ihn. Da waren die Zahlenhäufigkeiten im Milliardenbereich absolut gleich.

    Meinst du den Thread? https://www.c-plusplus.net/forum/47483-full


  • Mod

    @Erhard Mit deinem Code bekomme ich

    1: 16665217
    2: 16664601
    3: 16669229
    4: 16671513
    5: 16667476
    6: 16661964
    

    Das ist nicht besser.



  • hustbaer schrieb:

    Wenn du ne Reihe willst wo alle Zahlen exakt gleich oft vorkommen dann nimm halt random_shuffle .

    Ach ne, das ist zu einfach! Ich schlage vor

    for ( int i=1; i<= limit; ++i)
    

    durch

    for (;;)
    

    zu ersetzen. Wenn er damit durch ist sind auch alle Zahlen exakt gleich oft vorgekommen 😃
    ... ist aussedem schneller, weil man sich das inkrementieren und das Prüfen der Schleifeninvariante spart 🤡


  • Mod

    Ist leider nicht 100% RandomNumberDistribution kompatibel (aber 99%):

    #include <random>
    #include <vector>
    #include <limits>
    #include <algorithm>
    
    template< class IntType = int > class super_random_uniform_int_distribution
    {
    public:
    
      class param_type
      {
        IntType a, b;
        std::size_t range;
        std::vector< IntType > pool;
       public:
        typedef super_random_uniform_int_distribution<IntType> distribution_type;
    
        param_type(IntType a = 0, IntType b = std::numeric_limits<IntType>::max() ):
          a(a), b(b), range(b-a), pool(range+1) 
        { std::iota(pool.begin(), pool.end(), a); }
    
        friend distribution_type;
      };
    
      typedef IntType result_type;
    
      super_random_uniform_int_distribution( IntType a = 0,
                                                IntType b = std::numeric_limits<IntType>::max() ) : params(a, b) { }
      super_random_uniform_int_distribution( const param_type& params ): params(params) { }
    
      void reset() { params.range = params.b - params.a; }
    
      template< class Generator >
      result_type operator()( Generator& g )
      {
        std::uniform_int_distribution<std::size_t> d(0, params.range);
        std::size_t rn = d(g);
        IntType i = params.pool[rn];
        std::swap(params.pool[rn], params.pool[params.range]);
        if (params.range == 0) reset(); else --params.range;
        return i;
      }
    
      template< class Generator >
      result_type operator()( Generator& g, const param_type& params )
      {
        std::uniform_int_distribution<std::size_t> d(0, params.range);
        std::size_t rn = d(g);
        return params.pool[rn];
      }
    
      result_type a() const { return params.a; }
      result_type b() const { return params.b; }
    
      param_type param() const { return params; }
      void param( const param_type& params ) { this->params = params; }
      result_type min() const { return a(); }	
      result_type max() const { return b(); }
    private:
      param_type params;
    };
    
    #include <iostream>
    int main()
    {
      std::random_device rd;
      std::mt19937 gen(rd());
      super_random_uniform_int_distribution<> six(1, 6);
      int H[6] = {0,0,0,0,0,0};
      const long long unsigned int limit = 100000001;
      for ( long long unsigned int i=0; i<= limit; ++i )
        ++H[six(gen)-1];
      for (int i=0; i<6; ++i)
        {
          std::cout << "H[" << i+1 << "] = " << H[i]++ << "\n\n";
        }  
    }
    

    (Operatoren ==, !=, << und >> überlasse ich als Fleißaufgabe dem geneigten Leser)

    H[1] = 16666667
    
    H[2] = 16666667
    
    H[3] = 16666667
    
    H[4] = 16666667
    
    H[5] = 16666667
    
    H[6] = 16666667
    

    Eindeutig perfekter Zufall 😃



  • auch nicht schlecht

    unsigned int myRand()//geringe Abweichungen bei COUNT GROUP BY myRand%egal und lecker schnell
    {
       static x=0;
       return x++;
    }
    


  • Übringens hängt dem mt der Ruf an, ein wenig *zu gleichverteilt* zu sein, was so die Ergebnisse von diehard und Konsorten angeht.



  • @SeppJ
    Falls du es schaffst die Distribution einer Online-Roulette Bude anzudrehen lass es mich bitte wissen 🤡


  • Mod

    hustbaer schrieb:

    @SeppJ
    Falls du es schaffst die Distribution einer Online-Roulette Bude anzudrehen lass mich es mich bitte wissen 🤡

    Hmm... Vielleicht sollte ich die Klasse einfach super_random_uniform_int_distribution nennen und hier so stehen lassen oder auf github veröffentlichen. Irgendein fauler Programmierer wird sicherlich darüber stolpern und sie einfach so übernehmen 🙂



  • Ja, mach mal! 😃



  • SeppJ schrieb:

    hustbaer schrieb:

    @SeppJ
    Falls du es schaffst die Distribution einer Online-Roulette Bude anzudrehen lass mich es mich bitte wissen 🤡

    Hmm... Vielleicht sollte ich die Klasse einfach super_random_uniform_int_distribution nennen und hier so stehen lassen oder auf github veröffentlichen. Irgendein fauler Programmierer wird sicherlich darüber stolpern und sie einfach so übernehmen 🙂

    Nee, schauen wir vom Mersenne Twister ab, der auf allen Architekuren, wo ich ihn gemessen hatte die veröffentlichten Zahlen um Faktor 4 und mehr unterschritten hatte, ein Jahrzehnt(!) lang. Inzwischen hat er aufgeholt. Er war von Anfang an ungepüft ge-hype-d.

    Nennen wir ihn zum Beispiel GHRTumbler und stützen uns (angeblich) auf die GHR mit lauter Hyperlinks auf die "generalized Riemann hypothesis". Statt den GHRTumbler zu erklären wird die GHR erklärt. Minimales FaselBlasel dazu für den GHRTumbler. Als Veröffentlicher sei mal spaßig und tauche als Portugiese auf.

    Wenn Du es übertreiben willst, such Dir als Doktorvater einen kürzlich verstorbenen möglichst bekannten Mathematiker aus. Das wird keiner prüfen. Türlich keinen Portugiesen, sondern einen von wo man die Uni kennt und (MIT) oder (Stanford Uni) dranschreibt.

    lass mich es mich bitte wissen 🤡


  • Mod

    Wir sollten Jürgen Wolf bestechen, damit er "PRNGs von A bis Z" schreibt und darin speziell für Roulette-Tische konzipierte Zufallsgeneratoren preist, deren Code von SeppJ stark mittels Templates entstellt und auf mehrere hundert LOCs gestreckt wurde. Auf den Einband kommt "Das umfassende PRNG-Handbuch zum Lernen und Nachschlagen! Einsteiger erhalten eine gründliche und kompetente Einführung in moderne Pseudo Zufallszahlen-Generatoren. Viele praktische Beispiele und präzise Erläuterungen garantieren einen schnellen Lernerfolg. [..]"
    Und Wolfs Standardspruch "Mein Traum ist es, im Westen Kanadas zu leben. Und Bücher auf der Veranda schreiben."

    Das ganze wird dann von einem bezahlten Rezensenten in den Himmel gelobt.



  • Meinst du den Thread? https://www.c-plusplus.net/forum/47483-full

    Danke für den Link! Echt eine Ewigkeit her. ich hatte noch die Prozentverteilungen im Kopf. Wie man sich über die Jahre täuschen kann, wenn man sich nur die ersten drei Digits (von 6 bis 7) einprägt. Gut dann können wir das bequeme C++ 11 Konstrukt einsetzen, wenn es nicht schlechter ist.


Anmelden zum Antworten