1

乱数発生器に組み込まれている C++ 標準ライブラリを使用して、すべてを保存せずにシーケンス内の特定の乱数を取得する方法はありますか?

お気に入り

srand(cTime);
getRand(1); // 10
getRand(2); // 8995
getRand(3); // 65464456
getRand(1); // 10
getRand(2); // 8995
getRand(1); // 10
getRand(3); // 65464456
4

5 に答える 5

1

C++11 乱数エンジンはdiscard(unsigned long long z)、乱数シーケンスをz段階的に進めるメンバー関数 (§26.5.1.4) を実装する必要があります。複雑さの保証は非常に弱く、 「z連続した呼び出しの複雑さよりも悪くないe()」. このメンバーは明らかに、ノート 274 が述べているように、可能であればよりパフォーマンスの高い実装を公開できるようにするためだけに存在します。

zこの操作はユーザー コードでは一般的であり、多くの場合、エンジン固有の方法で実装できるため、連続呼び出しを行う同等の単純なループよりもパフォーマンスが大幅に向上しますe()

ジェネレーターを再シードし、値を破棄し、次に生成された値を使用することで、順番に th 番号discardを取得するという要件を簡単に実装できるとします。nn-1

私は、標準の RNG エンジンのどれが の効率的な実装に適しているか (あるとしても) は知りませんdiscard。少し調査とプロファイリングを行うのは、時間の価値があるかもしれません。

于 2013-07-28T20:13:49.427 に答える
1

数字を保存する必要があります。他のバリアントがあるかもしれませんが、それでも数値のリストを保存する必要があります (たとえば、引数 to getRand()- に基づいて異なるシードを使用しますが、それらを保存するよりも実際には有益ではありません)。

このようなものはかなりうまくいくでしょう、私は言います:

int getRand(int n)
{
    static std::map<int, int> mrand;
    // Check if it's there. 
    if ((std::map::iterator it = mrand.find(n)) != mrand.end())
    {
        return it->second;
    }

    int r = rand();
    mrand[n] = r;
    return r;
}

(私はこのコードをコンパイルしていません。「この種のことがうまくいくかもしれない」として書いただけです)

于 2013-07-28T13:08:44.333 に答える
0

チェックアウト: Random123

ドキュメントから:

Random123 は、「カウンターベース」の乱数ジェネレーター (CBRNG) のライブラリであり、N にステートレス ミキシング関数を適用することで N 番目の乱数を取得できます。

于 2013-07-28T18:42:25.823 に答える