c++ - 使用 srand() 在随机游走中出现蝴蝶模式,为什么?
问题描述
大约 3 年前,我和一个同事用 C++ 编写了一个 2D 随机游走,首先它似乎工作正常,因为我们每次都获得了不同的模式。但是,每当我们决定将步数增加到某个阈值以上时,就会出现明显的蝴蝶模式,我们注意到,每次运行代码时,模式都会重复,但从蝴蝶的不同位置开始。我们当时总结报告说是srand()函数关联的伪随机生成器导致的,但是今天又找到了这个报告,还有一些想了解的地方。我想更好地了解伪随机生成器是如何工作的,以获得这种对称和 ciclic 模式。我的模式
编辑:
我正在添加用于获取此图的代码:
#include<iostream>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include <fstream>
#include <string.h>
#include <string>
#include <iomanip>
using namespace std;
int main ()
{
srand(time(NULL));
int num1,n=250000;
ofstream rnd_coordinates("Random2D.txt");
float x=0,y=0,sumx_f=0,sumy_f=0,sum_d=0,d_m,X,t,d;
float x_m,y_m;
x=0;
y=0;
for(int i=0;i<n;i++){
t=i;
num1= rand()%4;
if(num1==0){
x++;
}
if(num1==1){
x--;
}
if(num1==2){
y++;
}
if(num1==3){
y--;
}
rnd_coordinates<<x<<','<<y<<','<<t<<endl;
}
rnd_coordinates.close();
return 0;
}
解决方案
你从来没有打过rand()
's period,但请记住,你实际上并没有使用rand()
完全保证 2^32 周期的整个范围。
考虑到这一点,您有两个选择:
- 使用所有位。
rand()
返回 2 个字节(16 位),您需要 2 位(对于 4 个可能的值)。将 16 位输出拆分为 2 位块并按顺序使用它们。 - 至少如果您坚持使用惰性
%n
方式,请选择一个不是您的周期除数的模数。例如选择 5 而不是 4,因为 5 是素数,如果你得到第 5 个值,则重新掷骰。
推荐阅读
- r - 重复 id 时在行中绑定数据框
- python - 可以创建一个“with”块来运行它只包含一次的代码吗?
- javascript - Javascript切片数组查找最大值
- ios - 如何在仅从远程 CloudKit 数据库收到更改时收到通知?
- c++ - 如果需要数据包标头,通过 UDP 发送大型连续缓冲区的最有效方法是什么?
- php - 如何知道无序数组的最后一个索引
- python - 如何使用 Python 更新 JIRA 中的自定义字段值?
- php - 尝试显示从 Oracle 数据库中选择的数据时出现 JPGraph 轴错误
- python - 为什么我的 Tkinter 滚动条位于它应该滚动的区域之上?
- ruby-on-rails - 如何使用 SAML 中的 RelayState 来指定 SP 的登录页面,使用 saml-omniauth 和设计?