このコードを使用して、Fisher-Yates のランダム化アルゴリズムのバリエーションを使用してベクトルのランダム順列を生成しています (最初の要素から最後の要素に移動しますが、その逆ではありません)。boost::random::mt11213b
プログラムの開始時にシードされるプログラムで RNG をグローバルに使用しているgenerator.seed(time(NULL));
ため、ここではラッパーシングルトンを使用RandomNumber
しています。
boost::random::uniform_int_distribution<unsigned long>
distribution(0, vec.size()-1);
for (unsigned long i=0;i<vec.size();i++)
std::swap(vec[i], vec[distribution(RandomNumber::getInstance().generator)]);
いくつかの実験により、このアルゴリズムに問題がある可能性があると確信するようになりました。これは私がしたことです
- 長さ 100 の整数のベクトルを作成しました
- 最初の 75 個の要素と
0
最後の 25 個の要素を1
- 配列をシャッフルしました。
- リストから最初の 5 つの要素を取得し、それらを合計しました。
この手順を数千回繰り返しました(手動ではなくループを使用して:))毎回、新しいベクトルから始めました。次に、合計の算術平均を計算したところ0.98
、期待値の代わりに結果が得られました1.25
。
面白いことに、順序付けされたアルゴリズムではなく、同じアルゴリズムで 1 回シャッフルされたベクトルから始めると、結果は次のよう1.22
に増加し、反復ごとにベクトルを破棄せずに、もう一度シャッフルするだけで、結果は1.25
期待値です。
何が問題なのかわからない。アルゴリズムは健全に見えます。私が考えることができる唯一の問題は、シード段階と
boost::random::uniform_int_distribution<unsigned long>
distribution(0, vec.size()-1);
ベクトルがシャッフルされる前に毎回呼び出される行 (おそらく、プログラムで一度だけ呼び出す必要がありますが、それはあまり意味がありません)
どんな助けでも大歓迎です!