3

Unix システムの c で srandom() と random() を使用して乱数を生成しています。複数の RNG が必要です。同じシードを指定すると、それぞれが同じシーケンスを出力するはずです。また、それぞれの状態を保存して復元したいと思います。擬似コードの例を次に示します。

R1 = new_rng(5); //5 is the seed
R2 = new rng(5); //5 is the seed here, too.
a = R1.random();
b = R1.random();
d = R2.random(); //a == d
s1 = R2.get_state(); //save the state of R2
e = R2.random(); //b == e
R2.set_state(s1); //restore the state of R2
f = R2.random(); //b == f

どうすればいいですか?RNG が別のスレッドに分岐する場合があり、新しいスレッドを作成するときにも RNG の状態を複製する必要があります。

4

5 に答える 5

6

erand48()/ nrand48()/jrand48()を使用して、倍精度浮動小数点、非負の長整数、または符号付き長整数の乱数をそれぞれ生成します。これらの関数を使用すると、必要な数の独立したシーケンスを持つことができます。状態は引数として渡され、簡単に保存および復元できます。さらに、シーケンスは標準で定義されており、プラットフォームが異なっていても実行間で変化しません。

他のいくつかの答えは示唆していrand_r()ます。この関数は POSIX.1-2008 で廃止され、次の注記が含まれています。

このdrand48()関数は、より精巧な乱数ジェネレーターを提供します。

ある関数呼び出しと別の関数呼び出しの間で運べる状態量の制限はrand_r()、疑似乱数ジェネレーターのすべての要件を満たす方法で関数を実装できないことを意味します。したがって、重要な要件 (安全性を含む) を満たす必要がある場合は常に、この機能を避ける必要があります。

このrand_r()機能は、将来のバージョンで削除される可能性があります。

于 2009-06-30T14:18:04.493 に答える
1

メルセンヌツイスターに関するこの記事を読んでください。一番下にいくつかの実装へのリンクがあります。(つまり、PRNGを自分で実装します。)

于 2009-06-30T11:17:11.893 に答える
1

さまざまな UNIX フレーバーでの C ライブラリ拡張がいくつかあります。

  • BSD のようなランダム、initstate/setstate をチェック
  • _r バリアント (random_r、srandom_r、initstate_r など)
  • rand_r (stdlib.h)

対象の UNIX でサポートされているフレーバーはどれですか?

于 2009-06-30T11:31:34.363 に答える
1

rand_r(unsigned *seed)との代わりに使用srand()rand()ます。そうすれば、複数のランダム シードを維持できます。

于 2009-06-30T11:31:57.340 に答える
0

実際に同一のシードが与えられた場合、PRNG を使用してまったく同じシーケンスを生成できるかどうかはわかりません。一部の方法がそのように機能することは知っていますが、より良い方法にはある程度の非決定論が含まれているため、同一のシードが異なるシーケンスにつながる可能性があると思います。細かい櫛でlibcのドキュメントを調べて、これがどこかに言及されているかどうかを確認する必要があります。そうでない場合は、コードを確認してください (幸運にもコードにアクセスできる場合)。

いずれにせよ、これにより、アプリケーションが libc の PRNG 実装に非常に緊密に結合されます。あなたは間違いなく、開発している libc のフレーバー、さらには libc バージョンに縛られるでしょう。この機能が非常に重要な場合は、移植性と再現性を確保するために、アプリで乱数生成を再実装する必要がある場合があります。

于 2009-06-30T11:09:46.713 に答える