3

いくつかの正当な理由から、BSDのrandom()を使用して非常に大量の乱数を生成する必要があります。また、そのサイクルは非常に短いため(誤解しない限り、〜2 ^ 69)、そのような数値の品質はかなり急速に低下します。私のユースケース。アクセスできるrngボードを使用することはできますが、非常に遅いので、このトリックを実行できると思いました。ボードから1つの数値を取得し、それを使用してrandom()をシードし、random()を使用して数値を描画し、ボードは、新しい番号が利用可能であると言います。ボードは毎秒約100の数値を生成するので、random()はほとんど循環せず、生成速度は毎秒数百万の数値の要件に簡単に対応できると思います。

とにかく、問題は、random()が0と(2 ^ 31)-1の間の数値を均一に描画すると主張していることですが、私は数え切れないほどの数を描画しており、0も(2 ^ 31)-1これまでのところ。たぶん1と(2 ^ 31)-2ですが、私は極端なものを見たことがありません。さて、乱数の問題は、確信が持てないことです(Dilbert、Debianを参照)が、それでもこれは非常に奇妙に思えます。さらに、histc()関数を使用してOctaveで生成されたデータセットを分析しようとしましたが、最も低いビンと最も高いビンには、中間のビンの数の半分から4分の3が含まれています(これは均一に満たされているため、一部のビンでは推測されます)分布が「均一」であることを意味します)。

誰かがこれを説明できますか?

いくつかのコードを編集する

ボードはこの構造を3つのコンポーネントで出力し、次にそれらを組み合わせてシードを生成するためにいくつかのマンボジャンボを実行します。このボードの仕様はありません。数年前に前の学生がまとめた古いハードウェアであり、ドキュメントはほとんどありません。私が使用しているこの式は、ドキュメントで提案されているものの1つです。STEPパラメーターは、パフォーマンスを最適化すると同時にCPU使用率を抑えることができるように、1つのシードを使用してどのように数値を描画できるかを示します。

float n = fabsf(fmod(sqrt(a.s1*a.s1 + a.s2*a.s2 + a.s3*a.s3), 1.0));
unsigned int seed = n * UINT32_MAX;
srandom(seed);

for(int i = 0; i < STEP; i++) {
  long r = random();
  n = (float)r / (UINT32_MAX >> 1);
  [_numbers addObject:[NSNumber numberWithFloat:n]];
}
4

2 に答える 2

0

サイクルの長さを延長するための 1 つの方法は、異なる周期で 2 つの RNG を実行し、それらの出力を XOR することです。いくつかの例については、 L'Ecuyer 1988を参照してください。

于 2012-05-28T11:36:49.850 に答える
0

あなたはそれを確信していますか

void main() {
  while (random() != 0L);
}

無期限にハングしますか?私の Linux マシン (Gnu C ライブラリはBSDと同じ線形フィードバック シフト レジスタを使用しますが、シード手順は異なります) ではそうではありません。

このリファレンスによると 、アルゴリズムは連続する 0 または 1 の「ラン」を長さまで生成しますn-1。ここで、n はシフト レジスタのサイズです。これが 31 個の整数のサイズ (デフォルトのケース) の場合、最終的には 0 を 30 回 (ただし 31 回ではありません) 続けて返すことさえ確信できます。もちろん、それが起こるまで数世紀待たなければならないかもしれません...random()

于 2012-05-27T22:56:02.733 に答える