zufalls integer
-
hi, für eine monte carlo simulation brauche ich 100%ige zufalls integer von min_i bis max_i z.b. 1 bis 10. ich dachte eigentl. dass ich meine zufalls zahlen richtig generiere aber bin mir nicht mehr sicher. (aufgrund von simulations ergebnissen) kann jemand bitte kurz drüber schauen?
editierte (hoffentl.) korrigierte version
#include <ctime> #include <cstdlib> class randint { private: int min, max; int randomnumber; public: randint(int min_i, int max_i) { min = min_i; max = max_i; srand((unsigned) time(NULL)); } int getrand() { int nrofrandomnumbers, b; nrofrandomnumbers = max-min+1; b = (RAND_MAX+1)%nrofrandomnumbers; do { randomnumber = rand(); } while (randomnumber > RAND_MAX-b); return min+randomnumber%(max-min+1); } };
-
rand() ist ein Pseudozufallsgenerator. Echte Zufallszahlen bekommst Du damit nicht.
-
Es gibt kein 100% Zufall. In dem Fall müttest du z.B. eine Webcam nehmen und das dort zu erkenndene Rauschen nehmen. Das wäre eine recht günstige Lösung.
-
Das könnte dir helfen: http://www.random.org/
-
Während rand() für professionelles MC nicht gut genug ist, brauchst du doch keinen teuren echten Zufallsgenerator. Es gibt viele Numerikbibliotheken die sehr gute, sehr schnelle Pseudozufallsgeneratoren für wissenschaftliche Zwecke implementieren. Und auch in dem Numerikbuch deiner Wahl findest du Hinweise.
-
mir ist schon klar dass die zufalls zahlen die so generiert werden eigentl. nur zahlen einer folge sind die irgend einem algorithmus folgen. aber das stört mich nicht solange die warscheinlichkeit von allen zahlen exakt gleich ist und solange es kein muster oder tendenz zu einem muster gibt; auch nach sehr vielen generationen nicht.
SeppJ, willst du damit sagen rand(); ist nicht ausreichend?
-
Hier reicht rand() locker.
-
Halozination schrieb:
SeppJ, willst du damit sagen rand(); ist nicht ausreichend?
Das kommt halt da drauf an, was man machen will. rand() hat Muster und Tendenzen zu Mustern, schon nach wenigen Generationen. Wenn deine Simulationsergebnisse deutlich falsch sind, ist der Fehler aber sehr wahrscheinlich ein anderer.
-
srand((unsigned) time(NULL)); gehört eigentlich an den Anfang der main().
So in dem Konstruktor würde ich Angst haben, daß das mehrmals im Programmlauf passieren kann.
-
Man munkelt,
std::random_devicesoll echten Zufall liefern
-
Nexus schrieb:
Man munkelt,
std::random_devicesoll echten Zufall liefern
Ist das eigentlich portabel?
Gut für Kryptographie, aber für Simulationen Overkill und (vermutlich, nicht getestet) viel zu langsam.
-
Also an dem Code sind sicherlich ein paar Sachen - neben stilistischen - kaputt.
Schauen wir uns einfach mal Extremfälle an:max=RAND_MAX
min=0dann ist
nrofrandomnumbers = max-min+1=RAND_MAX+1; b = RAND_MAX%nrofrandomnumbers =RAND_MAX %(RAND_MAX+1) = RAND_MAX; ... if (randomnumber < 0) break;ich würde also vermuten, dass "nrofrandomnumbers = max-min;" sein sollte, probieren wir das mal:
nrofrandomnumbers = RAND_MAX; b = 0 if (randomnumber < RAND_MAX) break;Ohh, immer noch nicht ganz richtig. So wird nie randomnumber=max=RAND_MAX gezogen.
if (randomnumber <= RAND_MAX) break;Korrigiert.
-
Ich hab mit den Generatoren von boost relativ gute Erfahrungen gemacht.
http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html
Der mt19937 liefert ganz gute Zahlen.
-
Scorcher24 schrieb:
Ich hab mit den Generatoren von boost relativ gute Erfahrungen gemacht.
http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html
Der mt19937 liefert ganz gute Zahlen.Hast Du selber bemerkt, daß rand() schlechte Zahlen liefert?
Meistens hat man um Größenordnungen stärkere Fehler einprogrammiert.
Man könnte rand() vorwerfen, eine kurze Periode zu haben. Jo, dann läuft der Simulator halt ein paarmal rum, jeweils leicht versetzt und er denkt, es wäre jedesmal neu. Und am Ende ist es trotzdem hübsch gleichverteilt.
-
volkard schrieb:
Hast Du selber bemerkt, daß rand() schlechte Zahlen liefert?
Wenn das DIng als LCG implementiert ist, dann ist es zum Beispiel eine schlechte Idee, mehrdimensionale Normalverteilungen mit ihnen zu ziehen.
//edit hier ein Link zu einem paper, keine Ahnung ob du Zugriff drauf kriegst. aber der Abstract sagt schon eine Menge:
-
volkard schrieb:
Scorcher24 schrieb:
Ich hab mit den Generatoren von boost relativ gute Erfahrungen gemacht.
http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html
Der mt19937 liefert ganz gute Zahlen.Hast Du selber bemerkt, daß rand() schlechte Zahlen liefert?
Ja.
Ich habe im Zuge meiner 2D Engine per Zufall Sprites auf dem Bildschirm verteilt für ein Testprogramm. Und die Anordnung war nicht wirklich zufriedenstellend und nicht gleichmäßig. Meistens waren "Löcher" in der Anordnung. Sprich, es waren als bsp links und rechts sprites, aber in der mitte kaum welche. Sowas. Mit dem Mersenne Twiser von boost ist das nicht so. Da ist die Anordnung der Sprites viel gleichmäßiger über den Bildschirm.Das sind meine Funktionen:
typedef boost::mt19937 TRandomGenerator; typedef boost::uniform_int<> TRandomIntUniform; typedef boost::uniform_real<> TRandomFloatUniform; typedef boost::variate_generator<TRandomGenerator&, TRandomIntUniform > TIntVariateGen; typedef boost::variate_generator<TRandomGenerator&, TRandomFloatUniform > TFloatVariateGen; int NLSystemController::getRandomInt( int min, int max ) { TRandomIntUniform distance(min, max); TIntVariateGen dice(m_rand, distance); return dice(); } int NLSystemController::getRandomInt() { TRandomIntUniform distance; TIntVariateGen dice(m_rand, distance); return dice(); } f32 NLSystemController::getRandomReal( double min, double max ) { TRandomFloatUniform distance(min, max); TFloatVariateGen dice(m_rand, distance); return static_cast<f32>(dice()); } f32 NLSystemController::getRandomReal() { TRandomFloatUniform distance; TFloatVariateGen dice(m_rand, distance); return static_cast<f32>(dice()); }
-
Scorcher24 schrieb:
Meistens waren "Löcher" in der Anordnung. Sprich, es waren als bsp links und rechts sprites, aber in der mitte kaum welche. Sowas.
Da wähne ich andere Fehler. Ein schlechter LCG zeichnet sich eher durch übertriebene Gleichmäßigkeit aus.
-
Gibt es eigentlich einen Grund, wieso in diesem Forum im Gegensatz zu vielen anderen C++ Neuheiten
<random>so selten bis nie empfohlen wird? Normalerweise sind alle (die meisten) doch recht scharf drauf Dinge aus <c....> durch ein modernes C++ Pendant zu ersetzen und<random>ist schon recht lange in vc und gcc implementiert (wenn auch nicht 100% fehlerfrei) und in boost gibt es das eh schon lang.
Wieso "reicht" für euch immer ein rand() mit seinem globalen Zustand (das auch ständig falsch benutzt wird) und andere C Techniken sind pöse. Und ich rede jetzt hier nicht von der Qualität der Zahlen.
So und zur Frage:#include <random> // entweder #include <boost/random.hpp> // oder namespace Rand = boost; typedef Rand::uniform_int<int> Distribution; typedef Rand::mt19937 Engine; // oder eine andere typedef Rand::variate_generator<Engine, Distribution> Generator; Generator random(Engine(seed), Distribution(1, 10)); std::vector<int> v; std::generate_n(v.begin(), 10, std::ref(random));Ich habe auch verschiedene Monte Carlo Projekte und arbeite mit boost random (das tr1 random hatte im gcc in der normal_distribution oder irgendwo einen kleinen fehler; wahrscheinlich ist das auch gar nicht mehr so). Besonders wenn es komplexer wird und man das ganze dann auch noch parallelisiert möchte ich da nicht mit rand(...) rumhampeln.
-
Letztes Mal, als ich TR1.Random benutzt habe, war die Implementierung auf g++ verbuggt. Okay, gerade nachgeschaut, immer noch, obwohl der Bug bereits vor 2 Jahren bekannt war.
#ifdef _MSC_VER #include <random> #else #include <tr1/random> #endif #include <iostream> int main() { std::tr1::mt19937 engine; std::tr1::uniform_real<float> distribution(3.f, 4.f); std::cout << distribution(engine) << std::endl; }MSVC++
3.81472g++ 4.5.2 (MinGW)
3.49921e+009Und
std::uniform_realgibts bei g++ noch nicht, erststd::tr1::uniform_real. Für was Zuverlässiges und Portables würde ich also Boost.Random benutzen.
-
brotbernd schrieb:
Und ich rede jetzt hier nicht von der Qualität der Zahlen.
Ich rede nur von der Qualität der Zahlen. Wie so oft wurde rand() wieder abgelehnt nur wegen der Qualität der Zahlen. Und hier bin ich eher des Skeptiker. Mir scheint, man erzählt sich immer wieder gegenseitig etwas und sowas wie eine kleine Religion entsteht um den Mersenne Twister. Daß der globale Zustand pöse ist, da sind wir einer Meinung.