From this question: Random number generator which gravitates numbers to any given number in range?自從我遇到過這樣一個隨機數發生器之前,我做了一些研究。我只記得是名爲「穆勒」,所以我想我找到了,在這裏:在C中實現Box-Mueller隨機數發生器#
我可以找到其他語言的它衆多的實現,但我似乎無法到在C#中正確實現它。
此頁面,例如,The Box-Muller Method for Generating Gaussian Random Numbers說,代碼應該是這樣的(這不是C#):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
double
gaussian(void)
{
static double v, fac;
static int phase = 0;
double S, Z, U1, U2, u;
if (phase)
Z = v * fac;
else
{
do
{
U1 = (double)rand()/RAND_MAX;
U2 = (double)rand()/RAND_MAX;
u = 2. * U1 - 1.;
v = 2. * U2 - 1.;
S = u * u + v * v;
} while(S >= 1);
fac = sqrt (-2. * log(S)/S);
Z = u * fac;
}
phase = 1 - phase;
return Z;
}
現在,這是我在C#實現以上。請注意,變換會產生2個數字,因此上面的「階段」是個訣竅。我只是丟棄第二個值並返回第一個值。
public static double NextGaussianDouble(this Random r)
{
double u, v, S;
do
{
u = 2.0 * r.NextDouble() - 1.0;
v = 2.0 * r.NextDouble() - 1.0;
S = u * u + v * v;
}
while (S >= 1.0);
double fac = Math.Sqrt(-2.0 * Math.Log(S)/S);
return u * fac;
}
我的問題是,具有以下情形,在我的代碼不會在0-1的範圍內返回一個值,我無法理解的原代碼如何既可以。
- U = 0.5,V = 0.1
- S成爲
0.5*0.5 + 0.1*0.1
=0.26
- FAC變得〜
3.22
- 返回值是這樣〜
0.5 * 3.22
或〜1.6
即內不0 .. 1
。
我在做什麼錯誤/不理解?
如果我修改我的代碼,以便代替乘fac
與u
,我通過S
乘,我得到的範圍從0到1的值,但它有錯誤的分佈(好像有周圍具有極大分佈0.7- 0.8,然後在兩個方向上逐漸減小。)
請注意,我已經檢查了上述代碼的兩個示例,通常是C或Java,它們看起來都差不多。 – 2011-04-28 11:12:23
你確定C代碼生成你想要的? – Euphoric 2011-04-28 11:45:13