Ce face std::discrete_distribution
std::discrete_distribution primește o listă de ponderi și returnează indicele i cu probabilitatea pondere[i] / suma ponderilor. Ponderile nu trebuie să adune 1: {50, 30, 20} înseamnă 50%, 30% și 20%.
Este potrivit pentru extrageri ponderate: premii cu șanse diferite, alegerea unui răspuns după popularitate, evenimente din jocuri. Metoda probabilities() returnează probabilitățile normalizate.
Parametri
| Parametru | Descriere |
|---|---|
p0, p1, ... |
Ponderile (nenegative), una pentru fiecare index. |
generator |
La apel: un generator. |
Ce returnează
La fiecare apel, un index între 0 și numărul de ponderi minus 1.
Exemple
Exemplul 1: Roata norocului
Din 10000 de învârtiri, fiecare premiu iese aproximativ proporțional cu ponderea lui. Generatorul std::mt19937 cu seed fix produce aceleași numere pe orice compilator, dar modul în care o distribuție le transformă nu este fixat de standard. Rezultatul de mai jos este cel dat de libc++ (Clang); cu GCC sau MSVC, același seed poate da alte valori.
#include <array>
#include <print>
#include <random>
#include <string>
int main() {
std::array<std::string, 3> premii{"Pix", "Tricou", "Telefon"};
std::discrete_distribution<int> roata{80, 19, 1};
std::mt19937 gen(3);
std::array<int, 3> castigate{};
for (int i = 0; i < 10000; ++i) {
++castigate[roata(gen)];
}
for (int i = 0; i < 3; ++i) {
std::println("{:<8} {:>5}", premii[i], castigate[i]);
}
}
Rezultat
Pix 7930
Tricou 1990
Telefon 80
Exemplul 2: Probabilitățile normalizate
Această parte nu depinde de generator, deci este aceeași pe orice compilator.
#include <print>
#include <random>
int main() {
std::discrete_distribution<int> d{2, 1, 1};
for (double p : d.probabilities()) {
std::print("{:.2f} ", p);
}
std::println("");
}
Rezultat
0.50 0.25 0.25
Greșeli frecvente
- Dai ponderi negative: comportament nedefinit.
- Uiți că rezultatul este un index, nu valoarea: folosește-l ca poziție în vectorul cu opțiuni.
Comenzi înrudite
std::uniform_int_distribution: Transformă numerele unui generator în întregi aleatorii dintr-un interval [a, b], toate cu aceeași probabilitate.std::bernoulli_distribution: Produce true cu probabilitatea p și false în rest: un „da sau nu” aleatoriu, ca o monedă (eventual măsluită).std::sample: Alege aleatoriu n elemente distincte dintr-un interval și le copiază la destinație.