Serialization 序列化OCaml的StdLib中“模块随机”的当前状态

Serialization 序列化OCaml的StdLib中“模块随机”的当前状态,serialization,random,ocaml,standard-library,Serialization,Random,Ocaml,Standard Library,我一定读过标准库模块Random and Random上的OCaml手册页面。State六次,可能更频繁,但我不知道如何序列化PRNG的当前内部状态 以下是我到目前为止学到的: 模块Random和Random.State都在从外部抽象/不透明的状态下运行 这两个模块都提供两个/三个初始值设定项,但导出当前状态的函数。。。我看不到他们: 我能做什么?救命啊 您可以使用模块序列化和反序列化状态,例如 let save_random_state out = Marshal.to_channel

我一定读过标准库模块Random and Random上的OCaml手册页面。State六次,可能更频繁,但我不知道如何序列化PRNG的当前内部状态

以下是我到目前为止学到的:

模块Random和Random.State都在从外部抽象/不透明的状态下运行

这两个模块都提供两个/三个初始值设定项,但导出当前状态的函数。。。我看不到他们:


我能做什么?救命啊

您可以使用模块序列化和反序列化状态,例如

let save_random_state out = 
   Marshal.to_channel out (Random.get_state ()) []

let load_random_state inp = 
   Random.set_state (Marshal.from_channel inp)
但是,如果您只是希望随机模块生成相同的伪随机数序列,而不是使用相同的状态初始化,例如,使用相同的种子,例如,如果您将以

let () = Random.set_state (Random.State.make [|42|])

您将获得程序的确定性行为,因为随机模块将始终生成相同的数字。

在初始化期间进行种子设定是可以的,但是,当最初的UNIX进程早已结束,并且启动了一个新进程来完成部分工作时,它无法恢复冗长的计算。因此,该计划看起来像s |>Marshal.to_string |>Z.of_bits,以将该状态转换为一个Zarith大整数。相当多的工作,但可以理解。谢谢。我认为这是个坏主意。同样,如果您只想控制状态,请使用Random.set_state并将您的状态放在那里。如果您的状态aka seed表示为Z.t数字,则将其转换为字节数组并使用此数组作为种子。您是对的!从随机状态变为Z.t不是一个好主意。动态键入来拯救:My Prolog的random:setrand/1谓词将同时使用Prolog原子来精确表示random.States和Prolog数字整数/浮点;第一种方法可以精确再现前一种状态,后一种方法可以方便地以亚秒级的精度播种UNIX时间。谢谢顺便说一句,这就像SICStus Prolog做的一样。Prolog实现者中有一句谚语是这样的:在不确定的情况下,像SICStus一样去做。哈哈,只是认真的: