zufallszahlen
-
Hi, ich will double Zufallszahlen erstellen. In folgendem beispiel sollen zufallszahlen zwischen 0 und r generiert werden, wobei r ersteinmal ein integer sein soll.
#include <ctime> #include <cstdlib> #include <iostream> using namespace std; int main() { double x; int r; cin >> r; srand(time(0)); x=((rand()%r)+1)*(rand()/RAND_MAX); /* (rand()%r)+1) ist integer streckungsfaktor zwischen 1 und r. Das(rand()/RAND_MAX) soll eine Zahl zwischen 0 und 1 werden. Ich habe das ganze in 2 faktoren aufgeteilt damit ich mehr verschiedene zufalls doubles habe (RAND_MAX für jede einheit). */ cout << x; system("Pause"); return 0; }Das Problem ist dass ich immer x = 0 bekomme wieso?
Eine weitere sache die mir nicht gefällt ist dass RAND_MAX so gering ist mit 7fff (32767).
Wenn ich nun z.b. r = 15000 wähle gibt es 3 möglichkeiten 1 zu bekommen (1%15000, 15001%15000, 30001%15000)
aber z.b. nur 2 möglichkeit für 14999 (14999%15000, 29999%15000), wenn eine zahl deutlich warscheinlicher ist als eine andere ist das nicht mehr zufällig...
-
In deiner Formel kommen nur int-Werte vor, also verwendet der Compiler dort Ganzahl-Arithmetik - und der (Teil)Ausdruck
rand()/RAND_MAXist immer null. Eine Lösung wäre es, einen der Teile in einen double zu casten.Ansonsten ist deine Skalierung nicht nur falsch, sondern auch sinnlos - ich würde den Wert eher per
(rand()*r)/RAND_MAXberechnen (das löst auch das Divisionsproblem).PS: Im Magazin gibt es einen Artikel über Zufallszahlen, der für dich interessant werden könnte

-
Nebenbei hat deine Skalierung den Nachteil, dass Werte nahe r nur sehr selten generiert werden, während sehr kleine Werte wesentlich häufiger sind.
-
ok mal wieder vergessen zu casten, ich glaube das lerne ich nie.
edit- nvm.
-
oh ich sehe nun was ihr meint. ty für die hilfe. werde mal den artikel suchen.
-
Wie otze schon sagte, bekommst du mit deiner Konstruktion keine gleichmäßige Verteilung hin. Und der Trick an der Alternative besteht darin, daß man weiter oben
double r;definieren sollte - dadurch verwendet der Compiler dann Gleitkomma-Arithmetik und du erhältst auch Werte mit Nachkommastellen.
-
Wenn du hochwertige Zufallszahlen brauchst, ist Boost.Random eine gute Wahl. Std::rand() ist üblicherweise nur ein einfacher, linearer Kongruenzgenerator - ausreichend, wenn es im Wesentlichen darum geht, dass der Benutzer sein Ergebnis nicht vorhersehen können soll, aber suboptimal für Simulationen und Ähnliches (deine Bemerkung über nicht mehr echte Zufälligkeit lässt mich etwas in der Richtung vermuten). Geht es gar um Kryptographie, solltest du dich an entsprechende Schnittstellen deines Betriebssystems wenden; unter UNIX /dev/random, unter Windows weiß ich das aus dem Stand nicht.
Allerdings ist mir std::rand() mit 16 Bit effektiver Breite schon länger nicht mehr untergekommen. Welchen Compiler verwendest du?
-
seldon schrieb:
Allerdings ist mir std::rand() mit 16 Bit effektiver Breite schon länger nicht mehr untergekommen. Welchen Compiler verwendest du?
Das hatten wir vor einem Monat schon einmal. Finde leider den konkreten Thread nicht, aber ich hatte damals ebenfalls versäumt, nach dem Compiler/Standardbibliothek zu fragen. Jedenfalls geistert wohl irgendwo da draußen tatsächlich eine Implementierung mit einem 16-Bit rand() herum und diese Implementierung ist verbreitet genug, um schon mehrmals hier im Forum aufzutauchen.
Wobei es natürlich im Prinzip total egal ist, wieviele zufällige Bits ein RNG pro Ziehung liefert. Hauptsache sie sind gut zufällig und die Rate von zufälligen Bits pro Zeit ist akzeptabel.
-
Halozination schrieb:
...
wenn eine zahl deutlich warscheinlicher ist als eine andere ist das nicht mehr zufällig...Zum einen sind die erzeugten Zahlen nie zufällig, dass basiert immer auf festen Berechnungsalgorithmen.
Und des weiteren sind Zufallszahlen, wo manche Zahlen öfters vorkommen als andere trotzdem zufällig, nur die Verteilung ist anders.
z.B. Betrachte mal einen Zufallsversuchs, etwa das Werfen eines idealen Würfels. Dann tritt jede Zahl 1 bis 6 gleich häufig auf. Ändert man nun aber die Spielregeln und nimmt 2 Würfel und addiert die Augenzahlen, so erhält man auf einmal, dass ein Ergebnis um die 7 wahrscheinlicher ist, als etwa die 12. (Es gibt nur eine Möglichkeit die 12 zu erhalten, nämlich als 6+6, für die 7 gibt es aber 6 Möglichkeiten: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1)
Trotzdem ist das Ergebnis zufällig, nur ist eben die Verteilung anders.
-
MinGW hat beispielsweise so ein 16-Bit rand().