为什么这些RNG在C++中没有产生类似的结果?
Why do these RNG's in C++ and R not produce similar results?
请原谅这篇文章令人厌恶的无聊性质,但我有一个问题要问那些在个人电脑上用C++和R编程的人。
问题:为什么下面两个程序产生的这些随机数不相等,我该如何解决这个问题?
- 首先,我怀疑我误用了R程序中的
local
函数和<<-
运算符 - 其次,我怀疑这可能是一个浮动的准确性问题。我还不清楚这两个程序有什么不同,所以我不知道如何解决这个问题
我已经尝试将C++中的所有计算强制转换为double
/float
(甚至long double
),并使用fmod
而不是模运算符%
:再次输出不同,但仍然与R中的输出不相似。我不知道它是否有任何重要意义,但我想补充一点,我正在使用G++编译器编译C++代码。
算法:以下算法可用于任何标准个人计算机。建议在并行中使用三个字生成器
- mk=171mk-1(mod 30269)
- m'k=172
- m'k=172
并使用分数部分作为伪随机数
- gk={mk/30269+m’k+/30307+m’’k/30023}
我已经使用了初始值m0=5,m’0=11,以及m'’0=17。
程序:我在C++中有以下程序:
//: MC:Uniform.cpp
// Generate pseudo random numbers uniformly between 0 and 1
#include <iostream>
#include <math.h> // For using "fmod()"
using namespace std;
float uniform(){
// A sequence of initial values
static int x = 5;
static int y = 11;
static int z = 17;
// Some integer arithmetic required
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
/* If both operands are nonnegative then the
remainder is nonnegative; if not, the sign of
the remainder is implementation-defined. */
if(x < 0)
x = x + 30269;
if(y < 0)
y = y + 30307;
if(z < 0)
z = z + 30323;
return fmod(x / 30269. + y / 30307. + z / 30323., 1.);
}
int main(){
// Print 5 random numbers
for(int i = 0; i < 5; i++){
cout << uniform() << ", ";
}
}///:~
程序带代码退出并输出以下内容:
0.686912, 0.329174, 0.689649, 0.753722, 0.209394,
我在R中也有一个程序,看起来如下:
## Generate pseudo random numbers uniformly between 0 and 1
uniform <- local({
# A sequence of initial values
x = 5
y = 11
z = 17
# Use the <<- operator to make x, y and z local static
# variables in R.
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x / 177)
y <<- 172 * (y %% 176) - 35 * (y / 176)
z <<- 170 * (z %% 178) - 63 * (z / 178)
return((x / 30269. + y / 30307. + z / 30323.)%%1.)
}
})
# Print 5 random numbers
for(i in 1:5){
print(uniform())
}
该程序也与代码一起退出,并产生输出
[1] 0.1857093
[1] 0.7222047
[1] 0.05103441
[1] 0.7375034
[1] 0.2065817
如有任何建议,我们将不胜感激。
您的R代码中还需要一些%/%
(整数除法)。请记住,默认情况下,R中的数字变量是浮点值,而不是整数;所以CCD_ 9将用非整数商进行普通除法。您还省略了处理负x
/y
/z
的部分。
f <- function(){
x <<- 171 * (x %% 177) - 2 * (x %/% 177)
y <<- 172 * (y %% 176) - 35 * (y %/% 176)
z <<- 170 * (z %% 178) - 63 * (z %/% 178)
if(x < 0)
x <<- x + 30269;
if(y < 0)
y <<- y + 30307;
if(z < 0)
z <<- z + 30323;
return((x / 30269. + y / 30307. + z / 30323.)%%1)
}
在做出这些改变之后,结果似乎没有什么严重的问题。100000个随机抽取的快速直方图看起来非常均匀,而且我找不到自相关。但是仍然与您的C++结果不匹配。。。。
您的C++代码中有一个简单的复制/粘贴错误。这个
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (x % 176) - 35 * (y / 176);
z = 170 * (x % 178) - 63 * (z / 178);
应该是这样。
x = 171 * (x % 177) - 2 * (x / 177);
y = 172 * (y % 176) - 35 * (y / 176);
z = 170 * (z % 178) - 63 * (z / 178);
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- valgrind-hellgrind与泄漏检查的结果不同
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 序列化,没有库的整数,得到奇怪的结果
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 在更改for循环的第三部分后,未使用for循环结果
- 使用++运算符会导致意外的结果
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- C++Brute Force攻击函数不会返回结果
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 算术运算的结果类似于:C浮点变量中的1/3
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 密码登录程序将永远循环并显示不正确的结果
- 如何让C++'tally up'结果并制定计划?
- 为什么这个程序的结果是3 "born"?和 4 死
- 为什么这些RNG在C++中没有产生类似的结果?