シードを使用してrand呼び出すことで呼び出しを「再開」できることはわかっていますが、これは暗号化メソッドを含む他のライブラリ メソッドによる将来の呼び出しに影響を与えるのでしょうか?srandrand
特定の場所でランダム性を繰り返しながら、コードの残りの部分が影響を受けないようにするにはどうすればよいですか?
(Ruby 1.9.2) 乱数発生器をシリアル化し、それをファイルに保存して、そのファイルをプログラムに提供できます。
ファイルを作成します。
File.open('random_generator.marshal', 'w'){ |f| Marshal.dump(Random.new, f) }
プログラムで乱数発生器を使用します。
f = File.open( 'random_generator.marshal', 'r' )
r = Marshal.load( f )
f.close
10.times{ puts r.rand } #repeatable
単純ランダム宝石を使用します。
(Ruby 1.9.3 では)を使用するより簡単な解決策がありRandomます。
r = Random.new(seed)を使用して、ランダム性呼び出しを生成するために使用できるオブジェクトを取得する必要がありますr.rand。r.randこれは反復可能であり、 notの呼び出しにのみ影響しますKernel.rand。
システム バージョンを使用しない独自のPRNG を実装できます。最も単純な線形合同法からメルセンヌツイスターまで、これを行う方法に関する文献はたくさんあります。
実際、Ruby はオープン ソースであるため、Ruby が乱数を処理する方法をこっそり覗いて(参考文献を参照)、システム バージョンとは別の情報を使用して再実装することができます。random.c
ランド():
...Kernel::srand を使用して、プログラムの異なる実行間で繰り返し可能な乱数シーケンスを確保できます....
srand():
擬似乱数ジェネレーターを number.to_i.abs の値にシードします。...シードを既知の値に設定することにより、テスト中にスクリプトを決定論的にすることができます....
シード値とユーザーが行った反復回数を保存し、後でその値で再シードし、以前に使用した回数をループして前の値をステップオーバーし、着陸することができますシーケンス内の次の値。シーケンスを回復しようとするのは、私が知っている唯一の方法です。他のルーチン/スレッドが気になる場合は、元のシードを取得して保存してから、srand を設定し、次の番号を取得してから、元のシードを復元します。
ランダム性に依存する他のルーチンのランダム性に影響を与えることを懸念している場合、それらのルーチンの作成者は、真にランダムなシードを処理していることを確認するために何かを行うべきだったと思います。あなたは自分のコードにのみ関心を持ち、システムを殺すことはできません。それを超えると、責任は彼らのものになります。
JRuby を使用している場合は、java.util.Random.