Random

Thomasio

Erfahrenes Mitglied
Ich habe eine Anwendung, die in zig verschiedenen Funktionen Zufallszahlen braucht, wobei mir die Funktion rand() einfach nicht reicht, schon deshalb, weil sie kleinere Zahlen bevorzugt.
Dazu kommt, dass ich die Initialisierung nach Möglichkeit nur einmal machen will, und nicht jedesmal bevor ich eine Zufallszahl generieren will, weil ich sonst bei 2 zeitgleichen Aufrufen 2 mal das gleiche Ergebnis bekomme, sofern ich die Uhrzeit zur Initialisierung verwende.

Ich bruche also eine Funktion, die bei Programmstart initialisiert wird und mir bei Aufruf eine Zufallszahl zurück gibt.

Gibt es irgendwo eine Library oder fertige Funktion, die das besser kann als rand()?
Google spuckt zum Thema "C++ random" nur zig1000 Treffer zu rand() und srand() aus.
 
Ich habe eine Anwendung, die in zig verschiedenen Funktionen Zufallszahlen braucht, wobei mir die Funktion rand() einfach nicht reicht, schon deshalb, weil sie kleinere Zahlen bevorzugt.
Was soll das heißen? Die rand() Funktion liefert gleichverteilte Zufallszahlen im Bereich 0 bis RAND_MAX. Vermutlich wendest du die Funktion nicht richtig an.
Dazu kommt, dass ich die Initialisierung nach Möglichkeit nur einmal machen will, und nicht jedesmal bevor ich eine Zufallszahl generieren will, weil ich sonst bei 2 zeitgleichen Aufrufen 2 mal das gleiche Ergebnis bekomme, sofern ich die Uhrzeit zur Initialisierung verwende.
Es macht keinen Sinn in einem Programm den Zufallszahlengenerator mehrfach zu initialisieren. Man sollte nur einmal im Programm srand(time(NULL)) aufrufen.
Ich bruche also eine Funktion, die bei Programmstart initialisiert wird und mir bei Aufruf eine Zufallszahl zurück gibt.
Siehe man rand
Gibt es irgendwo eine Library oder fertige Funktion, die das besser kann als rand()?
Sicher gibt es noch andere Bibliotheken. Boost Random zum Beispiel. Da gibt es auch noch andere Verteilungen die man verwenden kann.

Gruß
 
Bei C++ kannst de meist einfach auf boost.org zurück greifen. In dem Fall auch. Und sonst hier von wegen ehm nur einmal initialisieren ...
C++:
#include <ctime>
#include <cstdlib>

const int irand(const int min, const int max)
{
    static bool initialised(false);
    if (initialisied == false) { std::srand(static_cast<unsigned>(std::time(NULL))); initialised = true; }
    return min + static_cast<const int>((max - min + 1.0)* std::rand() / (RAND_MAX+1.0));
}
so ;)
 
Zuletzt bearbeitet:
Dass rand() kleinere Zahlen bevorzugt habe ich mir nicht ausgedacht, das habe ich in der Dokumentation auf cplusplus.com gefunden, zusammen mit dem Hinweis, dass man für anspruchsvolle Aufgaben etwas besseres verwenden sollte, nur leider stand nicht dabei, was denn besser wäre.

Ich kenne durchaus ein paar Random Generatoren, z.B. den Mersenne Twister, aber die haben durch die Bank alle das gleiche Problem, sie sind nicht thread safe, sprich man muss in multi thread Anwendungen den Generator für jeden Thread einzeln initialisieren, was wiederum bedeutet, wenn 2 threads gleichzeitig gestartet werden, produzieren sie auch die gleichen Zahlen.
Das hat mit Zufall eher wenig zu tun.
 
Dass rand() kleinere Zahlen bevorzugt habe ich mir nicht ausgedacht, das habe ich in der Dokumentation auf cplusplus.com gefunden
Das hast du falsch verstanden.
http://www.cplusplus.com/reference/clibrary/cstdlib/rand.html hat gesagt.:
( value % 100 ) is in the range 0 to 99
( value % 100 + 1 ) is in the range 1 to 100
( value % 30 + 1985 ) is in the range 1985 to 2014

