2

これがどのタイプのアルゴリズムであるか、またはこれ
を実行するためのより簡単で効率的な方法があるかどうか疑問に思っています。

特定の確率密度が与えられているとしましょう。

prob[] = {.1, .15, .25, .05, .45}

グループ1〜10%
グループ2〜15%
グループ3〜25 %グループ
4〜5%
グループ5〜45%

乱数(0,1)、
実行= .853234

5つのグループのいずれかに挿入します

if (ran <=prob[0]) selection = 1;  
else if (ran <= prob[0]+prob[1]) selection = 2;  
...
else if (ran <= prob[0]+prob[1]+...+prob[4]) selection = 5;  

私は乱数の生成にあまり精通していません

4

4 に答える 4

2

ここで本質的に行っていることは、累積分布関数を逆にすることです。を与えられた分布の確率F変数の CDF とするXと、次のように定義されF(x) == P[X <= x]ます。

ここで非常に便利なことは、U0 と 1 の間の一様確率変数を生成すると、

P[F^-1(U) <= x] == P[U <= F(x)] == F(x) == P[X <= x]

つまり、 !F^-1(U)と同じ分布になります。X

もちろん、これはCDFを反転できる場合にのみ可能ですが、あなたの場合Fは区分関数(階段のような)であり、アルゴリズムは、特定の均一値に対して、この値がどのステップで満たされるかを決定します。したがって、アルゴリズムは完全に正しいです。

ただし、生成する乱数が多い場合は改善できます。最初に CDF テーブルを生成します。この場合は次のようになります。

CDF[] = {.1, .25, .5, .55, 1.}

次に、生成された 0 から 1 までの均一な数値ごとに、CDF テーブルで二分法を実行して、対応するインデックスを取得します。

于 2011-11-03T10:41:05.333 に答える
1

あなたのアルゴリズムは正しいです。ただし、あなたの例では、確率の合計は 1 になりません。

于 2011-10-31T15:41:37.263 に答える
0

そのコードは、確率の合計が 100% にならないことを除いて機能します (そのため、if ステートメントがどれも一致しない可能性があります)。

このアプローチは、累積確率分布を使用して少し単純化できます。

cumprob[5] = {.1, .2, .45, .50, 1.0};

これにより、if-elif チェーンの代わりにlsearchを使用することもできます。

于 2011-10-31T15:41:57.647 に答える
0

あなたのアルゴリズムは、これを実装する最良の方法ではない離散分布にランダムな浮動小数点数を使用しています。あなたの実装は、与えられた分布とほとんど区別できない分布を提供するかもしれませんが、それは科学的に正しくありません。

代わりに、与えられた確率 (例では 5%) の最小公分母を見つけ、[0,19] のランダムな整数を使用してグループを選択します。例:

switch(random(19)) {
case 0:
case 1:
  selection = 1;
  break;
case 2:
case 3:
case 4:
  selection = 2;
  break;
case 5:
case 6:
case 7:
case 8:
case 9:
  selection = 3;
  break;
case 10:
  selection = 4;
  break;
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
  selection = 4;
  break;
}
于 2011-11-03T08:20:44.037 に答える