Chciałabym uzupełnić doskonałe odpowiedzi Angry Shoe i Peterchena krótkim przeglądem stanu techniki w 2015 roku:
Kilka dobrych wyborów
randutils
randutils
Biblioteki (prezentacja) jest interesującą nowością, oferując prosty interfejs oraz (zadeklarowanej) solidne losowe możliwości. Ma wady polegające na tym, że dodaje zależność od projektu, a ponieważ jest nowy, nie został gruntownie przetestowany. W każdym razie, będąc wolnym (licencja MIT) i tylko nagłówkiem, myślę, że warto spróbować.
Minimalna próbka: rzut kostką
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Nawet jeśli ktoś nie jest zainteresowany biblioteką, strona internetowa ( http://www.pcg-random.org/ ) zawiera wiele interesujących artykułów na temat generowania liczb losowych w ogóle, aw szczególności biblioteki C ++.
Boost.Random
Boost.Random
(dokumentacja) jest biblioteką, która inspirowana C++11
„s <random>
, z którymi akcje znacznie interfejsu. Chociaż teoretycznie jest również zależnością zewnętrzną, Boost
ma obecnie status biblioteki „quasi-standardowej”, a jej Random
moduł można uznać za klasyczny wybór dla dobrej jakości generowania liczb losowych. Ma dwie zalety w stosunku do C++11
rozwiązania:
- jest bardziej przenośny, potrzebuje tylko obsługi kompilatora dla C ++ 03
- jego
random_device
metody zastosowania systemu specyficzne zaoferować posiew dobrej jakości
Jedyną małą wadą jest to, że oferta modułu random_device
nie obejmuje samego nagłówka, należy ją skompilować i połączyć boost_random
.
Minimalna próbka: rzut kostką
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Chociaż minimalna próbka działa dobrze, prawdziwe programy powinny korzystać z kilku ulepszeń:
- make
mt19937
a thread_local
: generator jest dość obszerny (> 2 KB) i lepiej nie umieszczać go na stosie
- ziarno
mt19937
z więcej niż jedną liczbą całkowitą: Mersenne Twister ma duży stan i może skorzystać z większej entropii podczas inicjalizacji
Kilka niezbyt dobrych wyborów
Biblioteka C ++ 11
Będąc najbardziej idiomatycznym rozwiązaniem, <random>
biblioteka nie oferuje zbyt wiele w zamian za złożoność interfejsu nawet dla podstawowych potrzeb. Wada tkwi w std::random_device
tym, że Standard nie narzuca żadnej minimalnej jakości dla swoich wyników (o ile entropy()
zwraca 0
), a od 2015 r. MinGW (nie jest najczęściej używanym kompilatorem, ale raczej nie jest ezoterycznym wyborem) zawsze będzie drukować 4
na minimalnej próbce.
Minimalna próbka: rzut kostką
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
Jeśli implementacja nie jest zepsuta, to rozwiązanie powinno być równoważne z Boost i obowiązują te same sugestie.
Rozwiązanie Godota
Minimalna próbka: rzut kostką
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
To proste, skuteczne i zgrabne rozwiązanie. Tylko wada, kompilacja zajmie trochę czasu - około dwóch lat, pod warunkiem, że C ++ 17 zostanie wydany na czas, a randint
funkcja eksperymentalna zostanie zatwierdzona do nowego standardu. Być może do tego czasu poprawią się również gwarancje jakości siewu.
Minimalna próbka: rzut kostką
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
Stare rozwiązanie C jest uważane za szkodliwe i nie bez powodu (zobacz inne odpowiedzi tutaj lub tę szczegółową analizę ). Mimo to ma swoje zalety: jest prosty, przenośny, szybki i uczciwy, w tym sensie, że wiadomo, że otrzymywane liczby losowe nie są przyzwoite, a zatem nie ma pokusy, aby używać ich do poważnych celów.
Troll księgowy
Minimalna próbka: rzut kostką
#include <iostream>
int main() {
std::cout << 9;
}
Podczas gdy 9 to dość nietypowy wynik jak na zwykły rzut kostką, trzeba podziwiać doskonałe połączenie dobrych cech tego rozwiązania, które jest najszybsze, najprostsze, najbardziej przyjazne dla pamięci podręcznej i najbardziej przenośne. Zamieniając 9 na 4, uzyskuje się doskonały generator dla każdego rodzaju śmierci Dungeons and Dragons, jednocześnie unikając obciążonych symbolami wartości 1, 2 i 3. Jedyną małą wadą jest to, że z powodu złego temperamentu księgowych trolli Dilberta, ten program faktycznie wywołuje niezdefiniowane zachowanie.