Angry Shoeとpeterchenの優れた答えを、2015年の最新技術の概要で補足したいと思います。
いくつかの良い選択肢
randutils
randutils
ライブラリー(プレゼンテーション)は、シンプルなインターフェイスと(宣言)堅牢なランダム機能を提供、面白いノベルティです。それはあなたのプロジェクトへの依存を追加するという不利な点を持っています、そして、新しいので、それは広範囲にテストされていません。とにかく、無料(MITライセンス)でヘッダーのみなので、試してみる価値はあると思います。
最小限のサンプル:サイコロ
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
ライブラリに興味がない場合でも、ウェブサイト(http://www.pcg-random.org/)には、一般的な乱数生成のテーマ、特にC ++ライブラリに関する興味深い記事が多数掲載されています。
Boost.Random
Boost.Random
(ドキュメント)インスピレーションを得たライブラリであるC++11
のを<random>
インタフェースの多くを共有して誰と、。理論的には外部依存関係でもBoost
ありますが、「準標準」ライブラリのステータスになりました。そのRandom
モジュールは、良質な乱数生成の古典的な選択肢と見なすことができます。C++11
ソリューションに関して2つの利点があります。
- 移植性が高く、C ++ 03のコンパイラサポートが必要なだけ
- その
random_device
優れた品質の播種提供するために使用するシステム固有の方法
唯一の小さな欠点は、提供されるモジュールrandom_device
がヘッダーのみではなく、コンパイルしてリンクする必要があることboost_random
です。
最小限のサンプル:サイコロ
#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';
}
最小限のサンプルはうまく機能しますが、実際のプログラムは2つの改善点を使用する必要があります。
- make
mt19937
a thread_local
:ジェネレータはかなりふくよか(> 2 KB)で、スタックに割り当てない方がよい
mt19937
複数の整数のシード:Mersenne Twisterは大きな状態にあり、初期化中により多くのエントロピーを利用できます
あまり良くない選択
C ++ 11ライブラリ
最も慣用的なソリューションである<random>
ライブラリは、基本的なニーズであっても、そのインターフェースの複雑さと引き換えに多くを提供しません。欠点はstd::random_device
次のとおりです。Standardは、(entropy()
returnsである限り0
)出力の最低限の品質を義務付けていません。2015年の時点では、MinGW(最も使用頻度の高いコンパイラではありませんが、難解な選択ではありません)は常に4
最小限のサンプルで印刷します。
最小限のサンプル:サイコロ
#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';
}
実装が腐っていない場合、このソリューションはBoostのソリューションと同等であり、同じ提案が適用されます。
Godotのソリューション
最小限のサンプル:サイコロ
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
これはシンプルで効果的かつきちんとしたソリューションです。C ++ 17が予定どおりにリリースされ、実験的randint
機能が新しい標準に承認された場合、コンパイルに時間がかかるため、問題が発生します。約2年かかります。おそらくその頃には、播種品質の保証も向上するでしょう。
最小限のサンプル:サイコロ
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
古いCのソリューションは有害であると考えられており、それには十分な理由があります(ここでの他の回答またはこの詳細な分析を参照してください)。それでも、それには利点があります:シンプルで、移植性があり、高速で正直です。ある意味で、得られる乱数はまともなものではないことがわかっているため、深刻な目的でそれらを使用したくありません。
会計トロールソリューション
最小限のサンプル:サイコロ
#include <iostream>
int main() {
std::cout << 9; // http://dilbert.com/strip/2001-10-25
}
9は通常のダイスロールではやや珍しい結果ですが、このソリューションでは優れた品質の優れた組み合わせを賞賛する必要があります。9を4に置き換えることで、シンボルが豊富な値1、2、3を回避しながら、あらゆる種類のダンジョンとドラゴンズダイスに最適なジェネレーターを手に入れます。唯一の小さな欠点は、ディルバートの会計トロールの気性が悪いためこのプログラムは実際には未定義の動作を引き起こします。