web-dev-qa-db-ja.com

161803398は「特別な」番号ですか? Math.Random()の内部

私は答えが「数学のため」だと思うが、誰かが基本についてもう少し洞察を与えられることを望んでいたレベル...

今日、私はBCLソースコードをいじくり回し、以前に使用したクラスのいくつかが実際にどのように実装されているかを見ました。以前は(擬似)乱数を生成する方法について考えたことはなかったので、どのように行われるかを確認することにしました。

完全なソースはこちら: http://referencesource.Microsoft.com/#mscorlib/system/random.cs#29

private const int MSEED = 161803398; 

このMSEED値は、Random()クラスがシードされるたびに使用されます。

とにかく、この「マジックナンバー」-161803398を見ましたが、なぜそのナンバーが選択されたのか、最も曖昧な考えがありません。素数でも2の累乗でもありません。より重要と思われる数字の「中間」ではありません。私はそれを2進数と16進数で見ましたが、私にとっては数字のように見えました。

Googleで番号を検索しようとしましたが、何も見つかりませんでした。

163
Rob P.

いいえ、しかしそれはファイ(「黄金比」)に基づいています。

161803398 = 1.61803398 * 10^8 ≈ φ * 10^8

黄金比の詳細はこちら

そしてreallyここでカジュアルな数学者のための良い読み物

そして、私は 乱数発生器に関する研究論文 がこの主張に同意することを発見しました。 (53ページを参照)

141

この数値は、 黄金比1.61803398 * 10 ^ 8から取得されます。マットはこの数が何であるかという素晴らしい答えを出したので、アルゴリズムについて少し説明します。

これは、このアルゴリズムの特別な番号ではありません。アルゴリズムはKnuthの 減算 乱数生成アルゴリズムであり、その主なポイントは次のとおりです。

  • 56個の乱数の循環リストを保存します
  • 初期化はリストを埋めるプロセスで、特定の決定論的アルゴリズムを使用してそれらの値をランダム化します
  • 31離れた2つのインデックスが保持されます
  • 新しい乱数は、2つのインデックスでの2つの値の差です
  • リストに新しい乱数を保存する

ジェネレータは、次の再帰に基づいています:Xn =(Xn-55 - バツn-24)mod m、n≥0。これは 遅延フィボナッチジェネレーター :Xの部分的なケースです。n =(Xn-j @ バツn-k)mod m、0 <k <jおよび@は任意の2項演算(減算、加算、xor)です。

このジェネレータにはいくつかの実装があります。 Knuthは、彼の本でFORTRANの実装を提供しています。次のコメント付きで次の code が見つかりました。

パラメーター(MBIG = 1000000000、MSEED = 161803398、MZ = 0、FAC = 1.E-9)

Knuthによると、上記の値の代わりに、大きなMBIG、および小さな(しかしまだ大きな)MSEEDを使用できます。

もう少し見つけることができます ここ 注、これは実際には研究論文ではなく(Mathが述べているように)、これは単なる修士論文です。

暗号の人々は、無理数(piesqrt(5))を使用することを好みます。これは、 そのような数 の数字が等しい周波数であるため、高い エントロピー を持ちます。この関連する質問は security stackexchange で見つけることができ、そのような数値について詳しく知ることができます。引用はここにあります:

「定数がランダムに選択されると、高い確率で、攻撃者はそれを破ることができなくなります。」しかし、偏執的なロットである暗号作成者は、誰かが「この定数のセットを使用しましょう。 私はランダムに選んだ、私は誓います 」と言うとき、懐疑的です。したがって、妥協として、たとえば、πのバイナリ展開のような定数を使用します。大きな数のプールからランダムにそれらを選択したという数学的な利点はなくなりましたが、少なくとも、妨害行為はなかったと確信できます。

62
Salvador Dali