9

サイトを検索しましたが、探していたものが正確に見つかりませんでした...正規分布から離散乱数を生成したかったのです。

たとえば、最小値が 4、最大値が 10、平均値が 7 の範囲がある場合、その範囲内の数値を返す必要があるコードまたは関数呼び出し (Objective C を推奨) を指定します。当然のことながら、正規分布により、より多くの数値が平均 7 を中心に返されます。

2 番目の例として、ベル カーブ/分布を一方の端に向かって歪ませることはできますか? 最小で 4、最大で 10 の範囲の乱数を生成する必要があり、返される数値の大部分が 8 を中心に、歪んだベル カーブに基づいて自然に減少するようにしたいとします。

どんな助けでも大歓迎です....

アンソニー

4

5 に答える 5

4

これは何のために必要ですか?クラップスプレイヤーのやり方でできますか?

2 から 5 までの範囲 (もちろん、5 を含む) のランダムな整数を 2 つ生成し、それらを加算します。または、コイン (0,1) を 6 回投げて、結果に 4 を加えます。

複数のサイコロを合計すると、正規分布 (「ベル カーブ」) が生成されますが、ハイスローまたはロースローを排除すると、さまざまな方法で分布を歪めることができます。

重要なのは、離散数を使用することです (それが整数であることを願っています)。複数のサイコロを投げると、正規分布が生成されることで有名です。実際、それが学校でガウス曲線を初めて紹介された方法だと思います。


もちろん、投げる回数が多いほど、ベル カーブに近づきます。1 つのサイコロを振ると、平らな線が得られます。2 つのサイコロを転がすと、ベルにそれほど近くないランプの上下が作成されます。コイン投げを 6 回行うと、距離が近づきます。

だからこれを考慮してください...

あなたの質問を正しく理解できれば、考えられる結果は 7 つだけです。整数 (4、5、6、7、8、9、10) です。7 つの確率の配列を設定して、好みの分布に近づけることができます。

于 2009-07-29T00:31:46.913 に答える
1

多くのフレームワークとライブラリにはこれが組み込まれています。

また、TokenMacGuyが言ったように、正規分布は、定義された間隔ではなく、平均μと標準偏差σの2つのパラメーターによって特徴付けられます。これらの両方のパラメーターを使用すると、分布の特定の分位数を特定の間隔に制限できるため、すべてのポイントの95%がその間隔に含まれます。ただし、(-∞、∞)以外の間隔に完全に制限することはできません。

均一なランダム値から正規分布値を生成する方法はいくつかあります(これは、ほとんどのランダムまたは疑似乱数ジェネレーターが生成しているものです。

  • Box-Muller変換は、計算が正確に高速ではありませんが、おそらく最も簡単です。必要な数字の数にもよりますが、それで十分ですが、間違いなく非常に簡単に書くことができます。

  • もう1つのオプションは、通常はより高速なマルサグリア法です1

  • 3番目の方法は、ジッグラトアルゴリズムです。これは、計算はかなり高速ですが、プログラミングははるかに複雑です。ただし、実際に多くの乱数を使用するアプリケーションでは、これが最良の選択である可能性があります。

ただし、一般的なアドバイスとして、通常の分散乱数をすでに生成しているライブラリにアクセスできる場合は、自分で記述しないでください。


分布を歪めるには、通常の正規分布を使用し、曲線の片側に適切にμσを選択してから、必要な平均のどちら側にポイントが落ちたかを判断し、目的の分布に合うように適切にストレッチします。


整数のみを生成する場合は、乱数が目的の間隔内にある場合は最も近い整数に丸め、そうでない場合は拒否することをお勧めします(新しい乱数を描画します)。このようにして、分布を人為的に歪めることはありません(たとえば、値をそれぞれ4または10にクランプする場合など)。


1意図的に悪い乱数ジェネレーター(はい、RANDUよりも悪い)を使用したテストで、極座標法では無限ループが発生し、すべてのサンプルが拒否されることに気付きました。ただし、通常の統計的期待値を満たす乱数では発生しません。

于 2009-07-29T00:15:23.333 に答える
1

Dan Dyer と Jay はまさにその通りです。本当に必要なのは、正規分布ではなく、二項分布です。二項分布の形状は正規分布によく似ていますが、離散的で有界ですが、正規分布は連続的で有界です。

Jay のコードは、試行が 6 回で、試行ごとの成功確率が 50% の二項分布を生成します。分布を「歪ませる」場合は、確率が 50% 以外になるように、n に 1 を追加するかどうかを決定する行を変更するだけです。

于 2009-08-12T04:49:30.063 に答える
1

はい、洗練された数学的解決策がありますが、「シンプルだが実用的」であるという点では、Nosredna のコメントに同意します。シンプルな Java ソリューションの場合:

Random random=new Random();
public int bell7()
{
  int n=4;
  for (int x=0;x<6;++x)
    n+=random.nextInt(2);
  return n;
}

Java を使用していない場合、Random.nextInt(n) は 0 から n-1 の間のランダムな整数を返します。残りは、どのプログラミング言語でも見られるものと似ているはずだと思います。

範囲が大きい場合は、nextInt(2) の代わりに大きな数値を使用して、呼び出しの頻度とパフォーマンスの要件に応じて、ループの反復回数を減らします。

于 2009-07-29T16:50:57.683 に答える
1

正規分布は、その端点によって記述されません。通常、それは平均値 (7 であると指定した) とその標準偏差によって表されます。この分布の重要な特徴は、この分布から予想される範囲をはるかに超える値が得られる可能性があることです。

分布から値を取得する通常の方法は、一様分布からランダムな値を生成することです。これは、たとえば で非常に簡単に実行できます。次に、それを累積分布関数rand()の引数として使用します。境界。標準分布の場合、この関数は

F(x) = 0.5 - 0.5*erf( (x-μ)/(σ * sqrt(2.0)))

ここで、テイラー級数で記述できる誤差関数erf()は次のとおりです。

erf(z) = 2.0/sqrt(2.0) * Σ ∞</sup> n=0 ((-1) n z 2n + 1 )/(n!(2n + 1))

これを C に翻訳する練習問題として残しておきます。

演習に参加したくない場合は、Gnu Scientific Libraryの使用を検討してください。これには、他の多くの機能の中でも、多くの一般的な分布の 1 つで乱数を生成する手法があり、ガウス分布 (ヒント) はその 1 つです。

明らかに、これらの関数はすべて浮動小数点値を返します。離散値に変換するには、何らかの丸め戦略を使用する必要があります。有用な (しかし素朴な) アプローチは、単純に整数にダウンキャストすることです。

于 2009-07-28T23:57:33.677 に答える