随机数生成:相同的C++代码,两种不同的行为
Random Number Generation : same C++ code, two different behaviors
和我的同事正在C++一起做一个蒙特卡洛项目。她使用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
函数。 即便如此,我也不确定跨计算机和操作系统的底层代码是否会返回相同的值。
更重要的是,如果你想要相同的结果,不要使用随机函数。
- 在C++中将函数压缩为两种方式
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 计算两个代码块的时间复杂度
- 这两个代码片段相似,但显示的结果不同
- 如何使映射键具有两种不同的数据类型?
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 如何构造可以调用和返回两种不同类型的模板
- 这两种C++语法之间有什么区别?
- 为什么两种不同的对象初始化方式给出不同的输出
- std::cin 从控制台获取两种不同的变量类型,'storing'以后使用第二种类型?
- 定义类模板构造函数的两种方法之间的区别
- 初始化类的两种方法?
- C++ 一个函数,可以根据接受的值返回两种类型之一
- 如何检查程序员在C++中提供的两种不同格式的输入
- C++指针中的这两种类型的值分配有什么区别?
- 两种专用方法中的相同代码
- 随机数生成:相同的C++代码,两种不同的行为
- c++:我应该如何重新安排这段代码,以便循环检查两种情况
- 我的c++代码在ideone和codeforces自定义测试中提供了两种不同的输出