乱数発生器に組み込まれている C++ 標準ライブラリを使用して、すべてを保存せずにシーケンス内の特定の乱数を取得する方法はありますか?
お気に入り
srand(cTime);
getRand(1); // 10
getRand(2); // 8995
getRand(3); // 65464456
getRand(1); // 10
getRand(2); // 8995
getRand(1); // 10
getRand(3); // 65464456
C++11 乱数エンジンはdiscard(unsigned long long z)
、乱数シーケンスをz
段階的に進めるメンバー関数 (§26.5.1.4) を実装する必要があります。複雑さの保証は非常に弱く、 「z
連続した呼び出しの複雑さよりも悪くないe()
」. このメンバーは明らかに、ノート 274 が述べているように、可能であればよりパフォーマンスの高い実装を公開できるようにするためだけに存在します。
z
この操作はユーザー コードでは一般的であり、多くの場合、エンジン固有の方法で実装できるため、連続呼び出しを行う同等の単純なループよりもパフォーマンスが大幅に向上しますe()
。
ジェネレーターを再シードし、値を破棄し、次に生成された値を使用することで、順番に th 番号discard
を取得するという要件を簡単に実装できるとします。n
n-1
私は、標準の RNG エンジンのどれが の効率的な実装に適しているか (あるとしても) は知りませんdiscard
。少し調査とプロファイリングを行うのは、時間の価値があるかもしれません。
数字を保存する必要があります。他のバリアントがあるかもしれませんが、それでも数値のリストを保存する必要があります (たとえば、引数 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;
}
(私はこのコードをコンパイルしていません。「この種のことがうまくいくかもしれない」として書いただけです)
チェックアウト: Random123
ドキュメントから:
Random123 は、「カウンターベース」の乱数ジェネレーター (CBRNG) のライブラリであり、N にステートレス ミキシング関数を適用することで N 番目の乱数を取得できます。