Notice though that this modulo operation does not generate a truly uniformly distributed random number in the span (since in most cases lower numbers are slightly more likely), but it is generally a good approximation for short spans.
Da steht, das man beachten sollte, dass die Modulo Operation keine wirklichen gleichverteilten Zufallszahlen generiert.

Gruß
 
Uuuuughhh,ich glaube ich stehe gerade völlig im Wald.
Was denn nun?
Wieso steht da dieser Hinweis auf die Modulo Operation, oder sollte ich erstmal fragen, was ist die Modulo Operation überhaupt?
Wenn ich ein Würfelspiel machen will, darf es einfach nicht passieren, dass mehr 1er als 6er vorkommen, und wenn das ein Multiplayer Spiel werden soll, wo jeder Spieler am Server im eigenen thread läuft darf es auch nicht passieren, dass 2 Spieler die gleiche Zahlenfolge würfeln.
 
Uuuuughhh,ich glaube ich stehe gerade völlig im Wald.
Was denn nun?
Wieso steht da dieser Hinweis auf die Modulo Operation, oder sollte ich erstmal fragen, was ist die Modulo Operation überhaupt?
Die Modulo Operation berechnet den Rest bei einer Ganzzahldivision.
Wenn ich ein Würfelspiel machen will, darf es einfach nicht passieren, dass mehr 1er als 6er vorkommen, und wenn das ein Multiplayer Spiel werden soll, wo jeder Spieler am Server im eigenen thread läuft darf es auch nicht passieren, dass 2 Spieler die gleiche Zahlenfolge würfeln.
Ja, dann darfst du nicht die Modulo Operation auf diese Weise verwenden um eine Abbildung des Intervalls [0, RAND_MAX] auf [1, 6] zu beschreiben.

Du mußt es so machen wie DevDevil. Ein genauere Erklärung steht in dem Link den ich schon gepostet hatte (oder in einem Thema was wir schonmal hatten "bessere Zufallszahlen" o.ä.)
Numerical Recipes in C hat gesagt.:
If you want to generate a random integer between 1 and 10, you should always do it by using high-order bits, as in

j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

and never by anything resembling

j = 1 + (rand() % 10);

(which uses lower-order bits).
Gruß
 
Erstmal danke an euch, zumindest habe ich jetzt ein bischen was zum tüfteln.
Ich lasse das Thema mal noch offen, falls noch jemand etwas Nützliches hinzufügen kann.
Ansonsten bin ich mir ziemlich sicher, dass ich es nicht so einfach auf die Reihe bringen werde.

Ich melde mich dann wieder, entweder mit fertigem Code oder neuen Fragen.
 
Ein bischen getestet und schon gehts nicht.

Code:
const int irand()
{
    static bool initialised(false);
    if (initialisied == false)
    {
        std::srand(static_cast<unsigned>(std::time(NULL)));
        initialised = true;
    }
   return static_cast<const int>(7 * std::rand() / (RAND_MAX+1.0));
}

Problem: multi thread
Nur der erste thread der auf die irand Funktion zugreift bekommt random Werte.
Ab dem zweiten thread erzeugt er identische Zahlenfolgen, offensichtlich weil die Initialisierung nicht thread übergreifend funktioniert, sprich ab dem zweiten thread rand() automatisch mit 1 initialisiert wird.
Ich müsste also die Initialisierung in jedem thread neu machen, was aber wieder bedeutet, werden 2 threads gleichzeitig gestartet, habe ich auch wieder identische Zahlenfolgen.
 
Hi,
und wie sollen zwei Threads zeitgleich gestartet werden? Selbst wenn du einen Multicore-Prozessor hast, können sie nur nacheinander gestartet werden (danach aber sehr wohl zeitgleich auf verschiedenen Kernen ausgeführt werden).

Mfg

langer
 
Zurück