Saya ingin melengkapi jawaban Angry Shoe dan peterchen yang sangat baik dengan gambaran singkat tentang keadaan seni pada tahun 2015:
Beberapa pilihan bagus
randutils
The randutils
library (presentasi) merupakan hal baru yang menarik, menawarkan antarmuka yang sederhana dan (dinyatakan) yang kuat kemampuan random. Ini memiliki kelemahan yang menambah ketergantungan pada proyek Anda dan, karena masih baru, itu belum diuji secara ekstensif. Bagaimanapun, karena gratis (lisensi MIT) dan hanya header, saya pikir itu patut dicoba.
Sampel minimal: die roll
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
Bahkan jika seseorang tidak tertarik dengan perpustakaan, situs web ( http://www.pcg-random.org/ ) menyediakan banyak artikel menarik tentang tema pembuatan bilangan acak secara umum dan perpustakaan C ++ pada khususnya.
Boost.Random
Boost.Random
(dokumentasi) adalah perpustakaan yang terinspirasi C++11
's <random>
, dengan siapa saham banyak antarmuka. Sementara secara teoritis juga menjadi ketergantungan eksternal, Boost
sekarang memiliki status perpustakaan "kuasi-standar", dan Random
modulnya dapat dianggap sebagai pilihan klasik untuk pembuatan bilangan acak berkualitas baik. Ini menampilkan dua keuntungan sehubungan dengan C++11
solusi:
- ini lebih portabel, hanya membutuhkan dukungan kompiler untuk C ++ 03
- nya
random_device
metode penggunaan sistem yang tawaran pembenihan berkualitas baik
Satu-satunya kelemahan kecil adalah bahwa penawaran modul random_device
tidak hanya untuk header, seseorang harus mengkompilasi dan menautkan boost_random
.
Sampel minimal: die roll
#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';
}
Sementara sampel minimal bekerja dengan baik, program nyata harus menggunakan sepasang perbaikan:
- membuat
mt19937
sebuah thread_local
: generator cukup gemuk (> 2 KB) dan lebih baik tidak dialokasikan pada stack
- benih
mt19937
dengan lebih dari satu bilangan bulat: Mersenne Twister memiliki status yang besar dan dapat memanfaatkan lebih banyak entropi selama inisialisasi
Beberapa pilihan yang tidak terlalu bagus
Pustaka C ++ 11
Meskipun menjadi solusi yang paling idiomatis, <random>
perpustakaan tidak menawarkan banyak imbalan atas kompleksitas antarmukanya bahkan untuk kebutuhan dasar. Kekurangannya adalah std::random_device
: Standar tidak mengamanatkan kualitas minimal apa pun untuk keluarannya (selama entropy()
pengembalian 0
) dan, mulai 2015, MinGW (bukan kompiler yang paling sering digunakan, tetapi bukan pilihan esoteris) akan selalu mencetak 4
pada sampel minimal.
Sampel minimal: die roll
#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';
}
Jika implementasinya tidak busuk, solusi ini harus setara dengan Boost, dan saran yang sama berlaku.
Solusi Godot
Sampel minimal: die roll
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
Ini adalah solusi yang sederhana, efektif dan rapi. Hanya cacat, perlu beberapa saat untuk mengkompilasi - sekitar dua tahun, asalkan C ++ 17 dirilis tepat waktu dan randint
fungsi eksperimental disetujui ke dalam Standar baru. Mungkin pada saat itu juga jaminan kualitas pembenihan akan meningkat.
Sampel minimal: die roll
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
Solusi C lama dianggap berbahaya, dan untuk alasan yang baik (lihat jawaban lain di sini atau analisis terperinci ini ). Namun, ia memiliki kelebihan: sederhana, portabel, cepat dan jujur, dalam arti diketahui bahwa nomor acak yang didapat hampir tidak layak, dan oleh karena itu orang tidak tergoda untuk menggunakannya untuk tujuan yang serius.
Solusi troll akuntansi
Sampel minimal: die roll
#include <iostream>
int main() {
std::cout << 9;
}
Sementara 9 adalah hasil yang agak tidak biasa untuk die roll biasa, seseorang harus mengagumi kombinasi kualitas yang sangat baik dalam solusi ini, yang berhasil menjadi yang tercepat, paling sederhana, paling ramah-cache dan paling portabel. Dengan mengganti 9 dengan 4 seseorang mendapatkan generator yang sempurna untuk semua jenis Dungeons and Dragons yang mati, sambil tetap menghindari nilai sarat simbol 1, 2 dan 3. Satu-satunya kekurangan kecil adalah, karena temperamen buruk troll akuntansi Dilbert, program ini sebenarnya menimbulkan perilaku yang tidak terdefinisi.