意図したとおりに機能しないC ++を使用して実装された論文からの確率密度関数
-
29-09-2019 - |
質問
だから私はヒューリスティックアルゴリズムを実装しており、この機能に出会います。
1からN(Cで0からN-1、w/e)の配列があります。別の配列にコピーするいくつかの要素を選択したいと思います。パラメーターy(0 <y <= 1)が与えられた場合、平均が(y * n)の数値の分布が必要です。つまり、私がこの関数を呼び出すときはいつでも、それは私に0からnの間で数字を与え、これらの数値の平均はy*nであることを意味します。
著者によると、「l」は乱数です:0 <l <n。私のテストコードでは、現在0 <= l <= nを生成しています。そして、私は正しいコードを持っていましたが、私はこれを何時間も台無しにしています、そして私はそれをコードバックするのが怠けています。
したがって、y <= 0.5の場合、関数の最初の部分を0.2に、nを100にコーディングしました。つまり、平均20で0から99の間で数値を返す必要があり、結果は間ではありません。 0とn、しかしいくつかのフロート。そして、より大きいほど、このフロートは小さくなります。
これはCテストコードです。 「x」は「L」パラメーターです。
//hate how code tag works, it's not even working now
int n = 100;
float y = 0.2;
float n_copy;
for(int i = 0 ; i < 20 ; i++)
{
float x = (float) (rand()/(float)RAND_MAX); // 0 <= x <= 1
x = x * n; // 0 <= x <= n
float p1 = (1 - y) / (n*y);
float p2 = (1 - ( x / n ));
float exp = (1 - (2*y)) / y;
p2 = pow(p2, exp);
n_copy = p1 * p2;
printf("%.5f\n", n_copy);
}
そして、ここにいくつかの結果があります(5小数は切り捨てられます):
0.03354
0.00484
0.00003
0.00029
0.00020
0.00028
0.00263
0.01619
0.00032
0.00000
0.03598
0.03975
0.00704
0.00176
0.00001
0.01333
0.03396
0.02795
0.00005
0.00860
記事は次のとおりです。
http://www.scribd.com/doc/3097936/cas-the-cunning-ant-system
6ページと7ページ。
または、Googleで「CAS:CunningAnt System」を検索します。
それで、私は何が間違っているのですか?この同じ機能を説明する5つ以上の論文があるので、著者が間違っているとは思いません。
私を助けてくれる人に私のすべてのインターネット。これは私の仕事にとって重要です。
ありがとう :)
解決
DMCKEEは実際には正しいですが、私はもっと詳しく説明し、ここで混乱のいくつかを説明しようとすると思いました。私は間違いなく失敗する可能性があります。 f_s(l)
, 、上記のかなり式にある関数は、確率分布関数です。特定の入力に対して、それはあなたに伝えます l
0からNの間で、その確率 l
セグメントの長さです。 0とnの間のすべての値の合計(積分)は1に等しくなければなりません。
7ページの上部にあるグラフは、この点を混乱させます。それはプロットします l
vs。 f_s(l)
, 、しかし、あなたはそれが横に置く迷走要因に注意する必要があります。下部の値は0から1に進むことに気付きましたが、 x n
横には、それを意味します l
値は実際に0からnになります。また、y軸にはaがあります x 1/n
つまり、これらの値は実際には約3までになり、3/nになります。
それで、あなたは今何をしていますか?さて、確率分布関数を統合することにより、累積分布関数を解決する必要があります l
これは実際にはそれほど悪くないことが判明しました(私はWolfram Mathematica Online IntegratorでXを使用してそれをしました l
y <= .5の方程式のみを使用します。しかし、それは無期限の積分を使用していて、あなたはxに沿って0から0に統合されています l
. 。結果の方程式を何らかの変数(たとえばz)に等しく設定すると、今の目標は解決することです l
zの関数として。 zここでは0から1の乱数です。必要に応じて、このパートにシンボリックソルバーを使用してみてください(私がそうします)。次に、ランダムを選ぶことができるという目標を達成しただけではありません l
sこの分布から、Nirvanaも達成しました。
もう少し作業が行われました
もう少し助けます。 y <= .5で言ったことを試してみましたが、使用していたシンボリック代数システムは反転を行うことができませんでした(他のシステムができるかもしれません)。しかし、それから私は式を.5 <y <= 1で使用してみることにしました。これははるかに簡単であることが判明しました。変更した場合 l
x inに f_s(l)
私は得ます
y / n / (1 - y) * (x / n)^((2 * y - 1) / (1 - y))
これをxを0から0から統合します l
私は(Mathematicaのオンラインインテグレーターを使用して)
(l / n)^(y / (1 - y))
この種のものでは、それよりもそれほど良くなりません。これをzに等しく設定して解決した場合 l
わかりました:
l = n * z^(1 / y - 1) for .5 < y <= 1
1つのクイックチェックはy = 1の場合です。この場合、私たちは取得します l = n
Zが何であれ。ここまでは順調ですね。これで、z(0〜1の間の乱数)を生成するだけで、 l
これは、.5 <y <= 1の必要なように配布されます。ただし、待ってください。7ページのグラフを見ると、確率分布関数が対称であることがわかります。つまり、上記の結果を使用して0 <y <= .5の値を見つけることができます。変更するだけです l
-> n-l
と y
-> 1-y
そして、取得します
n - l = n * z^(1 / (1 - y) - 1)
l = n * (1 - z^(1 / (1 - y) - 1)) for 0 < y <= .5
とにかく、私がどこかで何らかのエラーを犯さない限り、それはあなたの問題を解決するはずです。幸運を。
他のヒント
あなたはあなたに期待されることを誤解するかもしれません。
(適切に正規化された)PDFが与えられ、それに一致するランダム分布をスローしたい場合、PDFを統合して累積確率分布(CDF)を形成し、CDFを反転させ、逆のランダム述語を反転の引数として使用します働き。
もう少し詳細。
f_s(l)
PDFであり、正規化されています [0,n)
.
これで、それを統合してCDFを形成します
g_s(l') = \int_0^{l'} dl f_s(l)
これは、私が呼んだ不特定のエンドポイントに明確な積分であることに注意してください l'
. 。したがって、CDFはの関数です l'
. 。正規化権があると仮定すると、 g_s(N) = 1.0
. 。そうでない場合は、単純な係数を適用して修正します。
次に、CDFを反転し、結果を呼び出します G^{-1}(x)
. 。このためには、おそらくガンマの特定の価値を選択したいと思うでしょう。
次に、均一な乱数を投げます [0,n)
, 、そしてそれらを議論として使用し、 x
, 、 に G^{-1}
. 。結果は間にあるはずです [0,1)
, 、およびに従って配布する必要があります f_s
.
ジャスティンが言ったように、数学にコンピューター代数システムを使用できます。
記載されているように、任意の値l、y、nについて、P1とP2を呼び出す項は[0,1)とexpが[1、..)にあることを考えると、[P2、exp)も[0、 1)したがって、範囲[0、n)で出力を取得する方法がわかりません