web-dev-qa-db-ja.com

JavaScript Math.randomはどのくらいランダムですか?

6年間、私のウェブサイトに 乱数ジェネレーター のページがありました。長い間、それは「乱数ジェネレータ」のGoogleでの最初または2番目の結果であり、ディスカッションフォーラムやブログで何百ものコンテストや図面を決定するために使用されてきました(リファラーが私のWebログを参照してください).

今日、誰かが私に電子メールを送って、思ったほどランダムではないかもしれません。彼女は非常に大きな乱数を生成しようとしました(たとえば、1〜10000000000000000000) )、それらはほとんど常に同じ桁数であることがわかりました。実際、関数をループでラップして、数千の数を生成し、非常に大きな数に対して十分に確実に生成できるようにしました変動は約2桁でした

どうして?

これがループバージョンです。自分で試してみることができます。

http://andrew.hedges.name/experiments/random/randomness.html

Mozilla Developer Network からの簡単な実装と、存在しないWebページをスワイプした1997年のコード(Paul Houleの「Central Randomizer 1.3」)の両方が含まれています。ソースを表示して、各メソッドの動作を確認します。

hereelsewhere についてMersenne Twisterを読みました。私が興味を持っているのはJavaScriptの組み込みMath.random関数からの結果にそれほど大きな違いがない理由。ありがとう!

110
Andrew Hedges

1から100までの数字を指定します。

  • 9桁は1桁(1-9)
  • 90は2桁です(10-99)
  • 1は3桁(100)です

1から1000までの数字を指定します。

  • 9は1桁
  • 90は2桁です
  • 900は3桁です
  • 1は4桁です

等々。

したがって、ランダムに選択した場合、選択可能な数値の大部分は同じ桁数になります。可能な値の大部分は同じ桁数になっているためです。

173
Quentin

あなたの結果は実際に期待されています。乱数が1〜10 ^ nの範囲で均一に分布している場合、数字の約9/10がn桁、さらに9/100がn-1桁になると予想されます。

55
jwoolard

さまざまな種類のランダム性があります。 Math.random は、数値の均一な分布を提供します。

桁違いの桁数が必要な場合は、指数関数を使用して べき乗分布 と呼ばれるものを作成することをお勧めします。

function random_powerlaw(mini, maxi) {
    return Math.ceil(Math.exp(Math.random()*(Math.log(maxi)-Math.log(mini)))*mini)
}

この関数は、2桁の数字と3桁の数字とほぼ同じ数の1桁の数字を提供します。

正規分布 (ガウス分布とも呼ばれる)のような乱数の他の分布もあります。

42
Christian

次のペーパーでは、主要なWebブラウザーでのmath.random()の安全性について説明します。 「主要なブラウザーでの一時的なユーザー追跡とクロスドメイン情報漏えいおよび攻撃」Amid Klein(2008) 。通常のJavaまたはWindowsビルトインPRNG関数。

一方、2 ^ 19937-1の期間のSFMTを実装するには、PRNGシーケンスごとに2496バイトの内部状態を維持する必要があります。これは許されないコストと考える人もいます。

18
jj1bdx

私には完全にランダムに見えます! (ヒント:ブラウザに依存します。)

個人的には、 [〜#〜] xkcd [〜#〜] から盗み出したものの、私の実装の方が良いと思います。

function random() {
  return 4; // Chosen by a fair dice throw. Guaranteed to be random.
}
18
Arafangion

10000000000000000000のような数値を使用すると、Javascriptが使用しているデータ型の精度を超えてしまいます。生成されるすべての数値は「00」で終わることに注意してください。

5
Greg

Chaos Game でJS擬似乱数ジェネレーターを試しました。

私の Sierpińskitriangle はかなりランダムだと言います: Fractal

5
zie1ony

たとえば、1e6までの数値を生成している場合、すべての数値がほぼ等しい確率で得られることを願っています。それはまた、1桁少ない数字を取得する可能性が10分の1しかないことを意味します。 100分の1の確率で2桁少なくなります。別のRNGを使用すると、対数ではなく数全体に均一な分布があるため、大きな違いが生じることはないでしょう。

3
Joey

1からNまで均一に分布する非乱数は同じ特性を持ちます。 (ある意味では)精度の問題であることに注意してください。 (整数としての)0-99の一様分布は、2桁の数値の90%を持ちます。 0-999999の一様分布には、905の数字が5桁あります。

数値のセット(制限が厳しくない条件の場合)には密度があります。誰かが「ランダムな」数について議論したい場合、これらの数の密度を指定する必要があります(上記のように)。一般的な密度は均一な密度です。他にも指数密度、標準密度などがあります。乱数発生器を提案する前に、どの密度が適切かを選択する必要があります。また、ある密度からの数値は、面倒な手段によって別の密度に簡単に変換できることがよくあります。

0
ttw