在Julia中,全局随机数生成器的种子可以使用以下方式设置:
srand(SEED)
我该如何检索全局随机数生成器的种子或当前状态,以便稍后再次使用?
目标是在任何给定时间点获取RNG的状态,并在不知道最初的种子或中间发生的所有调用RNG的情况下,在不同会话中重新创建它。
例如,R允许通过以下方式访问当前种子
.Random.seed
我希望在 Julia 中存在一种等效的方法。
Base.Random.RANDOM_SEED
是获取种子的好帮手:
julia> srand(10)
julia> Base.Random.RANDOM_SEED
1-element Array{Uint32,1}:
0x0000000a
julia> srand(1)
julia> Base.Random.RANDOM_SEED
1-element Array{Uint32,1}:
0x00000001
julia> srand(0xF)
julia> Base.Random.RANDOM_SEED
1-element Array{Uint32,1}:
0x0000000f
Base.Random.GLOBAL_RNG.seed
访问,而不是 Base.Random.RANDOM_SEED
。 - ChrisBase.Random
现在是自己的包,但Random.GLOBAL_RNG
没有seed
字段,而Random.RANDOM_SEED
未定义。 - ForceBrureinterpret(Int32, Base.Random.GLOBAL_RNG.seed)
测试:
julia> srand(123456789);
julia> reinterpret(Int32, Base.Random.GLOBAL_RNG.seed)
1-element Array{Int32,1}:
123456789
Base.Random.GLOBAL_RNG
对象。一种简单的方法是使用JLD包。使用专门的MersenneTwister算法,使用显式变量(而不是默认的隐式全局变量)提供您所需的功能:
newmt = Base.Random.MersenneTwister(123)
randvec = [rand(newmt) for i=1:100]
# save state now
savestate = deepcopy(newmt.state)
randvec2 = [rand(newmt) for i=1:20]
# rewind state to old state
newmt.state = savestate
randvec3 = [rand(newmt) for i=1:20]
if randvec2==randvec3
println("works!")
end
deepcopy
让我有点困惑。另外,要访问全局随机生成器状态可能更容易,但可能需要使用ccall
调用libdSFMT库(请参见Base
中的random.jl
和dSFMT.jl
)。
为了在函数和一般情况下更好地控制随机生成器,
RND = srand(0)
function coolfun()
println(RND.idx)
output = srand(RND, 100)
...
end
由于此问题的其他答案涉及旧版本的Julia并且不再起作用,因此我决定发布一个新答案。
在Julia版本>= 1.0中,字段Base.Random.GLOBAL_RNG不再存在。在Julia 1.0中,Random包中有一个字段Random.GLOBAL_RNG(不再是Base的一部分)。从那里检索种子并像https://dev59.com/s18d5IYBdhLWcg3wzEz4#47900426中描述的设置它不再起作用。
在Julia 1.4和1.5中,有函数Random.default_rng()。我成功地使用以下代码获得了保存和恢复随机生成器状态的期望行为:
julia> import Random
julia> Random.seed!(1);
julia> rand(Int)
6592875438459116351
julia> rng = copy(Random.default_rng());
julia> rand(Int)
1969495256574935408
julia> Random.seed!(2);
julia> rand(Int)
6712802529292398593
julia> copy!(Random.default_rng(), rng);
julia> rand(Int)
1969495256574935408
Random.GLOBAL_RNG
代替 Random.default_rng()
以获得相同的结果。 Random.default_rng()
未被导出或记录。) Random.seed!
以恢复正在运行的随机数生成器的状态。我也对建议或讨论是否可能感兴趣。Random.seed!(Random.default_rng().seed)
是有效的,而在 Julia 1.7 中,这些信息存储在 Random.GLOBAL_SEED
中。 - Lufurand()
后,Random.GLOBAL_SEED
没有更新,但是在后续的调用中,rand()
产生了不同的输出,这表明它正在更新某个_不同的_内部状态。 - ForceBruRandom.default_rng().seed
无法运行,因为没有seed
属性。 - ForceBru
Random.default_rng().seed
显示type TaskLocalRNG has no field seed
;对于Random.GLOBAL_RNG.seed
同样如此;在调用rand()
后,Random.GLOBAL_SEED
没有更新,因此似乎还有更多隐藏的随机状态。 - ForceBru