我知道这可以通过定义泪珠形状并接受落在该区域内的点(来自均匀的发生器)来完成。
我试图在C ++中通过生成两个均匀的随机数x和y来定位点(x,y),然后检查这个点是否属于该区域。
我对代码本身没有问题,但我的逻辑中存在缺陷吗?我还没有找到合适的图形方式来检查这是否是真正的正态分布。
这是应该起作用的代码:
typedef unsigned long long int Ullong;
typedef double Doub;
struct Normaldev : Ran {
Doub mu,sig;
Normaldev (Doub mmu, Doub ssig, Ullong i)
: Ran (i), mu(mmu), sig(ssig){}
Doub dev() {
Doub u, v, x, y, q;
do {
u=Doub();
v=1.7156*(Doub()-0.5);
x=u-0.449871;
y=abs(v)+0.386595;
q=x*x+y*(0.19600*y-0.25472*x);
} while(q>0.27597 && (q>0.27846 || v*v>-4*log(u)*u*u));
return mu+sig*v/u;
}
};
我尽可能多地根据我对C ++的基本知识更改了“数字食谱”一书中的建议代码,但是Ran究竟应该是什么?
答案 0 :(得分:1)
我尽可能多地根据我对C ++的基本知识更改了“数字食谱”一书中的建议代码,但是Ran究竟应该是什么?
Ran是NormalDev的父类。它没有在你给出的代码中定义。根据代码,它似乎是一个非常通用的随机数类,在其构造函数中采用unsigned long long int
种子。
答案 1 :(得分:-1)
查看第3版“C中的数字食谱”,第364-369页。你会发现Box-Muller返回两个正态分布的随机变量,即'u'和'v'。因此,第一次调用该函数时,您计算两个变量,但只返回'u'。函数的第二次调用只会返回'v'。
double u, v;
double sigma = 1.0
double mean = 0.0;
int flag = 0;
double boxMuller()
{
if (flag == 1) {
flag = 0;
return v * sigma + mean;
}
double help;
do {
u = Doub() - 0.5;
v = Doub() - 0.5;
help = u * u + v * v;
} while (help >= 0.25);
help = sqrt( log( help * 4.0 ) / help * -2.0 );
u *= help;
v *= help;
flag = 1;
return u * sigma + mean;
}
相比之下,制服比率方法必须在每次通话时计算一个新的随机变量(不是每一秒)。
所以我测量了时间,并且更喜欢使用上面的Box-Muller代码。