在Julia集中设置随机种子,以便在从程序的不同部分调用函数时不生成相同的值。

3
我有一个Julia程序,用于运行一些蒙特卡罗模拟。为此,在调用生成随机数的函数之前,我设置了一个种子。该函数可以从程序的不同部分调用,但问题是当我从程序的不同部分调用该函数时,我生成的随机值并不相同。
我的问题是:为了获得相同的可重现结果,我必须始终从程序的同一部分调用此函数吗?也许这个问题更与计算机科学相关,而不仅仅是编程语言本身。
我考虑在函数内部使用递增索引来生成种子,但我仍然不能获得相同的结果。

1
你能展示一下你用来实现这个的代码吗?提供一个最小可行示例会更好。 - Sundar R
您能否提供一个可重现的代码,以展示您的问题?通常最好不要使用默认全局随机数生成器,而是使用自己的随机数生成器实例,以确保您完全控制它的使用方式。 - Bogumił Kamiński
1个回答

3

如果将随机数生成器对象作为参数传递给您的函数,根据您的需求产生随机性会更加容易。

例如:

using Random

function foo(a=3;rng=MersenneTwister(123))
  return rand(rng,a)
end

现在,您可以调用该函数并在每次函数调用时获得相同的结果。
foo() # the same result on any call

然而,这通常不是你想要的。更常见的情况是你想保证整个实验的可重复性。 在这种情况下,在脚本开头设置一个RNG并调用该函数。这将导致函数的输出在每次调用时都不同,但在整个脚本的一次运行和另一次运行之间相同。
myGlobalProgramRNG = MersenneTwister() # at the beginning of your script...
foo(rng=myGlobalProgramRNG)

需要注意多线程。如果你想要保证在多线程情况下的可复制性,尤其是无论你的脚本是以1、2、4个线程运行,例如,可以查看我在ML库中如何处理它,使用generateParallelRngs()函数。

第二个注意点是,即使你在脚本开头创建自己的随机数生成器或种子默认的随机种子,不同的Julia版本可能(而且确实会)改变RNG流,因此仅在同一Julia版本内才能保证可复制性。 为了解决这个问题,你可以使用像StableRNG.jl这样的包来保证RNG流的稳定性(代价是失去一点性能)...


1
+1 -- 我们在Turing.jl中这样做,但rng总是作为可选的第一个参数,回退到GLOBAL_RNG,以与标准库的随机函数保持一致。 - phipsgabler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接