srandおよびrand関数を正しく使用していません。乱数ジェネレーターを一度「シード」してから、を使用rand()
してRNGから連続する値を取得することになっています。各シードは、特定のランダム性基準に適合する特定の数列になります。
代わりに、毎回乱数ジェネレーターをシードしてから、乱数シーケンスの最初の値を取得します。は非常に高速に呼び出されるため、同じシードが返されるためtime()
、乱数ジェネレーターを同じシーケンスの先頭に効果的にリセットし、以前と同じ番号を取得します。
によって返される値がtime()
更新されて毎回新しいシードを取得したとしても、適切な乱数が保証されるわけではありません。乱数ジェネレーターは、数列が特定の統計的特性を持つ数列を生成するように設計されています。ただし、同じプロパティが異なるシーケンスから選択された値を保持するという保証はありません。
したがって、決定論的乱数ジェネレーターを使用するには、ジェネレーターを1回だけシードしてから、その1つのシードによって生成された値のシーケンスを消費する必要があります。
別のポイント; 実装に使用される乱数ジェネレーターはrand()
、歴史的にあまり優れてrand()
おらず、再入可能でもスレッドセーフでもありません。また、生成さrand()
れた値を目的の分布の値に変換することは必ずしも簡単ではありません。
C ++では、<random>
はるかに優れた機能を提供するライブラリを選択する必要があります。の使用例を次に示し<random>
ます。
#include <random>
#include <iostream>
int main() {
const int sides = 6;
int groups = 10, dice_per_group = 3;
std::uniform_int_distribution<> distribution(1,sides); // create an object that uses randomness from an external source (provided later) to produces random values in the given (inclusive) range
// create and seed the source of randomness
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 engine(seed);
for (int i=0; i<groups; ++i) {
for (int j=0; j<dice_per_group; ++j) {
// use the distribution with the source of randomness
int r = distribution(engine);
std::cout << "Die #" << j+1 << " rolled a " << r << '\n';
}
std::cout << '\n';
}
}