3

乱数シーケンスのさまざまな位置にある番号にランダムにアクセスできる高速乱数ジェネレーターが必要です。Xorshiftを選択したのは、実装が高速で簡単だからです。

シーケンスから特定の乱数を取得するために、次のメソッドを実装しました(mPos次の乱数の位置を保存します)。

void XorshiftRandomGenerator::skipTo(unsigned int pos)
{
    // Reset if we passed the position
    if (mPos>pos)
        reset();

    // Generate random numbers until we're done
    while (mPos<pos)
        random();
}

後続random()は目的の数を返しますが、このメソッドは非常にコストがかかります。間にあるすべての乱数を計算せずに、Xorshiftで大量の乱数をスキップする方法はありますか?

別の方法として、別の乱数ジェネレーターを使用することもできます。先に速くスキップできるものを提案できますか?

4

3 に答える 3

2

このトピックを幅広く扱っている、ForestB.Brownによる1994年の論文「任意のストライドによる乱数生成」があります。

ナブがコメントで述べたように、線形合同法は効率的なスキップに使用できます。もちろん、LNGの通常の長所と短所が当てはまります。物事は単純で非常に高速ですが、疑似乱数はそれほど高品質ではありません。ここでは、式について詳しく説明します。

于 2015-02-13T12:35:18.970 に答える
2

確かにxorshiftにジャンプすることができ、プロセスはここで説明されていますが、私はそれを自分で読んでいないので、それがどれほど簡単かわかりません。

または、基礎となるLCG(@Daerstの回答と同じ)を使用してジャンプ関数を提供するPCGを確認できますが、後処理して統計プロパティを改善するか、ここで説明する分割可能なジェネレーターの一部を確認できます。たとえば、SplitMixジェネレーターには、ループ内で定数が追加されるだけなので、任意の距離をジャンプするには、ジャンプ距離に定数を掛けて追加するだけです(ここでは、BigCrushを通過するSplitMix派生物です)。

于 2016-06-19T04:53:18.457 に答える
1

乱数ジェネレーターの階層を使用できます。つまり、ジェネレータAで生成するすべての数値は、ジェネレータBのシードとして使用されます。ジェネレータBは、Aから次の数値を取得して再初期化し、次の100の数値を生成する前に、100の数値を生成します。このようにして、ステップをスキップできます。もちろん、これをジェネレーターのツリーにカスケードすることもできます。

于 2012-07-27T17:48:29.620 に答える