私の目標は、ランダムな値を持つベクトルのベクトルの各ベクトルの各要素を満たすことです。次のコードを検討してください:イテレータを使用するときにランダムジェネレータを再配置する必要があるのはなぜですか?
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
typedef std::vector<int> IntVect;
typedef std::vector<IntVect> Grid;
void fillRandom(Grid& grid, int lo, int hi);
int main(int argc, const char * argv[]) {
Grid grid { Grid(5, IntVect (5)) };
fillRandom(grid, 0, 10);
for (auto& row : grid) {
for (auto& i : row) {
std::cout << i << " ";
}
std::cout << "\n";
}
return 0;
}
// fillRandom v1
void fillRandom(Grid& grid, int lo, int hi) {
// Init Random engine
std::random_device rnd_device;
std::mt19937 generator { rnd_device() };
std::uniform_int_distribution<int> distr(lo, hi);
auto dice = std::bind(distr, generator);
Grid::iterator i { grid.begin() };
for (; i != grid.end(); ++i) {
std::generate(i->begin(), i->end(), dice);
generator.seed(rnd_device()); // reseed
dice = std::bind(distr, generator);
}
return;
}
fillRandom
で、私はgrid
の各要素のための発電機を再シードする必要があります。
7 5 8 1 9
7 5 8 1 9
7 5 8 1 9
7 5 8 1 9
7 5 8 1 9
:それ以外の場合、出力は次のように、grid
の各要素について同じになります。私はfillRandom
を変更する場合は、:
// fillRandom v2
void fillRandom(Grid& grid, int lo, int hi) {
// Init Random engine as above
for (auto& row : grid)
for (auto& i : row)
i = dice();
return;
}
私はgrid
の各vector
のための発電機を再シードせずに期待される結果を取得します。
fillRandom
dice()
の第2のバージョンでは、各ベクトルの各要素が呼び出され、結果としてgrid
がランダムな値で埋められます。しかし、最初のバージョンはまったく同じことを行う必要があります。しかし明らかにそうではありません。ここでの違いは何ですか?
は、なぜ私はstd::generate
とイテレータを使用する場合、すべてのベクトルのための乱数発生器を再シードする必要がありますか?この行動を理解するのを助けてください。
これはラムダの代わりに動作し、より簡潔です: 'auto dice = std :: bind(distr、std :: ref(generator));' – zett42