使用 srand() 在随机游走中出现蝴蝶图案,为什么?

Isi*_*gre 11 c++ random srand random-walk random-seed

大约 3 年前,我和一位同事用 C++ 编写了一个 2D 随机游走,起初它似乎工作正常,因为我们每次都获得不同的模式。但是每当我们决定将步数增加到某个阈值以上时,就会出现明显的蝴蝶图案,我们注意到每次运行代码时,该图案都会重复,但会从蝴蝶的不同位置开始。我们当时总结报告说是srand()函数关联的伪随机生成器造成的,但是今天又找到了这个报告,还有一些想了解的地方。我想更好地了解伪随机生成器是如何工作的,以获得这种对称性和环状图案。模式我'

在此处输入图片说明

编辑:

我正在添加用于获取此数字的代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

Bli*_*ndy 3

您从未遇到过 的rand()句点,但请记住,您实际上并没有使用rand()保证 2^32 句点的整个范围。

考虑到这一点,您有两个选择:

  1. 使用所有位。rand()返回 2 个字节(16 位),而您需要 2 位(用于 4 个可能的值)。将 16 位输出拆分为 2 位块并按顺序使用它们。
  2. 至少,如果您坚持使用惰性%n方式,请选择一个不是周期除数的模数。例如,选择 5 而不是 4,因为 5 是素数,如果您得到第 5 个值,则重新滚动。