【问题标题】:Why are my random numbers always the same?为什么我的随机数总是一样的?
【发布时间】:2014-05-26 18:03:48
【问题描述】:

我正在使用 Fortran 的 random_number 子例程,但在不同的程序运行中,生成的数字不会改变。我应该在我的代码中包含什么,以便每次编译和运行程序时数字都会改变?

【问题讨论】:

    标签: random fortran gfortran


    【解决方案1】:

    随机数生成器产生伪随机数。要每次运行获得不同的数字,您需要在程序开始时初始化random seed。这会在伪随机流中选择不同的起始位置。

    【讨论】:

    • 而做到这一点的方法是不带参数地调用 RANDOM_SEED。在大多数实现中,这将使种子“随机化”。
    • @SteveLionel 由于问题被标记为 gfortran,我会注意到这个实现似乎不是其中之一。
    • @francescalus 是的,确实如此。我觉得这相当惊人。但是,标准确实说,这样的调用以“依赖于实现”的方式初始化种子,因此标准允许 gfortran 所做的事情。 gcc.gnu.org/onlinedocs/gfortran/RANDOM_005fSEED.html 给出了一个如何随机化种子的例子,但是......糟糕。
    • 这并不像看起来那么糟糕。这种“奇怪”的行为允许随机数序列从一次代码运行到下一次运行是相同的。这样可以更轻松地测试高度随机的系统。但是,在同一个程序中,数字是“随机的”。如果您想要与另一次运行不同的随机数,则使用 RANDOM_SEED。总的来说,我发现这是一个很好的实现。
    【解决方案2】:

    来自对random_number 的调用的伪随机数序列取决于处理器使用的算法和种子的值。

    种子的初始值取决于处理器。对于某些处理器,每次程序运行时这个种子值都是相同的,而对于某些处理器,它会有所不同。第一种情况给出了一个可重复的伪随机序列,第二种情况给出了一个不可重复的序列。

    gfortran(版本 7 之前)属于第一类。如果您希望获得不可重复的序列,则需要显式更改随机种子。

    正如another answer 中所述,固有的random_seed 可用于设置种子的值并重新启动伪随机生成器。同样,当调用为call random_seed()(即,没有put= 参数)时会发生什么,这取决于处理器。有些处理器会以可重复的顺序重新启动生成器,有些则不会。 gfortran(同样,在版本 7 之前)属于第一类。

    对于call random_seed() 产生可重复序列的处理器,需要显式的运行时变化种子来生成不同的序列。可以在the documentation 中找到这些旧 gfortran 版本的示例。

    应该注意的是,选择种子可能是一件复杂的事情。不仅会存在可移植性问题,而且可能需要注意确保发电机不会在低熵区域重新启动。对于多图像程序,用户必须努力使这些图像具有不同的序列。

    最后一点,Fortran 2018 引入了标准内部过程random_init。这处理了选择跨调用的可重复性和(coarray)图像的区别这两种情况。

    【讨论】:

    • gcc 文档的链接也必须更新,它应该指向旧版本,就像我在这里所做的那样 stackoverflow.com/a/18773059/721644
    • 好点,谢谢。我以为我当时做得对,但看起来我没有。
    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 2020-11-21
    • 2020-06-16
    • 2021-05-02
    • 2013-04-23
    • 1970-01-01
    相关资源
    最近更新 更多