1

rand(x, y, seed)次のプロパティを使用して、引数に基づいて(疑似)乱数を返す関数に興味があります。

  1. 返される値は、その3つの引数に依存する必要があり、これまでに呼び出された回数には依存しません。randたとえば、これらの呼び出しをこの順序で想定します。

    rand(0, 0, 123) = 1
    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    

    次に、同じ引数を使用して呼び出しrandますが、順序は異なりますが、同じ値を取得する必要があります。例えば:

    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    rand(0, 0, 123) = 1
    
  2. 関数は、通常の適切なプロパティ(まともな、私は実際にはそれほど凝ったものは必要ありません)PRNGを持っている必要があります:大周期、一様分布など。符号付き整数に適合する正の整数を返すことは問題ありません。必要に応じて高くすることもできます。

  3. これらの数値が行列の生成に使用されると想定します。次に、シードを変更することで、生成されたマトリックスが他のシードによって生成されたマトリックスと可能な限り異なって見えるようにする必要があります。これは、できるだけ多くのシードで発生するはずです。行列を繰り返さないようにします。

それが役に立ったら、私のシードは常にミリ秒単位のUNIXタイムスタンプになります(それがどういうわけか簡単になる場合は秒単位でもかまいません)。すべての引数は32ビットのsignedintまで使用できますが、関数内で64ビット値を操作することは問題ありません。

これにはどのような機能を使用できますか?

私が考えたこと:

パーリンノイズは私が望むことのいくつかを実行しているように見えますが、PRNGとして、特に分布に関して、それが実際にどれほど適切であるかはわかりません。(x, y)また、パラメータがかなりランダムになり、すべてのパラメータを事前に計算できないため、どれほど効率的かわかりません。

次の関数も調べました。

p = 1400328593
rand(x, y, seed) = (x * x * seed + y * seed * seed + seed * x * y + seed) mod p
                 = (seed * (x * x + y * seed + x * y + 1)) mod p

これは十分な数を生成するようです。私の(非常に弱い)テストに基づくと、それらも非常によく分布しているようです。生理のテストはもっと難しいですが、私はそれをしていません。

アップデート:

上記の関数のEntの出力は次のとおりです。time(NULL)シードはCで、値は次のように生成され(x, y) in {0 ... 999} x {0 ... 999}ます。

エントロピー=バイトあたり3.312850ビット。

最適な圧縮により、この9207076バイトファイルのサイズが58%削減されます。

9207076サンプルのカイ2乗分布は、229710872.43であり、ランダムにこの値を超えるのは、0.01パーセント未満の時間です。

データバイトの算術平均値は52.3354(127.5 =ランダム)です。Piのモンテカルロ値は4.000000000(エラー27.32パーセント)です。シリアル相関係数は0.036131です(完全に無相関= 0.0)。

これは実際には十分に良いですか(理論的には、上記のテストはまったく良くないことを示唆しています)、または私が使用すべきよく知られているものがありますか?

4

2 に答える 2

2

ハッシュ関数が必要なようです。優れた分散特性が保証されているため、非効率的でない場合は、SHA1などの安全なものを選択してください。それ以外の場合は、FNVなどの一般的なハッシュ関数を使用できます。シードと座標を入力データとして使用し、ハッシュをランダム値として使用するだけです。

于 2012-10-02T10:32:36.463 に答える
1

BlumBlumShubを使ってみることができます。これには、系列のn番目の値を直接計算できるという特性があります。これは状況に適しているようです。これは、p、q、およびx0の3つのパラメーターを取ります。pとqは素数であり、x0はpとqの両方に関連して素数です。したがって、引数xとyを使用してx番目とy番目の素数を見つけることができ、次にそれらはpとqに適しており、3番目のパラメーターを使用してx0に適した値を見つけることができます。これは少し面倒で、Blum Blum Shubは暗号化RNGであるため低速ですが、実際に速度を必要としない場合は機能し、実装はそれほど難しくありません。

これを行う別の方法は、CMWCのようなRNGを取得し、ジェネレーターのi番目の位置をx + y ^ i + seed ^(2i)のようなもので埋め、ジェネレーターをしばらく実行することです(おそらく格納する値の数に等しい倍数)、次に値を引き出します。

CMWCを使用したい場合は、ここでgithubにある実装と、既知の期間でジェネレーターを構築するための値をここで確認できます。

于 2012-10-01T16:58:42.167 に答える