关于随机:在朱莉娅中检索RNG种子

Retrieve RNG seed in julia

在Julia,全球RNG的种子可以用

1
srand(SEED)

如何检索全局RNG的种子或当前状态,例如稍后再检索?

目标是在任何给定的时间点获取RNG的状态,并在不同的会话中重新创建它,而不知道同时发生的对RNG的初始种子或所有调用。

例如,R允许通过

1
.Random.seed

我希望茱莉亚也能有同样的方法。


Base.Random.RANDOM_SEED是你获得种子的朋友:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

这没有文档记录,但源代码很容易阅读。我不知道如何获取RNG的当前状态,但它可能在dSFMT模块中。


你应该得到这样的种子

1
reinterpret(Int32, Base.Random.GLOBAL_RNG.seed)

测试:

1
2
3
4
5
julia> srand(123456789);

julia> reinterpret(Int32, Base.Random.GLOBAL_RNG.seed)
1-element Array{Int32,1}:
 123456789

为了保存恢复完整的RNG状态,您可以做一些简单的事情,只需存储整个Base.Random.GLOBAL_RNG对象。一个简单的方法是使用jld包。

在我的私有包中,我手动将RNG状态保存/读取到HDF5,请参见此处。

编辑:这当然是@iaindunning答案的更明确版本


使用带有显式变量(而不是默认随机值函数提供的隐藏全局变量)的专用mersennetwester,可以提供所需的功能:

1
2
3
4
5
6
7
8
9
10
11
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

埃多克斯一号〔3〕在那里把我扔了一秒钟。此外,访问全局随机生成器状态会更容易,但可能需要ccalling libdsfmt库(见random.jldSFMT.jlin Base


为了在函数和一般情况下使用随机生成器时更好地控制,

1
2
3
4
5
6
RND = srand(0)
function coolfun()
    println(RND.idx)
    output = srand(RND, 100)
    ...
end

一个明显的解决方案是在调用srand(seed)之前保存seed值。

或者,如果您知道正在使用的RNG,并且它在密码学上不安全,那么您可以从它产生的伪随机数中计算出值。例如,请参见分解线性同余生成器