0

質問はトピックから外れているかもしれませんが、これは素晴らしく単純な乱数関数ではないのではないかと思っていました. 0 から までの乱数を与えることになっています$max:

function randomNumber($max){
  ((int)(1000000000000 / microtime())) % ($max+1);
}

ここで明らかな何かが欠けていなければ、これはうまくいくはずですよね?しかし、次の質問は次のとおりです。ここで作成された数字は本当にランダムですか? 1,000,000 個のサイコロをシミュレートすると、次のような結果が得られます。

Array
(
    [1] => 166520
    [2] => 166619
    [3] => 166522
    [4] => 167001
    [5] => 166512
    [6] => 166826
)

私がこの質問をしている理由は次のとおりです。真の乱数を作成することはできないと読んだので、考え始めたところ、この関数はまったく複雑になることなく、かなりランダムな結果をもたらすようです。ここで何か不足していますか?

4

1 に答える 1

1

これは、許容できるランダムと見なされるほど十分な疑似ランダムではありません。

乱数ジェネレーターで生成された偶数は真のランダムではないことに注意してください。それらは、乱数が必要なときに使用できる十分な疑似乱数です。非常に複雑なパターンではありますが、それらは依然としてパターンに従っています。

これは単純な解決策であり、乱数が得られるように見えるかもしれませんが、アプリケーションに固有に生成された集計データに奇妙な点が見つかる場合があります。たとえば、2 つのサイコロを同時に振るモノポリーのようなゲームでサイコロを振っていた場合、通常よりも 2 倍になる確率が高くなることがあります。特定のアルゴリズムがこの特定の問題を引き起こすとは言えません。これは、独自の乱数生成ルーチンを使用して発生する可能性のある異常の種類の例にすぎません。

具体的に言えることは、生成された値は、生成時の現在のマイクロ秒数に基づいているということです。数ミリ秒以内に 2 つの値を生成すると、結果は近くなります。典型的な乱数ジェネレーターは、ジェネレーターに値 (通常は現在の時刻から) をシードしますが、その時点から、別の数値を生成するための各呼び出しで、シードによって開始されたランダムシーケンスの次の値を提供するだけです。取得する数は、呼び出しごとにジェネレーターを再シードしない限り、時間に依存しません。ただし、この要素はルーチンに存在し、望ましくない副作用の原因となる可能性もあります.

于 2013-10-24T14:08:51.073 に答える