私はこれの周りに頭を得ることができません、よりランダムですか?
rand()
または:
rand() * rand()
私はそれが本当の頭の体操を見つけています、あなたは私を手伝っていただけませんか?
編集:
直感的には、数学的な答えはランダムであることがわかりますが、「乱数アルゴリズムを2回実行」すると、2つを掛け合わせると、単に行うよりもランダムなものが作成されると思います。一度。
私はこれの周りに頭を得ることができません、よりランダムですか?
rand()
または:
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 *ランダム()が均一に分布されています。
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]]
中心極限定理の状態の和ことランダム()になる傾向がある正規分布用語増加として。
たった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つの画像に示されている確率分布はアーウィンホール分布として知られていることをコメントで指摘してくれたThomas Ahleに感謝します。
rand()+rand()
、あなたはファットセンターを持つ「2d6」タイプのディストリビューションになってしまうでしょう。
どちらの方法もランダムだと思いますが、私のgutfeelはrand() * rand()
より多くのゼロをシードするため、ランダムではないと言っています。すぐに1のようにrand()
あり0
、合計はなり0
どちらも「よりランダム」ではありません。
rand()
疑似ランダムシード(通常は常に変化する現在時刻に基づく)に基づいて、予測可能な数のセットを生成します。シーケンス内の2つの連続した数値を乗算すると、異なるが等しく予測可能な数値のシーケンスが生成されます。
これが衝突を減らすかどうかに対処すると、答えはノーです。実際には、2つの数値を乗算する効果により、衝突が増加し0 < n < 1
ます。結果はより小さな部分になり、スペクトルの下端に向かって結果にバイアスを引き起こします。
いくつかのさらなる説明。以下では、「予測不可能」および「ランダム」は、誰かが前の数字に基づいて次の数字が何になるかを推測する能力を指します。神託。
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, ...
どちらの方法でも、常に同じシードに対して同じ数のリストが生成されるため、オラクルは等しく予測できます。しかし、2つの呼び出しを掛けた結果を見ると0.3
、元のシーケンスの分布はまあまあですが、すべてが不足していることがわかります。2つの分数を乗算する効果のため、数値は偏っています。結果の数値は常に小さいため、予測不可能であるにもかかわらず、衝突である可能性がはるかに高くなります。
rand()+rand()+rand()...
ランダムさがますます少なくなることに注意してください(ランダムとは、均一に分散することを意味します)。
rand()
実際にランダムであることを信頼し、ランダム性を「強化」しようとしないでください。シードを複数回設定しないでください。それ自体がセミランダムである限り、個々のシードは完全に問題ありません。私が見た多くの実装では、UNIXエポックをシードとして使用しています。これは1秒ごとに変化し、変化するたびに一意です。
ポイントを説明するための単純化し過ぎ。
ランダム関数が0
またはのみを出力するとします1
。
random()
の1つですが(0,1)
、のrandom()*random()
1つです(0,0,0,1)
0
2番目のケースでaを取得するチャンスは、を取得するチャンスとまったく同じではないことがはっきりとわかります1
。
私が最初にこの答えを投稿するとき、私はそれを読んだ人は一目で違いを理解することが可能ように短いと、それを維持したいrandom()
とrandom()*random()
、私は元の広告litteramの質問に答えるから自分自身を維持することはできません。
どちらがよりランダムですか?
ことでrandom()
、random()*random()
、random()+random()
、(random()+1)/2
またはエントロピーの同じソース(又は擬似乱数発生器の場合に同じ初期状態)を有する固定された結果をもたらさない任意の他の組み合わせ、答えは、彼らがあることであろう均等ランダム(差配布されています)。私たちが見ることができる完璧な例は、クラップスのゲームです。あなたが得る数random(1,6)+random(1,6)
は、7を獲得する可能性が最も高いことを私たちは皆知っていますが、2つのサイコロを振った結果が1を振った結果よりもランダムであることを意味するわけではありません。
ここに簡単な答えがあります。独占を検討してください。2つの6面サイコロ(またはゲーム表記を好む方は2d6)を2つ振り、合計を取ります。最も一般的な結果は7です。これは、7を振る方法が6つあるためです(1,6 2,5 3,4 4,3 5,2および6,1)。一方、2は1、1でのみロール可能です。範囲が同じであっても、2d6のローリングが1d12のローリングとは異なることは簡単です(1d12で1を取得できることを無視して、ポイントは同じままです)。結果を追加するのではなく乗算すると、同様の方法で結果が歪められ、ほとんどの結果が範囲の真ん中に表示されます。外れ値を削減しようとする場合、これは良い方法ですが、分布を均等にするのには役立ちません。
(そして奇妙なことに、ローロールも増加します。ランダム性が0で始まると仮定すると、他のロールが0に変わるため、0でスパイクが表示されます。0と1の間の2つのランダムな数値を検討します)と乗算。いずれかの結果が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()実装には期間があります。つまり、膨大な数の呼び出しの後、シーケンスが繰り返されます。出力のシーケンスはrand() * rand()
半分の時間で繰り返されるため、その意味では「ランダム性が低くなります」。
また、注意深く作成しないと、ランダムな値に対して算術演算を実行すると、ランダムさが少なくなる傾向があります。上記の「rand()
+ rand()
+ rand()
...」(k回など)のポスターでは、実際には値の範囲の平均値のk倍がrand()
返される傾向があります。(これは、その平均について対称的なステップを持つランダムウォークです。)
具体的には、rand()関数が[0,1)の範囲で一様に分布したランダムな実数を返すと仮定します。(はい、この例では無限の精度が許可されます。これにより結果が変わることはありません。)特定の言語を選択しなかったため、言語によって動作が異なる可能性がありますが、次の分析はrand( )。積rand() * rand()
も[0,1)の範囲ですが、もはや均一に分布していません。実際、積は区間[1 / 4,1)と同じように区間[0,1 / 4)にあります。乗算を増やすと、結果がさらにゼロにスキューされます。これにより、結果がより予測可能になります。広いストロークでは、より予測可能==ランダム性が低くなります。
一様にランダムな入力に対するほとんどすべての操作シーケンスは、一様にランダムではなく、予測可能性が向上します。注意してこのプロパティを克服できますが、その場合、算術で時間を無駄にするよりも、実際に必要な範囲で均一に分布した乱数を生成する方が簡単でしょう。
「ランダム」と「よりランダム」は、どちらのゼロをゼロにするかを尋ねるようなものです。
この場合、rand
はPRNGであるため、完全にランダムではありません。(実際には、シードが既知であればかなり予測可能です)。それを別の値で乗算すると、多かれ少なかれランダムになります。
真の暗号タイプのRNGは実際にはランダムです。また、あらゆる種類の関数で値を実行しても、エントロピーを追加することはできず、エントロピーを削除してランダムでなくなる可能性が非常に高くなります。
あなたが探している概念は「エントロピー」、つまりビット列の無秩序の「程度」です。このアイデアは、「最大エントロピー」の概念の観点から理解するのが最も簡単です。
最大のエントロピーを持つビットの文字列のおおよその定義は、短いビットの文字列で正確に表現できないことです(つまり、何らかのアルゴリズムを使用して、小さい文字列を元の文字列に戻す)。
ランダム性に対する最大エントロピーの関連性は、数値を「ランダムに」選択すると、ビットストリングが最大エントロピーに近い数値を選択する、つまり圧縮できないという事実に由来します。これは、「ランダムな」数の特徴を理解するのに最適です。
したがって、2つのランダムサンプルからランダムに「2倍」の乱数を作成する場合は、2つのビット文字列を連結します。実際には、サンプルを倍長の単語の上半分と下半分に詰め込むだけです。
もっと実際的な注意として、もしあなたが気難しいrand()を使っている場合は、いくつかのサンプルを一緒にxorするのに役立つ場合があります---しかし、本当に壊れている場合は、その手順でも役に立たないでしょう。
4
またはバイナリをゼロビット0100
に圧縮できます。解凍プログラムは単に「4」を返します。それよりランダムになることはありません。dilbertの問題は、それをゼロビットに圧縮できるかどうかがわからないことです(常に「9」を返すことで解凍)。8も返す可能性があるので、1ビットに圧縮できます。解凍:0-> 9、1-> 8。ランダムビットは1つです。
受け入れられた答えはかなり美しいですが、あなたの質問に答える別の方法があります。PachydermPuncherの回答はすでにこの代替アプローチを採用しており、私はそれを少し拡張するつもりです。
情報理論について考える最も簡単な方法は、情報の最小単位である1ビットの観点からです。
C標準ライブラリでrand()
は、0からの範囲の整数を返しRAND_MAX
ます。これは、プラットフォームに応じて異なる方法で定義される制限です。仮定するはRAND_MAX
として定義することを起こる2^n - 1
場合n
(これは、Microsoftの実装でケースであることを起こるいくつかの整数であるn
15です)。次に、優れた実装はn
情報のビットを返すと言います。
rand()
コインを裏返して1ビットの値を見つけ、それが15ビットのバッチになるまで繰り返すことにより、乱数を作成すると想像してください。次に、ビットは独立しています(1つのビットの値は、同じバッチ内の他のビットが特定の値を持つ可能性に影響しません)。したがって、個別に考慮される各ビットは、0から1までの乱数のようなものであり、その範囲全体で「均等に分散」されます(1として0になる可能性が高い)。
ビットの独立性により、ビットのバッチによって表される数もその範囲全体に均等に分散されます。これは直感的に明らかです。15ビットの場合、許容範囲は2^15 - 1
0〜= 32767です。その範囲内のすべての数値は、次のような一意のビットパターンです。
010110101110010
また、ビットが独立している場合、他のどのパターンよりもパターンが発生する可能性は高くありません。したがって、範囲内のすべての可能性のある数値は等しく可能性があります。そして、その逆は真です:rand()
が均等に分布した整数を生成する場合、それらの数値は独立したビットで構成されます。
したがってrand()
、ビットを作成するための生産ラインと考えると、ビットを任意のサイズのバッチで提供することができます。サイズが気に入らない場合は、バッチを個別のビットに分割し、それらを好きな量に戻します(ただし、2の累乗ではない特定の範囲が必要な場合は、数値を縮小する必要があります) 、そしてこれを行う最も簡単な方法は、浮動小数点に変換することです)。
元の提案に戻り、15のバッチから30のバッチにrand()
移動し、最初の数を求め、15桁だけビットシフトしてから、別の数rand()
を追加するとします。これは、2つの呼び出しをrand()
均等な分布を乱すことなく組み合わせる方法です。情報のビットを配置する場所の間に重複がないため、単純に機能します。
これはrand()
、定数を掛けての範囲を「ストレッチ」することとは大きく異なります。たとえば、範囲を2倍にしたい場合rand()
、2を掛けることができますが、今では偶数だけが得られ、奇数は得られません。これは正確にスムーズな分布ではなく、アプリケーションによっては重大な問題になる可能性があります。たとえば、ルーレットのようなゲームで奇数/偶数のベットが許可されている可能性があります。(ビットの観点から考えると、直感的にその間違いを避けることができます。2を掛けることは、ビットを左に1桁シフト(より大きな意味)し、ギャップをゼロで埋めることと同じであることを理解しているからです。したがって、明らかに情報量は同じです-少し移動しただけです。)
このような数値範囲のギャップは、浮動小数点数のアプリケーションでは把握できません。浮動小数点範囲には、本質的にまったく表現できないギャップがあるためです。2つの表現可能な浮動小数点の間のギャップには、無限数の欠落した実数が存在します。ポイント数!とにかく、ギャップのある生活をすることを学ばなければなりません。
他の人が警告したように、特に数学者は実数の魅力に抵抗できないので、直感はこの領域で危険です。
しかし、少なくともビットの観点から考えると、直感で少し先に進むかもしれません。ビットは本当に簡単です- コンピュータでさえそれを理解することができます。
他の人が言ったように、簡単な短い答えは次のとおりです。いいえ、それはよりランダムではありませんが、分布を変更します。
あなたがサイコロゲームをしていたとしましょう。完全にランダムなランダムサイコロがいくつかあります。各サイコロが振る前に、最初に2つのサイコロをボウルに入れて振り、サイコロの1つをランダムに選んだ後、そのサイコロを振った場合、サイコロは「よりランダム」になりますか?明らかに違いはありません。両方のサイコロが乱数を与える場合、2つのサイコロの1つをランダムに選択しても違いはありません。どちらの方法でも、1〜6の乱数が得られ、十分な数のロールに均等に分配されます。
サイコロが公平ではないのではないかと疑われる場合、実際にはそのような手順が役立つと思います。たとえば、ダイスのバランスがわずかに悪いため、1が1/6の時間よりも多く1を与える傾向があり、別のダイスが6を異常に頻繁に与える傾向がある場合、2つをランダムに選択するとバイアスが不明瞭になる傾向があります。(この場合でも、1と6は2、3、4、および5を超えて表示されますが、まあ、不均衡の性質によっては異なると思います。)
ランダム性には多くの定義があります。ランダムな系列の1つの定義は、ランダムなプロセスによって生成される一連の数値であることです。この定義では、フェアダイスを5回振り、2、4、3、2、5の数字を取得すると、ランダムシリーズになります。その後、同じフェアダイをさらに5回振り、1、1、1、1、1、1を取得すると、ランダムシリーズになります。
コンピュータ上のランダム関数は真にランダムではなく疑似ランダムであり、アルゴリズムとシードを知っていれば完全に予測可能であることをいくつかのポスターが指摘しました。これは事実ですが、ほとんどの場合完全に無関係です。カードのデッキをシャッフルしてから一度に1枚ずつ裏返すと、これはランダムなシリーズになります。誰かがカードをのぞくと、結果は完全に予測可能になりますが、ランダム性のほとんどの定義では、これによりランダム性が低下することはありません。シリーズがランダム性の統計的テストに合格した場合、カードをのぞいても、その事実は変わりません。実際には、次のカードを推測するあなたの能力に多額のお金を賭けている場合、あなたがカードを覗いたという事実は非常に関連性があります。システムのパフォーマンスをテストするために、シリーズを使用してWebサイトへの訪問者のメニューピックをシミュレートしている場合、ピークしたという事実はまったく違いがありません。(この知識を利用するためにプログラムを変更しない限り。)
編集する
モンティホール問題への私のコメントをコメントに入れることができなかったと思うので、答えを更新します。
ベリサリウスのリンクを読んでいない人にとっては、その要点は次のとおりです。ゲームショーの出場者には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をどのように思いつくのでしょうか。競技者が最初にドアを選んだとき、彼は勝者を選ぶ確率の3分の1を持っていました。それは明らかだと思います。つまり、他のドアの1つが勝者である可能性が2/3ありました。ホストが彼に追加情報を提供せずに切り替える機会を与えた場合、利益は得られません。繰り返しますが、これは明らかです。しかし、それを見る1つの方法は、彼が切り替えて勝つ可能性が2/3あると言うことです。しかし、彼には2つの選択肢があります。したがって、それぞれの勝者になる確率は2/3を2で割った値= 1/3であり、これは元のピックと同じです。もちろん、最終的な結果はすでにわかっていますが、これは別の方法で計算するだけです。
しかし、ホストはこれら2つの選択肢の1つが勝者ではないことを明らかにしました。したがって、彼が選択しなかったドアが勝者である2/3の確率で、彼は2つの選択肢のうちの1つがそうではないことを知っています。他はそうかもしれないしそうでないかもしれません。つまり、2で除算された2/3はもうありません。開いたドアはゼロで、閉じたドアは2/3です。
偶数が表と見なされ、奇数が裏と見なされる単純なコインフリップ問題があるとします。論理的な実装は次のとおりです。
rand() mod 2
十分に大きな分布では、偶数の数は奇数の数と等しくなければなりません。
ここで、わずかな調整を検討します。
rand() * rand() mod 2
結果のいずれかが偶数の場合、結果全体が均一になります。4つの可能な結果を考慮してください(偶数*偶数=偶数、偶数*奇数=偶数、奇数*偶数=偶数、奇数*奇数=奇数)。さて、十分に大きなディストリビューションでは、答えは75%の時間になるはずです。
私があなただったら、私は頭を賭けます。
このコメントは、ランダム性の数学的特性に関する議論よりも、メソッドに基づいてカスタムランダム関数を実装してはならない理由の説明です。
rand()%2
あまりランダムではないかもしれません。これは実際には低ビットのランダム性に依存し、一部のPRNGはそのようにはあまり良くありません。(もちろん、一部の言語では浮動小数点の結果が得られるため、rand()
そのような方法でまったく実行できません...)
乱数の組み合わせがどうなるか疑問がある場合は、統計理論で学んだ教訓を利用できます。
OPの状況で、彼はX * X = X ^ 2(XはUniform [0,1]に沿って分布する確率変数)の結果を知りたいと考えています。CDF手法は1対1のマッピングなので、使用します。
X〜Uniform [0,1] なので、cdfは次のようになります。f X(x)= 1変換Y <-X ^ 2が必要なので、y = x ^ 2逆x(y)を求めます:sqrt(y)= xこれにより、xがyの関数として得られます。次に、導関数dx / dyを見つけます:d / dy(sqrt(y))= 1 /(2 sqrt(y))
Yの分布は次のように与えられます:f Y(y)= f X(x(y))| dx / dy | = 1 /(2 sqrt(y))
まだ完了していません。Yのドメインを取得する必要があります。0<= x <1、0 <= x ^ 2 <1なので、Yは[0、1)の範囲にあります。Yのpdfが実際にpdfであるかどうかを確認する場合は、ドメイン全体で積分します。1/(2 sqrt(y))を0から1に統合すると、実際には1としてポップアップします。また、言った機能は善意の投稿者のように見えます。
Xのようなものについては1 + X 2 + ... + X nは、(ここで、X I〜制服[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ビットのランダム情報が含まれています。
乱数のほとんどの使用は、ランダムソースで実際に使用できるほどのランダム性にさえ使用しません。良いPRNGを入手して、あまり心配しないでください。(「良さ」のレベルは、それを使って何をしているのかによって異なります。モンテカルロシミュレーションまたは暗号化を行うときは注意する必要がありますが、それ以外の場合は通常、標準のPRNGの方がはるかに高速であるため、おそらくそれを使用できます。)
浮動乱数は、一般に、ゼロと特定の範囲の間の整数を生成するアルゴリズムに基づいています。したがって、rand()* rand()を使用することで、本質的にはint_rand()* int_rand()/ rand_max ^ 2と言っています。つまり、素数/ rand_max ^ 2を除外しています。
これにより、ランダム化された分布が大幅に変化します。
rand()は、ほとんどのシステムで均一に分散されており、適切にシードされていると予測が困難です。計算を行う特別な理由がない限り、それを使用してください(つまり、分布を必要な曲線に整形します)。
rand()*rand()
の結果空間よりも小さいですrand()
。私の投票を取得します...
これらの分布のほとんどは、乱数を制限または正規化する必要があるために発生します。
これをすべて正に正規化し、範囲内に収まり、割り当てられた変数タイプのメモリサイズの制約内に収まるようにします。
言い換えると、ランダムな呼び出しを0とXの間で制限する必要があるため(Xは変数のサイズ制限です)、0とXの間で「ランダムな」数値のグループができます。
ここで、乱数を別の乱数に追加すると、合計は0と2Xの間のどこかになります...これにより、値がエッジポイントから遠ざけられます(2つの小さな数値と2つの大きな数値を一緒に追加する確率は、広い範囲に2つの乱数がある)。
ゼロに近い数値があり、それを別の乱数に追加すると、確かに大きくなり、0から遠ざかる場合を考えてください(これは大きな数に当てはまり、2つの大きな数がありそうにありません) (Xに近い数値)ランダム関数によって2回返されます。
ここで、負の数と正の数(ゼロ軸を横切って均等に広がる)を使用してランダムメソッドをセットアップする場合、これは当てはまりません。
たとえばRandomReal({-x, x}, 50000, .01)
、負の数と正の数の数の分布が均一になるとし、乱数を加算すると、それらは「ランダムさ」を維持します。
今、私はRandom() * Random()
負から正のスパンで何が起こるかわかりません...それは見るのに興味深いグラフになるでしょう...しかし、今コードを書くことに戻らなければなりません。:-P
これ以上ランダムなものはありません。ランダムかそうでないかのどちらかです。ランダムとは、「予測が難しい」ことを意味します。非決定的という意味ではありません。random()がランダムの場合、random()とrandom()* random()はどちらも等しくランダムです。分布がランダムである限り、関係はありません。不均一な分布が発生した場合、それは単に一部の値が他の値よりも可能性が高いことを意味します。それらはまだ予測できません。
疑似ランダム性が関係しているため、数値は非常に確定的です。ただし、確率モデルとシミュレーションでは、多くの場合、擬似ランダム性で十分です。疑似乱数ジェネレータを複雑にしても、分析が困難になることはよく知られています。ランダム性を改善することはほとんどありません。多くの場合、統計的検定に失敗します。
乱数の望ましい特性は重要です:再現性と再現性、統計的ランダム性、(通常)均一に分布し、長い周期は少数です。
乱数の変換について:誰かが言ったように、2つ以上の均一に分散された合計は正規分布になります。これは、追加の中心極限定理です。すべてのディストリビューションが独立しており、同一である限り、ソースディストリビューションに関係なく適用されます。の乗法中心極限定理は、2つ以上の独立して同一分布の確率変数の積が対数正規であることを示しています。他の誰かが作成したグラフは指数関数的に見えますが、実際には対数正規です。したがって、random()* random()は対数正規分布です(ただし、同じストリームから数値が取得されるため、独立していない場合があります)。これは、一部のアプリケーションでは望ましい場合があります。ただし、通常は1つの乱数を生成し、それを対数正規分布数に変換することをお勧めします。Random()* random()は分析が難しい場合があります。
詳細については、www.performorama.orgにある私の本を参照してください。この本は作成中ですが、関連資料があります。章とセクションの番号は、時間の経過とともに変化する可能性があることに注意してください。第8章(確率論)-セクション8.3.1および8.3.3、第10章(乱数)。
実際に考えると、それrand() * rand()
はほどランダムではありませんrand()
。これが理由です。
基本的に、奇数は偶数と同じ数です。そして、0.04325は奇数、0.388は偶数、0.4は偶数、0.15は奇数と言って、
その手段rand()
有する偶数または奇数の小数であることの等しいチャンス。
一方、rand() * rand()
オッズは少し異なって積み上げられていますか?まあ言ってみれば:
double a = rand();
double b = rand();
double c = a * b;
a
そして、b
の両方が偶数か奇数であることの50%のprecentのチャンスがあります。知っています
手段はその75%の確率でc
いる間だけ、でもある25%の確率でそれはの価値作り、奇妙だrand() * rand()
より予測可能なrand()
ため、少ないランダムに、。
rand()
通常、0と1の間の数を与えます。それが偶数か奇数かについて話すことは意味がありますか?
0.2*0.2=0.04
、このアプローチに根本的な欠陥があることを示唆しています。2つのdoubleの53ビットを乗算すると、結果に約100ビットが含まれます。ただし、これらのビットの後半は破棄されます。したがって、最下位ビットとして1を使用して2つのdoubleを取る場合、それらの積の最下位ビットについては何も言えません。
rand()
の定義は、分布に意味のある「偶数」と「奇数」の定義と同じであると想定しました。のrand()*rand()
。そうでない場合、この引数は失敗します。これは整数にも当てはまりますが、これらは整数ではありません。
原始多項式を実装する線形フィードバックシフトレジスタ(LFSR)を使用します。
結果は2 ^ nの疑似乱数のシーケンスになります。つまり、nがLFSRのビット数であるシーケンスで繰り返されるものはありません。均一な分布になります。
http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
コンピュータクロックのマイクロ秒に基づいた「ランダムな」シードを使用するか、ファイルシステムの継続的に変化するデータでmd5の結果のサブセットを使用します。
たとえば、32ビットのLFSRは、指定されたシードで始まる2 ^ 32の一意の番号を(2とは異なり)順番に生成します。シーケンスは常に同じ順序になりますが、異なるシードでは開始点が(明らかに)異なります。したがって、シーディングの間のシーケンスの繰り返しが問題にならない場合は、これが適切な選択かもしれません。
128ビットLFSRを使用して、連続的に変化するシステムデータのmd5結果であるシードを使用して、ハードウェアシミュレーターでランダムテストを生成しました。
がrand()
その間の数値を返すと仮定すると、[0, 1)
それがrand() * rand()
0にバイアスされることは明らかです。これは、x
その間の数値を掛けると、[0, 1)
より小さい数値になるためx
です。次に、10000個以上の乱数の分布を示します。
のrand()
間の整数を返す場合[x, y]
、次の分布になります。奇数と偶数の値の数に注意してください。
わかりました。それで、乱数ジェネレータを作成して使用していると言って、他の答えを補完するためにいくつかの値を追加しようとします。
乱数ジェネレーターは、目的に合わせて変更できる複数の特性を持つデバイス(非常に一般的な意味で)です。それらのいくつか(私から)は次のとおりです。
ここでのほとんどの回答では、分布が主な関心事ですが、関数とパラメーターを組み合わせて一致させることにより、一見すると評価が明確でない場合があるいくつかの特性が異なる乱数を生成する新しい方法を作成します。
2つの乱数の合計が必ずしもランダムではないことを示すのは簡単です。あなたが6面サイコロを持っていると想像してください。それぞれの数字が出現する確率は1/6です。今、あなたが2つのサイコロを持っていて、結果を合計したとしましょう。これらの合計の分布は1/12ではありません。どうして?特定の数値が他の数値よりも多く表示されるためです。それらの複数のパーティションがあります。たとえば、数値2は1 + 1のみの合計ですが、7は3 + 4または4 + 3または5 + 2などによって形成される可能性があるため、次の可能性が高くなります。
したがって、変換を適用する場合、この場合はランダム関数に追加しても、それがランダムになることはなく、必ずしもランダム性が保持されません。上記のダイスの場合、分布は7に歪んでいるため、ランダム性は低くなります。
他の人がすでに指摘したように、私たちの誰もが彼の頭の中のランダムさの彼自身の絵を持っているので、この質問に答えることは難しいです。
だからこそ、少し時間をかけてこのサイトを読んで、ランダム性をよりよく理解することを強くお勧めします。
本当の質問に戻るために。この用語では、多かれ少なかれランダムではありません。
どちらもランダムに表示されます。
どちらの場合も-ちょうどランド()またはランド()*ランド() -状況は同じです:シーケンスが数字の数十億の後に繰り返されます(!) 。彼はシーケンス全体を知らないので、観察者にはランダムに見えますが、コンピューターには真のランダムソースがないため、ランダム性を生成することもできません。
例:天気はランダムですか? 天気がランダムかどうかを判断するのに十分なセンサーや知識がありません。
答えはそれによって異なりますが、rand()* rand()がrand()よりもランダムであることを願っていますが、次のようになります。
さて、上記のいずれかをチェックする場合は、単純な「rand()」を使用することをお勧めします。コードが読みやすくなるので(なぜこれを書いたのかを自問しないでください... 2秒以上)、保守が簡単です(rand関数をsuper_randに置き換えたい場合)。
より良いランダムが必要な場合は、十分なノイズ(静的な無線)を提供する任意のソースからストリーミングすることをお勧めしますrand()
。シンプルなもので十分です。