私はこれについて私の頭を理解することができません、どれがよりランダムですか?
Rand()
OR
Rand() * Rand()
私はそれが本当の頭の体操だと思っています、あなたは私を助けてもらえますか?
編集:
直感的には、数学的な答えはそれらが等しくランダムであるということになることを知っていますが、2つを一緒に掛けるときに2回「乱数アルゴリズムを実行する」一度。
擬似ランダム変数のランダム性またはその乗算を見つけようとするときはいつでも前の答えは正しいですが、 Random() は通常一様分布ですが、 Random()* Random() ではありません。
これは擬似乱数変数を通してシミュレートされた 一様乱数分布サンプル です。
BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]
これは2つの確率変数を乗算した後の分布ですが、
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] *
RandomReal[{0, 1}, 50000], {50000}], 0.01]]
したがって、どちらも「ランダム」ですが、分布は大きく異なります。
一方、 2 * Random() は一様分布です。
BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
Random()+ Random()は違います!
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] +
RandomReal[{0, 1}, 50000], {50000}], 0.01]]
中心極限定理 は、項が増えるにつれてRandom()の合計が 正規分布 になる傾向があると述べています。
たった4つの用語であなたは得ます:
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
{50000}],
0.01]]
そしてここで、1、2、4、6、10、20の一様分布確率変数を足し合わせることによって、一様分布から正規分布への道を見ることができます。
編集
いくつかのクレジット
最後の2つの画像に示されている確率分布は Irwin-Hall分布 として知られているというコメントで指摘してくれた Thomas Ahle に感謝します。
どちらの方法もランダムであると思いますが、私のgutfeelはRand() * Rand()
のほうがランダムではないと言っています。 1つのRand()
が0
になるとすぐに、合計は0
になります
どちらも「もっとランダム」ではありません。
Rand()
は、擬似乱数シードに基づいて(通常は常に変化している現在時刻に基づいて)予測可能な数値セットを生成します。シーケンス内の2つの連続した数字を乗算すると、異なるが同じように予測可能な数字のシーケンスが生成されます。
これが衝突を減らすかどうかを検討して、答えはノーです。 0 < n < 1
の場合、2つの数を乗算することにより、実際には衝突が増えます。結果はより小さな部分になり、スペクトルの下端に向かって結果に偏りが生じます。
いくつかのさらなる説明。以下では、「予測不可能」と「ランダム」は、次の数字が前の数字に基づいて何を推測するかを推測する能力を指します。 Oracleです。
次の値の一覧を生成するシードx
を考えます。
0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...
Rand()
は上記のリストを生成し、Rand() * Rand()
は次のものを生成します。
0.18, 0.08, 0.08, 0.21, ...
どちらの方法でも、同じシードに対して常に同じ番号リストが生成されるため、Oracleも同様に予測できます。しかし、2つの呼び出しを掛け合わせた結果を見ると、元の順序ではまともな分布にもかかわらず、それらはすべて0.3
の下にあることがわかります。 2つの分数を乗算する効果のために、数に偏りがあります。結果として得られる数は常に小さいので、それでも予測不可能であるにもかかわらず衝突である可能性がはるかに高いです。
要点を説明するための単純化しすぎ
ランダム関数が0
または1
のみを出力すると仮定します。
random()
は(0,1)
の1つですが、random()*random()
は(0,0,0,1)
の1つです
2番目のケースで0
を取得する機会は、1
を取得する機会とまったく同じではないことがはっきりわかります。
私が最初にこの答えを投稿したとき、それを読む人が一目でrandom()
とrandom()*random()
の違いを理解できるようにできるだけ短くしたいと思っていましたが、私は元の広告の質問に答えるのを止められません。
どちらがランダムか
random()
、random()*random()
、random()+random()
、(random()+1)/2
、または固定結果にならないその他の組み合わせは、同じエントロピーの元(または擬似乱数発生器の場合は同じ初期状態)を持つので、答えは equal random(違いは分布にあります)。私たちが見ることができる完璧な例はクラップスのゲームです。あなたが得る数はrandom(1,6)+random(1,6)
です、そして我々は皆7を得ることが最も高い可能性があることを知っています、しかしそれは2つのダイスを振ることの結果が1つを出すことの結果より多かれ少なかれランダムであることを意味しません。
これは簡単な答えです。独占を考えなさい。あなたは2つの6面サイコロ(またはゲーム記法を好む人のための2d6)を転がしてそれらの合計を取ります。あなたが7をロールすることができる6つの可能な方法があるので(1,6 2,5 3,4 4,3 5,2および6,1)、最も一般的な結果は7です。 2は1,1にしかロールできませんが。範囲が同じであっても、2d6のローリングは1d12のローリングとは異なることは簡単にわかります(1d12で1が得られることを無視しても、ポイントは変わりません)。結果を追加するのではなく乗算すると、同様の方法で結果が歪められ、結果のほとんどが範囲の中央に表示されます。外れ値を減らそうとしている場合、これは良い方法ですが、均一な分布を作るのには役立ちません。
(そして、奇妙なことに、ローロールも増加します。ランダム性が0から始まるとすると、他のロールが0になっても0になるので、スパイクは0になります。どちらかの結果が0であれば、もう一方の結果に関係なく全体が0になるので、1を得る唯一の方法は両方のロールが1になることです。しかし、それは奇妙なグラフになります。)
必須 xkcd ...
これをもっと離散的な数字で考えると役に立つかもしれません。 1から36の間の乱数を生成することを検討してください。そのため、最も簡単な方法は、2つの6面サイコロを投げることです。あなたはこれを得ます:
1 2 3 4 5 6
-----------------------------
1| 1 2 3 4 5 6
2| 2 4 6 8 10 12
3| 3 6 9 12 15 18
4| 4 8 12 16 20 24
5| 5 10 15 20 25 30
6| 6 12 18 24 30 36
だから私たちは36の数を持っていますが、それらのすべてが公正に表されているわけではなく、いくつかはまったく発生しません。中心の対角線(左下隅から右上隅)付近の数字が最も高い頻度で発生します。
サイコロ間の不公平な分布を説明するのと同じ原理が、0.0から1.0の間の浮動小数点数にも同様に当てはまります。
「ランダムさ」に関するいくつかのことは直感に反するものです。
フラットなRand()
の分布を仮定すると、以下はフラットでない分布になります。
sqrt(Rand(range^2))
(Rand(range) + Rand(range))/2
range - sqrt(Rand(range^2))
特定のバイアスカーブを作成する方法は他にもたくさんあります。私はRand() * Rand()
の簡単なテストをしました、そしてそれはあなたに非常に非線形な分布をします。
「ランダム」対「よりランダム」は、どちらのゼロがもっとゼロであるかを尋ねるのと少し似ています。
この場合、Rand
はPRNGなので、完全にランダムではありません。 (実際には、種がわかっていればかなり予測可能です)。それに別の値を掛けると、多かれ少なかれランダムにはなりません。
真の暗号型RNGは実際にはランダムになります。そして、どんな種類の関数でも値を実行してもそれ以上のエントロピーを追加することはできず、エントロピーを削除してランダムではない可能性が非常に高いです。
ほとんどのRand()の実装にはある程度の期間があります。すなわち膨大な数の呼び出しの後、シーケンスが繰り返されます。 Rand() * Rand()
の出力のシーケンスは半分の時間で繰り返されるので、その意味ではそれほど「ランダムではありません」です。
また、慎重に構成しないと、乱数に対して算術演算を実行すると乱数が少なくなる傾向があります。上のポスターは "Rand()
+ Rand()
+ Rand()
..."(k回と言います)を引用したもので、実際にはRand()
が返す値の範囲の平均値のk倍になる傾向があります。 (それは、その意味について対称的なステップを持つランダムウォークです。)
具体的にするために、Rand()関数は[0,1)の範囲の一様分布の乱数を返します。 (はい、この例は無限の精度を可能にします。これは結果を変えることはありません。)あなたは特定の言語を選びませんでした。 )積Rand() * Rand()
も範囲[0,1)にありますが、もはや一様分布ではありません。事実、積は区間[1/4,1)と同じくらい区間[0,1/4)にある可能性が高いです。より多くの乗算は結果をさらにゼロに向かってゆがめるでしょう。これにより、結果がより予測可能になります。広いストロークでは、より予測可能な==ランダムではありません。
一様にランダムな入力に対する一連の操作は、一様にランダムではないため、予測可能性が向上します。慎重に、この性質を克服することができます、しかしそれからそれは算術で時間を浪費するよりむしろあなたが実際に望んだ範囲で一様に分布した乱数を発生させることがより簡単であったでしょう。
あなたが探している概念は「エントロピー」、ビット列の乱れの「程度」です。この考えは、「最大エントロピー」の概念に関して最も理解しやすいものです。
最大エントロピーを有するビット列のおおよその定義は、それがより短いビット列に関して正確に表現することができないということである(すなわち、より小さな文字列を元の文字列に拡張するための何らかのアルゴリズムの使用)。
最大エントロピーと無作為性との関連性は、「ランダムに」数を選ぶと、ほとんど確実にビット列が最大エントロピーを持つ数に近い、つまり圧縮できない数を選ぶことに由来します。これが「乱数」の特徴を最もよく理解していることです。
したがって、2つの乱数サンプルから乱数として「2倍」の乱数を作成する場合は、2つのビット文字列を連結します。 。実際には、サンプルを倍長のWordの上位半分と下位半分に詰め込むだけです。
もっと実用的なことに、もしあなたがあなた自身が安っぽいRand()で鞍を付けているのであれば、それは時々2つのサンプルを一緒にxorすることを手助けすることができます。
受け入れられた答えはとても素敵ですが、あなたの質問に答えるための別の方法があります。 PachydermPuncherの答え は既にこの代替アプローチを取っています、そして私はそれを少し広げるつもりです。
情報理論について考える最も簡単な方法は、情報の最小単位、つまり1ビットという観点からです。
C標準ライブラリでは、Rand()
は0からRand_MAX
の範囲の整数を返します。これはプラットフォームによって異なる方法で定義される場合があります。 Rand_MAX
が、n
が何らかの整数である2^n - 1
として定義されていると仮定します(これは、Microsoftの実装の場合で、n
は15です)。そして、良い実装はn
ビットの情報を返すと言うでしょう。
Rand()
が硬貨を弾いて1ビットの値を見つけ、それが15ビットのバッチになるまで繰り返すことによって乱数を構成すると想像してください。その場合、ビットは独立しています(任意の1ビットの値は、同じバッチ内の他のビットが特定の値を持つ可能性には影響しません)。したがって、独立して考慮される各ビットは、0から1までの範囲の乱数のようなものであり、その範囲にわたって「均等に分布」しています(1が0である可能性が高い)。
ビットの独立性は、ビットのバッチによって表される数もそれらの範囲にわたって均等に分配されることを保証します。これは直感的に明白です。15ビットがある場合、許可される範囲は0から2^15 - 1
= 32767までです。その範囲内のすべての数値は、次のように一意のビットパターンです。
010110101110010
また、ビットが独立している場合は、他のどのパターンよりもパターンが発生する可能性は高くありません。だから範囲内のすべての可能な数は同じように可能性があります。 Rand()
が一様に分布した整数を生成するならば、それらの数は独立したビットで作られます。
それでRand()
をビットを作るための生産ラインと考えてください。それは偶然に任意のサイズのバッチでそれらを提供するために起こります。サイズが気に入らない場合は、バッチを個々のビットに分割してから、好きな量にまとめてください(ただし、2のべき乗ではない特定の範囲が必要な場合は、数値を小さくする必要があります)。そして、はるかに簡単な方法は、浮動小数点に変換することです。
元の提案に戻って、15のバッチから30のバッチに移動し、最初の番号をRand()
に要求し、15桁シフトしてから別のRand()
を追加するとします。これは、均等な分布を乱すことなくRand()
への2つの呼び出しを組み合わせる方法です。あなたが情報のビットを置く場所の間に重なりがないのでそれは単に働きます。
これは、定数を掛けることによってRand()
の範囲を「伸ばす」のとは大きく異なります。たとえば、Rand()
の範囲を2倍にしたい場合は、2倍にすることができます。ただし、今では偶数のみを取得し、奇数を取得することはできません。これは必ずしもスムーズな配布ではなく、アプリケーションによっては深刻な問題になる可能性があります。ルーレットのようなゲームで、おそらく奇数/偶数の賭けが可能です。 (ビットで考えると直観的にその間違いを避けることができます。2を掛けることはビットを1桁左にシフトする(重要度が高い)ことと同じで、ギャップをゼロで埋めることと同じだからです。したがって、明らかに情報量は同じです - それは少し動いただけです。)
浮動小数点数範囲には本質的に全く表現できないギャップがあるため、このような数範囲のギャップは把握できません。an無限数2つの表現可能な浮動小数点数の間には実数の欠落があります。だから私たちはとにかくギャップを持って生きることを学ぶ必要があります。
他の人が警告しているように、特に数学者が実数の魅力に抵抗することはできないので、直観はこの分野では危険です。
しかし、少なくともあなたがそれを少しの用語で考えるならば、あなたの直感はあなたをもう少し遠くに連れて行くかもしれません。ビットは本当に簡単です - たとえコンピュータでも理解できます。
他の人が言っているように、簡単な簡単な答えは:いいえ、それはよりランダムではありませんが、それは分布を変えます。
あなたがダイスゲームをしていたとしましょう。あなたはいくつかの完全に公正な、ランダムなサイコロを持っています。各ダイスロールの前に、最初に2つのサイコロをボウルに入れて振り回し、1つのサイコロをランダムに選んでからそのサイコロを転がした場合、サイコロのロールは「ランダム」になりますか。明らかに違いはないでしょう。両方のサイコロが乱数を出す場合、2つのサイコロのうち1つを無作為に選んでも違いはありません。どちらの方法でも、1から6の間の乱数を得て、十分な数のロールに均等に分配することができます。
あなたがサイコロが公正でないかもしれないとあなたが疑ったならば、私は現実の生活の中でそのような手順が役に立つかもしれないと思います。例えば、サイコロが少しアンバランスで、1/6以上の頻度で1を与える傾向があり、別の1が異常に頻繁に6を与える傾向がある場合、2つの間でランダムに選択すると偏りがわかりにくくなります。 (この場合、1と6はまだ2、3、4、および5を超えて表示されますが、不均衡の性質によって異なります)。
ランダムネスには多くの定義があります。ランダム級数の1つの定義は、それがランダムプロセスによって生成された一連の数であるということです。この定義により、もし私が公正なダイスを5回振って2、4、3、2、5という数字を得れば、それはランダムなシリーズです。私がその同じ公正なダイスをさらに5回回して1、1、1、1、1を得た場合、それはまたランダムなシリーズです。
いくつかのポスターは、コンピュータ上のランダム関数は真にランダムではなく疑似ランダムであり、アルゴリズムとシードを知っていればそれらは完全に予測可能であると指摘しています。これは事実ですが、ほとんどの場合完全に無関係です。私がカードのデッキをシャッフルしてから一度に一枚ずつ裏返す場合、これはランダムなシリーズになるはずです。誰かがカードを覗くと、結果は完全に予測可能になりますが、ほとんどのランダム性の定義では、ランダム性が低下することはありません。シリーズがランダム性の統計テストに合格した場合、私がカードを覗いたという事実はその事実を変えることはありません。実際には、私たちがあなたの次のカードを推測する能力について多額の金を賭けているならば、あなたがカードを覗いたという事実は非常に関連性があります。システムのパフォーマンスをテストするために当社のWebサイトへの訪問者のメニュー選択をシミュレートするためにシリーズを使用している場合、あなたが覗いたという事実はまったく違いを生じません。 (この知識を利用するようにプログラムを変更しない限り)
EDIT
Monty Hall問題に対する私の回答をコメントにすることはできないと思うので、回答を更新します。
Belisariusのリンクを読んでいない人のために、それの要旨は次のとおりです。ゲームショーの競技者には3つのドアの選択肢があります。 1つの後ろには貴重な賞があり、他の後ろには価値のないものがあります。彼はドア#1を選びます。勝者か敗者かを明らかにする前に、ホストはドア#3を開いてそれが敗者であることを明らかにします。それから彼は競技者にドア#2に切り替える機会を与えます。競技者はこれをするべきかどうか?
答えは、多くの人々の直感を害しますが、彼が切り替えるべきだということです。彼の最初のピックが勝者であった確率は1/3で、他のドアが勝者である確率は2/3です。私の最初の直感は、他の多くの人々のそれと一緒になって、切り替えによる利益がないだろうということで、オッズは50:50に変更されたばかりです。
結局、ホストが負けたドアを開いた直後に誰かがテレビのスイッチを入れたとします。その人は2つの残りの閉じられたドアを見るでしょう。彼がゲームの性質を知っていると仮定すると、彼は各ドアが賞を隠しているという1/2のチャンスがあると言うでしょう。競技者のオッズが1/3:2/3であるのに、視聴者のオッズを1/2:1/2にするにはどうすればよいですか。
私は直感を形にするためにこのことを本当に考えなければなりませんでした。これを理解するために、このような問題の確率について話をするとき、利用可能な情報が与えられたときに割り当てる確率を意味することを理解してください。賞品をドア#1の後ろに置いたクルーのメンバーにとって、賞品がドア#1の後ろにある確率は100%で、他の2つのドアのどちらかの後ろにいる確率はゼロです。
乗組員のオッズは競技者のオッズとは異なります。なぜなら、彼は競技者にはわからないこと、つまりどのドアに賞を入れたのかを知っているからです。同様に、コンテンツのオッズは視聴者のオッズとは異なります。視聴者にはわからないこと、つまりどちらのドアを最初に選んだのかを知っているからです。どのドアを開くかのホストの選択はランダムではないので、これは無関係ではありません。彼は競技者が選んだドアを開けないでしょう、そして彼は賞を隠すドアを開けません。これらが同じドアであれば、それは彼に2つの選択肢を残します。それらが異なるドアであるならば、それは1つだけを残します。
では、どうやって1/3と2/3を考え出すのでしょうか。競技者が最初にドアを選んだとき、彼は勝者を選ぶ1/3のチャンスがありました。それは明らかだと思います。それは他のドアの1つが勝者であるという2/3のチャンスがあったことを意味します。ホストが彼に追加情報を与えずに切り替えるチャンスを彼に与えた場合、何の利益もないでしょう。繰り返しますが、これは明らかなはずです。しかし、それを調べる1つの方法は、彼が切り替えによって勝つ可能性がある2/3のチャンスがあると言うことです。しかし彼には2つの選択肢があります。そのため、各プレイヤーは2/3を2 = 1/3の確率で勝者になる可能性がありますが、これは元の選択よりも優れています。もちろん、私たちはすでに最終結果を知っていました、これはそれを違う方法で計算するだけです。
しかし今、主催者は、これら二つの選択肢のうちの一つが勝者ではないことを明らかにしています。 2/3の確率で彼が選ばなかったドアが勝者である、彼は今2つの選択肢のうちの1つがそれではないことを知っている。もう一方はそうかもしれません。それで彼は2/3を2で割り算することはもうありません。彼は開いたドアには0を、閉じたドアには2/3を持っています。
偶数が頭と見なされ、奇数が尾と見なされる単純なコインフリップの問題があるとします。論理的な実装は次のとおりです。
Rand() mod 2
十分に大きい分布では、偶数の数は奇数の数と等しくなるはずです。
今少し微調整を考えてみましょう:
Rand() * Rand() mod 2
結果の1つが偶数の場合、全体の結果は偶数になります。考えられる4つの結果(偶数*偶数=偶数、偶数*奇数=偶数、奇数*偶数=偶数、奇数*奇数=奇数)を考えます。さて、十分に大きなディストリビューションでは、答えは75%の時間になるはずです。
私があなただったら私は頭を賭けるでしょう。
このコメントは、ランダム性の数学的性質に関する議論よりも、あなたの方法に基づいたカスタムランダム関数を実装すべきでない理由の説明です。
あなたの乱数の組み合わせがどうなるかについて疑問があるときは、統計理論で学んだ教訓を使うことができます。
OPの状況では、彼はX * X = X ^ 2の結果が何であるかを知りたがっています。ここで、XはUniform [0,1]に沿って分布した確率変数です。 CDFテクニックは、1対1のマッピングにすぎないので使用します。
X〜Uniform [0,1]から、cdfは次のようになります。バツ変換Y < - X ^ 2したがってy = x ^ 2が必要です。逆x(y)を求めます。sqrt(y)= xこれはxをyの関数として与えます。次に、導関数dx/dyを見つけます。d/dy(sqrt(y))= 1 /(2 sqrt(y))
Yの分布は次のように与えられます。fY(y)= fバツ(x(y))| dx/dy | = 1 /(2平方メートル(y))
0 <= x <1、0 <= x ^ 2 <1なので、Yは[0、1)の範囲にあります。 Yのpdfが本当にpdfであるかどうかを確認したい場合は、それをドメイン上で積分します。 0から1まで1 /(2 sqrt(y))を積分します そして確かに、それは1としてポップアップ表示されます。また、上記の関数の形は信じられないほど投稿したもののように見えます。
Xのようなものは1 + X2 + ... + Xn、(ここでX私 〜Uniform [0,1])モーメントが存在する任意の分布に対して有効な中心極限定理に訴えることができます。これが、Z検定が実際に存在する理由です。
結果として生じるpdfを決定するための他の技法は、ヤコビアン変換(これは、cdf技法の一般化バージョンである)およびMGF技法を含む。
編集:明確化として、私はその結果の変換の分布について話していることに注意してください、そのランダムさ。それは実際に別の議論のためです。また、私が実際に導き出したものは(Rand())^ 2用でした。 Rand()* Rand()では、はるかに複雑です。どのような場合でも、種類が一様に分布することはありません。
正確にはわかりませんが、Rand()
は通常Rand()*Rand()
よりランダムです。重要なことは、これがほとんどの用途にとって実際にはそれほど重要ではないということです。
しかし、最初に、彼らは異なる分布を作り出します。 これが問題でなければ問題ありませんが、問題ありません。特定のディストリビューションが必要な場合は、「もっとランダムな」質問全体を無視してください。では、なぜRand()
はもっとランダムなのでしょうか。
Rand()
がもっと乱数である理由(これは非常に一般的な範囲である[0..1]の浮動小数点数乱数を生成しているという仮定の下で)の核心は、2つのFP数を掛けたときです仮数部の多くの情報と一緒に、あなたは最後に情報のいくらかの損失を得ます。 IEEE倍精度浮動小数点数には、[0..1]から一様にランダムに選択された2つのIEEE倍精度浮動小数点数に入っているすべての情報を保持するのに十分なビットがないだけです。もちろん、あなたが(おそらく)その情報を使用するつもりはなかったのでそれほど問題ではありませんが、損失は本物です。どのディストリビューションを作成するか(つまり、組み合わせを実行するために使用する操作)も、実際には関係ありません。これらの各乱数には(最高で)52ビットのランダム情報があります。つまり、IEEE doubleが保持できる量です。2つ以上を1つに結合した場合でも、52ビットまでのランダム情報しか得られません。
乱数のほとんどの用途では、乱数ソースで実際に利用可能な限りの乱数に近いものでさえ使用していません。良いPRNGを手に入れて、それについてあまり心配しないでください。 (「良さ」のレベルは、それを使っていることによって異なります。モンテカルロシミュレーションや暗号化を行うときは注意が必要ですが、それ以外の場合は通常より速いので標準のPRNGを使用できます。 。)
浮動乱数は、一般に、ゼロから特定の範囲までの整数を生成するアルゴリズムに基づいています。そのため、Rand()* Rand()を使用すると、本質的にはint_Rand()* int_Rand()/ Rand_max ^ 2となります。つまり、素数/ Rand_max ^ 2は除外します。
それはランダム化された分布を大きく変えます。
Rand()は、ほとんどのシステムで一様に分散されており、正しくシードされていると予測が困難です。あなたがそれについて数学をする特別な理由がない限り(すなわち、必要な曲線に分布を形づくる)それを使用してください。
乗算する数は、コンピュータアーキテクチャによっては、より狭い範囲のソリューションになります。
コンピュータのディスプレイに16桁のRand()
が表示されている場合、0.1234567890123に2番目のRand()
を掛けた0.1234567890123とすると、0.0152415となるでしょう。
これらの分布のほとんどは、乱数を制限または正規化する必要があるために発生します。
割り当てられた変数型のメモリサイズの制約内に収まるように、すべて正であるように正規化します。
言い換えれば、私たちは0とXの間のランダムな呼び出しを制限しなければならないので(Xは私たちの変数のサイズ制限である)、私たちは0とXの間の "ランダムな"数のグループを持つでしょう。
乱数を別の乱数に追加すると、合計は0から2Xの間のどこかになります。エッジポイントから値がずれてしまいます(2つの小さい数値と2つの大きい数値を一緒に追加する確率は非常に小さい場合)。広い範囲にわたって2つの乱数があります。
あなたがゼロに近い数を持っていて、あなたがそれが0から確実に大きくなり、離れていく別の乱数でそれを追加する場合を考えてください(これは2つの大きな数を持つことはまずないでしょう) (Xに近い数値)Random関数によって2回返されます。
今、あなたが負の数と正の数(ゼロ軸を横切って等しく広がる)でランダムな方法を設定しようとするならば、これはもはやそうではないでしょう。
例えばRandomReal({-x, x}, 50000, .01)
と言うと、あなたはマイナスのプラス側に一様な数の分布を得るでしょう、そしてあなたが一緒に乱数を加えることになっていたらそれらはそれらの「ランダム性」を維持するでしょう。
さて、マイナスからプラスのスパンでRandom() * Random()
がどうなるのかわからないのですが…これは興味深いグラフになるでしょう…しかし、今すぐコードを書くことに戻らなければなりません。 :-P
ランダムもっとのようなものはありません。ランダムかそうでないかのどちらかです。ランダムは「予測が難しい」という意味です。それは非決定論的という意味ではありません。 random()とrandom()* random()はどちらも、random()がrandomであれば等しくランダムです。ランダム性に関する限り、分布は無関係です。不均一な分布が発生した場合、それは単にいくつかの値が他のものよりもありそうであることを意味します。それらはまだ予測不可能です。
擬似乱数性が関係しているので、数は非常に決定的です。ただし、確率モデルやシミュレーションでは、擬似乱数で十分であることがよくあります。疑似乱数発生器を複雑にしても分析が困難になることはよく知られています。ランダム性を改善することはほとんどありません。それはしばしば統計的検定に失敗する原因となります。
乱数の望ましい性質は重要です:再現性と再現性、統計的なランダムさ、(通常)一様分布、そして大きな周期は数個です。
乱数の変換について:誰かが言ったように、一様分布の2つ以上の和は正規分布になります。これは加法的中心極限定理です。すべての配布が独立していて同一である限り、ソース配布に関係なく適用されます。 乗法的中心極限定理は、2つ以上の独立したインデント分布のランダム変数の積が対数正規であると言います。他の人が作成したグラフは指数関数的に見えますが、実際は対数正規分布です。そのため、random()* random()は対数正規分布です(ただし、数値は同じストリームから取得されるため独立していない場合もあります)。これは用途によっては望ましいかもしれません。ただし、通常は1つの乱数を生成し、それを対数正規分布数に変換する方が適切です。 Random()* random()は分析が難しいかもしれません。
詳細については、www.performorama.orgで私の本を参照してください。この本は作成中ですが、関連資料はそこにあります。章番号とセクション番号は時とともに変わることに注意してください。第8章(確率論) - セクション8.3.1と8.3.3、第10章(乱数)。
コルモゴロフ複雑度 を使用すると、ランダムさに関して2つの数の配列を比較できます。この長さに達する...私は、この種の測定がより理論的な選択肢であることを知っています...
実際に考えてみると、Rand() * Rand()
はRand()
よりlessrandomです。これが理由です。
基本的に、偶数と同じ数の奇数があります。そして、0.04325は奇数であり、0.388は偶数、0.4は偶数、0.15は奇数のように、
つまり、Rand()
にはが偶数または奇数の10進数である可能性があります。
一方、Rand() * Rand()
では、オッズが少し違った形で積み重ねられています。まあ言ってみれば:
double a = Rand();
double b = Rand();
double c = a * b;
a
とb
はどちらも偶数または奇数である確率が50%です。知っています
75%の確率はc
が偶数であることを意味しますが、25%の確率それは奇妙なことに、Rand() * Rand()
の値をRand()
より予測可能にしているので、それほどランダムではありません。
原始多項式を実装する線形フィードバックシフトレジスタ(LFSR)を使用します。
結果は2 ^ nの疑似乱数の列となります。つまり、nがLFSRのビット数である場合、この列では何も繰り返されません。
http://ja.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.co.jp/support/documentation/application_notes/xapp052.pdf
あなたのコンピュータクロックのマイクロ秒に基づく「ランダムな」シードを使うか、あるいはあなたのファイルシステムのいくつかの連続的に変化するデータのmd5結果のサブセットかもしれません。
例えば、32ビットLFSRは与えられたシードから始めて2 ^ 32のユニークな数を順番に生成します(2ではありません)。シーケンスは常に同じ順序になりますが、シードが異なると開始点が(明らかに)異なります。そのため、シーディングの間に繰り返し発生する可能性がある問題が問題にならない場合は、これが適切な方法です。
私は128ビットのLFSRを使ってハードウェアシミュレータでランダムにテストを生成しました。シードは連続的に変化するシステムデータに対するmd 5の結果です。
Rand()
が[0, 1)
の間の数を返すと仮定すると、Rand() * Rand()
が0にバイアスされることは明らかです。これは、x
に[0, 1)
x
より小さい数になります。これが10000 more乱数の分布です:
google.charts.load("current", { packages: ["corechart"] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var i;
var randomNumbers = [];
for (i = 0; i < 10000; i++) {
randomNumbers.Push(Math.random() * Math.random());
}
var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
var data = new google.visualization.DataTable();
data.addColumn("number", "Value");
randomNumbers.forEach(function(randomNumber) {
data.addRow([randomNumber]);
});
chart.draw(data, {
title: randomNumbers.length + " Rand() * Rand() values between [0, 1)",
legend: { position: "none" }
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart-1" style="height: 500px">Generating chart...</div>
Rand()
が[x, y]
の間の整数を返す場合、次の分布があります。奇数と偶数の値の数に注意してください。
google.charts.load("current", { packages: ["corechart"] });
google.charts.setOnLoadCallback(drawChart);
document.querySelector("#draw-chart").addEventListener("click", drawChart);
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function drawChart() {
var min = Number(document.querySelector("#Rand-min").value);
var max = Number(document.querySelector("#Rand-max").value);
if (min >= max) {
return;
}
var i;
var randomNumbers = [];
for (i = 0; i < 10000; i++) {
randomNumbers.Push(randomInt(min, max) * randomInt(min, max));
}
var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
var data = new google.visualization.DataTable();
data.addColumn("number", "Value");
randomNumbers.forEach(function(randomNumber) {
data.addRow([randomNumber]);
});
chart.draw(data, {
title: randomNumbers.length + " Rand() * Rand() values between [" + min + ", " + max + "]",
legend: { position: "none" },
histogram: { bucketSize: 1 }
});
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<input type="number" id="Rand-min" value="0" min="0" max="10">
<input type="number" id="Rand-max" value="9" min="0" max="10">
<input type="button" id="draw-chart" value="Apply">
<div id="chart-1" style="height: 500px">Generating chart...</div>