C++ Laplace Zufallszahlen

feuerfuchs

Lt. Commander
Registriert
Dez. 2007
Beiträge
1.100
Hi,
Ich habe schon viel gegoogelt nach Zufallszahlengeneratoren, ich war mir aber nicht sicher ob alle Zahlen gleichwahrscheinlich sind.
Jedenfalls möchte ich in einem bestimmten Bereich Zufallszahlen generieren, von 1-38. Alle Ereignisse sollen gleichwahrscheinlich sein, also soll die Wahrscheinlichkeit für jede Zahl soll 1/38 sein.

Kennt jemand eine gute Funktion oder Headerdatei die das Problem löst?
 
Moin,

du könntest natürlich verschachtelte Schleifen erstellen und mit srand() jeweils die Zahlen berechnen.
Die Frage ist nur ob sich ein derartiger Aufwand lohnt.

MfG

badday
 
Hallo,

was ist eine Laplace Zufallszahl? Ich kenne nur eine Laplace-Verteilung oder ein Laplace-Experiment. Bei einem Laplace-Experiment gibt es endlich viele Elementarereignisse (z.B. Kopf,Zahl beim Münzwurf) die alle mit der gleichen Wahrscheinlichkeit (hier 0.5) auftreten.
Ich schätz mal, dass du diese gleiche Wahrscheinlichkeit meinst, die zugrunde liegende Verteilung wäre dann eine Gleichverteilung, und die dazugehörige Funktion rand().
Mit srand(int seed) wird der (Pseudo-)Zufallsgenerator initialisiert.

P.S.
Eine Münze ist ein dreiseitiger Würfel (Kopf,Zahl,Kante) aber kein Laplace-Würfel mehr, da das Ereignis "Kante" viel unwahrscheinlicher ist, als das Ereignis "Kopf" oder "Zahl"
 
@Blitzmerker:
Die Geschichte mit modulo 38 ist eine sehr schlechte Idee.

Selbst wenn die Zahlen vorher gleichmäßig verteilt waren, sind sie es hinterher nicht mehr.

Angenommen, ein Generator generiert eine absolut zufällige und perfekt gleichverteilte Folge der Zahlen von 1 bis 4.

Nun schauen wir mal darauf, was rauskommt, wenn wir jede Zahl modulo 3 nehmen:
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1

Merkst du was? :)

feuerfuchs:
Die Qualität der Pseudozufallszahlen aus rand() ist miserabel, zumindest aus kryptographischer Sicht. Je nachdem wofür du die Zahlen brauchst, ist rand mehr oder weniger gut für dich geeignet. Wenn du dazu mehr wissen willst, brauchen wir Infos was du genau mit diesen Zahlen vor hast.

Auf c-plusplus.de gibt es einen schönen Artikel von Markus Bäckmann dazu. Für dich interessant ist wohl insbesondere der Teil "Verteilungsgerechtigkeit ".
http://magazin.c-plusplus.de/artike...%20um%20rand%2C%20Random%20und%20den%20Zufall
In der Literaturempfehlung wird das Ebook "Numerical Recipes in C" verlinkt, in dem du bessere Algorithmen als rand() für Pseudozufallsgeneratoren findest. Trotzdem bleibt auch bei "besseren" Algorithmen immer das Problem der Verteilungsgerechtigkeit, deshalb empfiehlt es sich, den ganzen Artikel zu lesen. Der ist übrigens sehr gut. :)
 
Zuletzt bearbeitet:
Na ja, das ist logisch, aber wenn du aus der Zahlenreihe 0 bis 2^32 modulo 3 machst, dann ist die Verteilung sehr gleichmäßig. Natürlich nicht optimal gleichmäßig, aber auf 10 Stellen hinter dem Komma.

Und rand ist klar sehr schlecht, aber wenn die Zeit klein genug gewählt wird, also z.B Millisekunden, dann wird er wieder hinreichend zufällig. Man könnte natürlich radn oder srand einfach weglassen und nur aus der Zeit das Modulo machen.
 
Deshalb hängt es ja auch stark von feuerfuchs ab, welche Qualität er von den Zahlen erwartet, da er immerhin die Gleichverteilung betont. Selbst wenn es mit rand und modulo ausreicht, kann man aus dem verlinkten Artikel noch ein paar nette Sachen lernen.
 
@BerniG:
Deine Variante hat ebenfalls zur Folge, dass keine Gleichverteilung mehr vorhanden ist (um genau zu sein für den Fall, dass die Anzahl der zu generierenden Zufallszahlen kein echter Teiler von RAND_MAX+1 ist - sonst klappt es).
Angenommen RAND_MAX ist 2 (rand() liefert also PRN zwischen 0 und 2), wir wollen Zahlen zwischen 1 und 2 haben.

Nach deiner Formel oben (1 + (int) (2. * (rand() / (2 + 1.))))
rand() = 0 -> 1.0 -> 1
rand() = 1 -> 1.6666... -> 1
rand() = 2 -> 2.3333... -> 2

1 würde dann doppelt so häufig wie 2 vorkommen.

In dem Artikel, den ich zwei Beiträge weiter oben verlinkt habe, wird eine Lösung vorgestellt, die die Gleichverteilung erhält (in dem Abschnitt "Mehr Gerechtigkeit").
 
Zuletzt bearbeitet:
Zurück
Oben