Im Moment verwende ich den folgenden Code, um eine einheitliche Verteilung von Ganzzahlen mit einem Bereich zu erstellen. (Ich nahm den Seeding-Code heraus)
%Vor%Ich versuche, es zu modifizieren, um eine Verteilung zu geben, die Twords den Min-Wert bevorzugt, und fast nie produziert, nähert sich dem maximalen Wert. Ich kann alle vorgefertigten Distributionen sehen, aber keine davon ist eine Ganzzahl. Und ich kann auch nicht sagen, welcher meiner Bedürfnisse basierend auf irgendeiner der Dokumentation entspricht. Der nächste, den ich gekommen bin, ist die Chi-Quadrat-Verteilung, wie in Wikipedia gezeigt, wo k = 2
Aber ich kann nicht herausfinden, basierend auf der Dokumentation , wie man es benutzt Ganzzahlen, geschweige denn den k-Wert setzen.
Wie kann ich meine Funktion so einrichten, dass sie eine geeignete ungleichmäßige Ganzzahlverteilung verwendet?
arbeitet noch an der Auswahl der richtigen Distribution: Hier sind die Ergebnisse von std::poisson_distribution<int> dist((max - min) * .1);
von 0 bis 20:
noch nicht ganz da, da 0 häufiger als 1 sein sollte, aber es sollte der nächsten Person helfen, wird mehr Ergebnisse veröffentlichen, wie sie kommen.
Nun meine letzte Lösung wurde eine Kombination von Methoden:
%Vor%gibt das Ergebnis von:
Es gibt dort andere Integer-Verteilungen, sie haben nur int
in ihren Namen. Sie haben typedef IntType result_type
in ihren Klassendefinitionen.
Diejenigen, die sich wie beschrieben verhalten, sind:
binomial_distribution
(t, p)
Dadurch werden Zahlen im Bereich 0 ≤ x ≤ t generiert. Daher müssen Sie den Bereich nach min
umwandeln. Der Mittelwert liegt bei t · p , also wählen Sie ein p in der Nähe von 0.
std::binomial_distribution<int> dist(max - min, .1);
return dist(gen) + min;
Dies erzeugt Zahlen 0 ≤ x & lt; ∞, aber große Zahlen sind zunehmend weniger wahrscheinlich. Sie können alles über max
zensieren, um es auf einen Bereich zu beschränken. Der Parameter λ ist der Mittelwert. Wählen Sie es wie im vorherigen Beispiel:
std::poisson_distribution<int> dist((max - min) * .1);
int x;
do
x = dist(gen) + min;
while (x > max);
return x;
erzeugt auch Zahlen 0 ≤ x & lt; ∞, aber 0 ist das wahrscheinlichste Ergebnis und jede nachfolgende Zahl ist weniger wahrscheinlich als die vorherige. Wählen Sie erneut den Parameter aus, der dem Mittelwert des vorherigen Beispiels entspricht:
std::geometric_distribution<int> dist(1 / ((max - min) * .1 + 1));
int x;
do
x = dist(gen) + min;
while (x > max);
return x;
Sie können auch eine der kontinuierlichen Verteilungen verwenden, um eine double
zu generieren und sie dann auf eine int
zu runden.
Zusätzlich zu den in der großen Antwort von @aaz genannten Distributionen sollten Sie daran denken, dass Sie Ihre Uniformverteilung auch in jede Wahrscheinlichkeitsverteilungsfunktion transformieren können, die Sie sich vorstellen können, indem Sie inverses Transformations-Sampling (das ist jedoch tatsächlich nur für einige" nette "Funktionen möglich) oder Zurückweisungssampling (kann in jedem Fall angewendet werden, kann aber rechenintensiv sein).
Mir scheint, dass eine Verteilung, die Ihren Anforderungen entspricht, die (negative) Exponentialverteilung wäre:
Glücklicherweise handelt es sich um eine der Verteilungen, auf die Sie die inverse Transformationsabtastung anwenden können, was bedeutet, dass Sie mit einer Stichprobe aus einer einheitlichen [0, 1] -Distribution eine Exponentialverteilung erhalten, indem Sie die Formel anwenden:
%Vor% mit p
ist ein Zufallswert aus der Gleichverteilung und lambda
ist der Parameter der Exponentialverteilung; Weitere Informationen finden Sie hier .
Sobald du x
(was ein double
ist) bekommst, wirf es einfach auf int
(oder runde es mit einer Funktion wie:
), um Ihr Ergebnis zu erhalten.
Bearbeiten
Übrigens habe ich nicht bemerkt, dass sogar die exponentielle Verteilung bereits in <random>
enthalten ist ( link ) ... naja, noch besser, du musst den Code nicht schreiben, aber ein bisschen Theorie wird nie verloren :)
.
Tags und Links c++ random distribution