Zufallszahlen



  • Nachdem ich euch jz mehrere Wochen in Ruhe gelassen habe, muss ich doch ma wieder nerven ^^
    Ich weiß - hier gibts nen schönen Artikel zum Thema Zufallszahlen - aber da hab ich leider nicht das gefunden, was ich gesucht hatte...

    Zum eigtl Problem:
    Ich würde gerne den aktuellen Zufallszahlen-Seed vor der Benutzung von rand() speichern, damit ich ihn danach wieder zurücksetzen kann - aus dem einfachen Grund, damit ich die rand-funktionalität in eine Klasse auslagern kann, aber verschiedene Ketten von (Pseudo-)Zufallszahlen erzeugen kann - wieso das so wichtig ist? Bei einer Simulation sollten die Zahlen ja ein wenig zufällig sein aber auf jeden Fall reproduzierbar - also brauch ich z.bsp. ein random-seed für den bedarf und einen seed für iwelche verteilungen...
    Geht das mit den stl-funktionen rand/srand oder müsste ich mir da ne andere lib suchen?

    Danke scho mal

    bb



  • Log doch den Seed Wert einfach mit. Anstatt direkt zu initialisieren, machst du den Seed zuerst in eine Variable, speicherst die ab und dann initialsierst du srand damit..



  • Möglichkeit 1:

    // Demonstration einer Zufallsfunktion
    #include <stdlib.h>
    
    int main()
    {
       const int IrgentEinStartWert = 9;
       long Zufall; // Hier wird das ergebis stehen...
       srand(IrgentEinStartWert); // Würfel schütteln... (generieren)
       Zufall = rand(); // Einmal werfen.
       Zufall = rand(); // Nochmal werfen.
    }
    

    Möglichkeit 2:

    // Demonstration einer Zufallsfunktion
    #include <stdlib.h>
    
    int main()
    {
       const int IrgentEinStartWert = 9;
       long Zufall; // Hier wird das ergebis stehen...
       srand(IrgentEinStartWert); // Würfel schütteln... (generieren)
       Zufall = rand() % 6 + 1; // Generiert eine Zahl zwischen 1 bis 6.
    }
    

    Das sollte eigentlich funktionieren, eine andere Lösung habe ich grad nicht da, aber ich finde die nicht so gut, da man hierbei auf einen C-Header zurück greifen muss...
    Falls du eine C++ Wariante findest benutze lieber die, aber bei einfachen projekten dürfte es keinen unterschied machen...

    Mfg Wikinger75!



  • Z.B. so:

    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class Generator
    {
        public:
            Generator();
            Generator( long seed );
    
            int random() const;
            void reset();
    
        private:
            long m_seed;
    };
    
    Generator::Generator()
     : m_seed(0)
    {
        time( &m_seed );
        reset();
    }
    
    Generator::Generator( long seed )
     : m_seed(seed)
    {
        reset();
    }
    
    void Generator::reset()
    {
        srand( static_cast<unsigned>(m_seed) );
    }
    
    int Generator::random() const
    {
        return rand();
    }
    
    int main()
    {
        Generator g;
        cout << "Erster Lauf:" << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
    
        g.reset();
    
        cout << "Zweiter Lauf:" << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
        cout << g.random() << endl;
    
        return 0;
    }
    


  • ihr habts nicht verstanden



  • wetten schrieb:

    ihr habts nicht verstanden

    Kann sogar sein.
    Dann macht man sich halt noch nen Vector als Member, an den man bei nem random() den Wert anhängt. Dann sollte man doch ohne Weiteres auch diesen (und die ganzen letzten random()s) wieder bekommen, um die Simulation zu wiederholen.



  • Ich kenne mich da jetzt zwar nicht besonders aus, aber reicht es denn den Seed zu speichern?
    Ich meine selbst wenn die Selbe "Zufallsreihenfolge" gestartet wird, braucht es beim zweiten durchlauf nur einmal zu ruckeln (z.B. wenn im Hintergrund irgendwas passiert) und man hat eine Verschiebung der auftauchenden Zahlen.

    Beispiel:
    Durchlauf 1:

    Situation1 = 5
    Situation2 = 9
    Situation3 = 22
    Situation4 = 3
    Situation5 = 17
    Situation6 = 2

    Durchlauf 2:

    Situation1 = 5
    Situation2 = 9
    Situation3 = 22
    // Irgendwas im Hintergrund passiert dass den Programmfluss, Logikberechnung oder was auch immer ein kleines bischen zum stocken bringt
    Situation4 = 17 // <-- hier sollte jetzt 3 sein
    Situation5 = 2 // <-- hier sollte jetzt 17 sein
    Situation6 = 666 / <--- Die zahl ist neu und das Böse nimmt seinen Lauf.



  • Kahino schrieb:

    Ich meine selbst wenn die Selbe "Zufallsreihenfolge" gestartet wird, braucht es beim zweiten durchlauf nur einmal zu ruckeln (z.B. wenn im Hintergrund irgendwas passiert) und man hat eine Verschiebung der auftauchenden Zahlen.

    Nein, keine Angst, die Reihe bleibt beim gleichen Seed auch gleich, egal wie lange das nächste rand() weg ist.


  • Administrator

    Kahino schrieb:

    Ich kenne mich da jetzt zwar nicht besonders aus, aber reicht es denn den Seed zu speichern?

    Ja, zumindest im Falle von solchen Zufallsgeneratoren, welche über einen Seed arbeiten. Dies sind schliesslich nur pseudo Zufallsgeneratoren, intern haben die auch eine Formel, welche die Zufallszahlen entstehen lässt. Die nächste Zufallszahl ist in einem solchen System immer von der vorhergehenden abhängig, bzw. schlussendlich vom Seed.

    Es gibt andere Generatoren, welche zum Beispiel mit Störgeräuschen im Computer arbeiten, oder solche Dinge. Die sind dann wirklich zufällig, haben aber keinen Seed mehr.

    Grüssli





  • Erhard Henkes schrieb:

    Schau mal hier nach, vielleicht findest Du da was Brauchbares, das Du anpassen kannst:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-47483-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-w�rfel-and-start-is-50.html

    Danke - werd ich wo dann wirklich so relativ hässlich machen müssen ^^
    Aber ich hatte eben gehofft, dass es mit weniger tipp-Aufwand geht und irgendwie eleganter aussieht 😉

    An die anderen: wetten hat recht ^^ eigtl fand ichs nicht so schlecht von mir beschrieben - entweder ihr solltet besser lesen oder ich besser beschreiben lernen - naja... ^^

    Damit auch der Letzte versteht, was ich wollte:

    TRandomClass rnd1 (123);
    std::cout << rnd1.rand() << std::endl;
    
    //-------------------->
    TRandomClass rnd2 (231);
    std::cout << rnd2.rand() << std::endl;
    //<--------------------
    
    std::cout << rnd1.rand() << std::endl;
    

    und egal, ob das gemarkte auskommentiert ist oder nicht sollte am ende die gleiche zahl rauskommen...

    bb


  • Administrator

    Ehm, was hat das mit dem Seed zurücksetzen zu tun? Du willst einfach zwei Random Objekte, welche dir Zufallszahlen liefern zu einem unterschiedlichen Seed. Dann benutz doch die Boost.Random Bibliothek:
    http://www.boost.org/doc/libs/1_38_0/libs/random/index.html

    Grüssli



  • Gut - gibts also doch was von boost ^^
    Naja - ich hätte ja den Seed jedes mal mit dem gespeicherten für das objekt swappen müssen, die fkt ausführen und dann wieder den gespeicherten setzen müssen...
    hatte mir das eigtl so gedacht gehabt (nur eben bissl gekapselt ^^):

    srand(123);
    std::cout << rand() << std::endl;
    
    long tmp = GetRandomSeed();
    srand(213);
    std::cout << rand() << std::endl;
    srand(tmp);
    
    std::cout << rand() << std::endl;
    

    man hätte auch ganz einfach die funktion rand() kopieren können und in der eigenen klasse verwenden können - so wie das unter dem link 3-5 posts über dem hier ist - aber das wollte ich nicht...
    naja - ich nehm boost - danke 🙂

    bb



  • Mir kommen hier grad ein paar fragen auf^^
    Gibt es dekomentationen zu

    #include <ctime>
    #include <cstdlib>
    

    falls ja wo?

    Und gibt es auch eine c++ wariante von denen und zu denne Dokumentationen?^^

    Mfg Wikinger75



  • Wikinger75 schrieb:

    Und gibt es auch eine c++ wariante von denen

    das sind bereits die c++-varianten.



  • häh?
    ich hab ja nix ggn fehlende interpunktion - so lang man den sinn noch verstehen kann sind mir auch tip- bzw rechtschreibefehler egal... aber du übertreibst ein wenig ^^

    falls ich dich richtig verstanden habe - da gibt es unter anderem das hier:

    http://www.cplusplus.com/reference/
    http://www.cppreference.com/wiki/

    bb



  • Wikinger75 schrieb:
    Und gibt es auch eine c++ wariante von denen

    das sind bereits die c++-varianten.

    Warum heit das dan cstdlib und nicht stdlib?

    häh?
    ich hab ja nix ggn fehlende interpunktion - so lang man den sinn noch verstehen kann sind mir auch tip- bzw rechtschreibefehler egal... aber du übertreibst ein wenig ^^

    falls ich dich richtig verstanden habe - da gibt es unter anderem das hier:

    http://www.cplusplus.com/reference/
    http://www.cppreference.com/wiki/

    bb

    Ich meinte eine Dokumentation zu den 2 Headern, damit ich weiß was für funktion etc. diese beinhalten^^
    Das was du gepostet hast sieht recht gut aus.



  • Wikinger75 schrieb:

    Wikinger75 schrieb:
    Und gibt es auch eine c++ wariante von denen

    das sind bereits die c++-varianten.

    Warum heit das dan cstdlib und nicht stdlib?

    vielleicht weil es ähnliche funktionen in C gibt.
    jedenfalls stehen diese headers im C++-Stan

    dart. also halte ich sie für c++.



  • Wikinger75 schrieb:

    Wikinger75 schrieb:
    Und gibt es auch eine c++ wariante von denen

    das sind bereits die c++-varianten.

    Warum heit das dan cstdlib und nicht stdlib?

    C-Header:
    time.h
    stdlib.h
    ...

    Passende C++-header:
    ctime
    cstdlib
    ...



  • unskilled schrieb:

    Bei einer Simulation sollten die Zahlen ja ein wenig zufällig sein aber auf jeden Fall reproduzierbar

    Das erreicht man, indem man seed immer mit dem gleichen Wert am Programmstart initialisiert. Dann hat man fuer gewoehnlich Zufallszahlen und wiederholbare Ergebnisse. Jedenfalls ist das die gaengige Praxis.


Anmelden zum Antworten