繁体   English   中英

随机数生成:相同的C ++代码,两种不同的行为

[英]Random Number Generation : same C++ code, two different behaviors

我和我的同事正在一起使用C ++进行Monte Carlo项目。 她使用Visual Studio,我使用Xcode,我们通过git共享代码。 由于要使用需要随机数生成的给定方法,我们正在计算美国期权价格。 我们意识到对于某个参数K,我们得到了错误的结果(参数越高,答案越错误),我的同事发现,将Mersenne Twister的随机源更改为rand()(尽管生成器较差)可以使结果良好在整个K范围内

但是,当我更改代码版本的源代码时,它什么也没做。

更让我感到困惑的是,我创建了一个新的Xcode项目,并在其中复制了她的整个源代码,但仍然给我错误的结果(尽管她得到了很好的结果)。 因此,它不能源自代码本身。 我清理了项目,重新启动了Xcode,甚至重新启动了计算机(...),但没有任何变化:我们的项目表现一致,但有所不同,后面都有相同的代码。 (编辑:通过不同但始终如一的方式,我并不是说我们没有相同的数字序列。我的意思是她的蒙特卡洛估计量收敛于4.并趋近于3。)

您是否知道导致这种双重行为的原因是什么?

这是随机生成代码:

double loiuniforme() //uniform law
{
    return (double)((float)rand() / (float)RAND_MAX);
}


vector<double> loinormale() //normal law
{
    vector<double> loinormales(2, 0.);

    double u1 = loiuniforme();
    double v1 = loiuniforme();

    loinormales[0] = sqrt(-2 * log(u1))*cos(2 * M_PI*v1);
    loinormales[1] = sqrt(-2 * log(u1))*sin(2 * M_PI*v1);

    return(loinormales);

}

编辑:之前使用的MT RNG是:

double loiuniforme()
{
    mt19937::result_type seed = clock();
    auto real_rand = std::bind(std::uniform_real_distribution<double>(0,1), mt19937(seed));
    return real_rand();
}

C ++标准未指定rand()使用哪种算法。 编写该编译器的人可以自由使用他们想要的任何实现,并且不能保证它在两个不同的编译器,两个不同的体系结构甚至同一编译器的两个不同版本上的行为相同。

您应该只创建一个生成器,并将其用于每个数字。

mt19937::result_type seed = clock();

mt19937(seed)

每次调用该函数时,请使用新种子创建一个新的生成器。
这导致随机性全部扭曲。

您可以在函数中使用静态变量,因为它们是在第一次调用时初始化的:

double loiuniforme() 
{ 
    static std::mt19937 generator(clock()); 
    static std::uniform_real_distribution<double> distribution(0, 1); 
    return distribution(generator); 
}

(当您与同事比较结果时,请使用相同的硬编码种子来验证您是否获得了相同的结果。)

您需要在两台计算机上为rand函数添加相同的数字。 即使那样,我仍然不确定跨计算机和操作系统的基础代码是否会返回相同的值。

更重要的是,如果要获得相同的结果,请不要使用随机函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM