【问题标题】:Returned values from Gaussian random number generator高斯随机数生成器的返回值
【发布时间】:2013-05-30 01:54:34
【问题描述】:

我正在用 C 编写我的第一个代码。该项目是一个分子动力学代码,用于模拟粒子在无限重复的盒子中弹跳(周期性边界条件)。到目前为止,我一直在使用预设值加载粒子位置和速度。是时候为我的模拟添加一些(伪)随机性了。我在网上找到了以下高斯随机数生成函数,经过一些修改(原作者使用 drand48(),我无法使用),我让 gaussian() 函数返回了一些数字。现在我没有修改返回值以适应模拟;我只是想确保每次都能获得新的价值观。

我知道我需要为 rand() 添加一个种子,例如 srand(time(NULL))。 当 srand(time(NULL)) 被注释掉时,我每次运行模拟时都会得到相同的 20 个随机数,但是当包含该语句时,我会得到 10 次相同的随机数对。如何正确初始化 rand() 的种子?

/* function for gaussian random variables */
double gaussian()
{
    static int    have = 0;
    static double x2;
    double fac, y1, y2, x1;

    if ( have == 1 )  /* already one available ? */
    {
        have = 0;
        return x2;
    } 
    else 
    {
        /* generate a pair of random variables */
        /* srand(time(NULL)); */
        y1 = (double)rand() / RAND_MAX ;
        y2 = (double)rand() / RAND_MAX ;
        fac = sqrt(-2*log(y1));
        have = 1;
        x1 = fac*sin(2*M_PI*y2); /* x1 and x2 are now gaussian */
        x2 = fac*cos(2*M_PI*y2); /* so store one */
        return x1;               /* and return the other. */
    }
}

【问题讨论】:

  • 我相信很多人已经指出了将 srand() 放入函数的明显错误。如果这是您真正需要做的事情(而不仅仅是练习),那么计算正态变量的速度要快得多的方法称为 Ziggurat 算法。我的公共域ojrandlib 就是这样做的。

标签: c random gaussian


【解决方案1】:

您不应该在每次想要生成随机数时都调用srand(time(NULL)) - 仅在main() 函数开始时调用一次。

【讨论】:

    【解决方案2】:

    您只需为整个程序调用 srand() 一次,因此请将其放在主函数顶部附近或在程序早期方便的其他位置。

    您看到相同数字对的原因很可能是因为您在紧密循环中调用 gaussian() 函数,这样每次调用 time() 都会返回相同的值,因此会重置随机数发电机到同一点;因此它为您提供了相同的 2 个数字。

    【讨论】:

      【解决方案3】:
      #include <time.h>
      //…
      srand((unsigned)time(NULL));
      //set a seed only once
      //use rand()
      

      然而,rand() 总是生成伪随机数。

      【讨论】:

        猜你喜欢
        • 2014-04-15
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 2011-04-14
        • 1970-01-01
        • 1970-01-01
        • 2020-08-24
        • 1970-01-01
        相关资源
        最近更新 更多