C ++ rand()関数に基づいて、プログラムで数千のオブジェクトを生成します。それらをメモリに保持することは徹底的です。rand()の現在のシードをいつでもコピーする方法はありますか?これにより、完全なオブジェクトではなく、現在のシードのみを保存する機会が得られます。(したがって、乱数のまったく同じサブシーケンスを再生成することで、これらのオブジェクトを再生成できます)
徹底的な解決策は、 rand()によって与えられた乱数の完全なシーケンスを格納することです-それは価値がありません。もう1つの解決策は、ランダム化された数値に対して独自のクラスを実装することです。
グーグルは私に前向きな手がかりを与えなかった。randとsrandの基本を教えている記事は何百もありますが、具体的な記事は見つかりませんでした。
シードスティーラーが実装された他の乱数ジェネレーターを知っている人はいますか?
迅速な回答ありがとうございます!この質問に対する可能な回答/解決策は他にもあるので、ここにあなたの回答のリストを作成しました。
ソリューション:
簡単な答えは次のとおりです。シードを取得する標準的な方法はありません
最も近い回避策は、最初にINITIALシードを保存し、rand()関数を呼び出した回数を数えることです。これは、すべてのコンパイラの現在のstd :: rand()関数で機能するため、これを解決策としてマークしました(これが主な質問でした)。2.0 GHz CPUのベンチマークを行ったところ、35秒間にrand()を1,000,000,000回呼び出してカウントできることがわかりました。これは良さそうに聞こえるかもしれませんが、1つのオブジェクトを生成するために80,000回の呼び出しがあります。unsignedのサイズが長いため、これにより世代数が50,000に制限されます。とにかく、ここに私のコードがあります:
class rand2 { unsigned long n; public: rand2 () : n(0) {} unsigned long rnd() { n++; return rand(); } // get number of rand() calls inside this object unsigned long getno () { return n; } // fast forward to a saved position called rec void fast_forward (unsigned long rec) { while (n < rec) rnd(); } };
もう1つの方法は、Matteo Italiaが提案したような、独自の疑似乱数ジェネレーターを実装することです。これは最速で、おそらく最良のソリューションです。4,294,967,295 rand()呼び出しに制限されておらず、他のライブラリも使用する必要はありません。コンパイラが異なればジェネレータも異なることは言及する価値があります。MatteoのLCGをMingw/GCC3.4.2およびG++4.3.2のrand()と比較しました。それらの3つすべてが異なっていました(シード= 0)。
Cubbi、Jerry Coffin、Mike Seymourが提案したように、C++11または他のライブラリのジェネレーターを使用します。すでにそれらを使用している場合は、これが最良のアイデアです。C ++ 11ジェネレーターのリンク:http://en.cppreference.com/w/cpp/numeric/random (ここにもいくつかのアルゴリズムの説明があります)