バイアスを最小限に抑えて、高速ランダム シャッフルを繰り返し生成したいと考えています。
基本的な乱数発生器 (RNG) がバイアスされていない限り、 Fisher-Yates シャッフルがバイアスされていないことが知られています。
To shuffle an array a of n elements:
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]
しかし、RNG が偏っている (しかし高速である) 場合はどうなるでしょうか?
25 要素の配列のランダム順列を多数生成したいとします。偏った RNG で Fisher-Yates アルゴリズムを使用すると、順列に偏りが生じますが、これは、シャッフル アルゴリズムを適用する前に、25 要素の配列が同じ状態から始まることを前提としていると思います。たとえば、1 つの問題は、RNG の周期が 2^32 ~ 10^9 しかない場合、これは 25 であるため、25 要素のすべての可能な順列を生成できないことです! ~ 10^25 順列。
私の一般的な質問は、Fisher-Yates シャッフルの新しいアプリケーションを開始する前に、シャッフルされた要素をシャッフルしたままにしておくと、バイアスが減少し、アルゴリズムがすべての順列を生成できるようになるかということです。
私の推測では、一般的にはより良い結果が得られると思いますが、繰り返しシャッフルされる配列に、基礎となる RNG に関連する多数の要素が含まれている場合、順列が実際には予想よりも頻繁に繰り返される可能性があるようです。
これに対処する研究を知っている人はいますか?
サブ質問として、配列内の 25 個の要素のうち 5 個の順列を繰り返したい場合はどうすればよいので、Fisher-Yates アルゴリズムを使用して 5 個の要素を選択し、完全なシャッフルを行う前に停止しますか? (スワップされた配列の最後にある 5 つの要素を使用します。) 次に、以前の部分的にシャッフルされた 25 要素の配列を使用して、5 の別の順列を選択します。基になる RNG にバイアスがある場合は、元の 25 要素の配列。これについて何か考えはありますか?
25 要素のうち 5 要素の可能な順列は 6,375,600 しかないため、部分シャッフルのケースをテストする方が簡単だと思います。バイアスをチェックするために使用する簡単なテストはありますか?