【问题标题】:Seeding SML/NJ's RNG on a Windows machine在 Windows 机器上播种 SML/NJ 的 RNG
【发布时间】:2017-03-27 01:43:21
【问题描述】:

如何在 Windows 机器上播种 SML/NJ 的随机数生成器?

函数Random.rand() 接受一对整数,并使用它们作为随机数生成器的种子。根据我对其他编程语言的经验,我希望有一种相对简单的方法可以根据系统时钟来播种它(类似于 C 中的srand(time(null));)。除非我忽略了一些明显的东西,否则似乎没有任何直接的方法,至少如果您使用的是 Windows。

我能在 SML 中找到最接近 time(null) 的是 Posix.ProcEnv.time,它返回 Unix 纪元时间。不幸的是,Posix 结构不是 Windows 下载的一部分,Windows 结构(它是)似乎不包括time 的任何直接类似物。

Timer 结构确实有方法可以实时确定经过。我可以编写一个函数来进行大约半秒的无意义计算,计算需要多长时间,然后找出一种从中提取几个整数的方法。但是:1)对于大多数语言中微不足道的事情来说,这是一项非常艰巨的工作,2)更重要的是——它似乎可能导致同一个种子被重用的次数不平凡。

我的另一个想法是,如果我可以访问 Windows 环境变量 "TIME",我就可以使用它。以下将时间打印到 repl:

OS.Process.system "TIME/T";

但不提供对打印字符串的任何编程访问。

OS.Process.getEnv "TIME";

听起来很有希望,但返回 NONE

如果在 SML/NJ 中确实没有简单的解决方案 - 是否有适用于 SML 的其他一些实现(例如 Poly/ML)的选项?

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    基础库的TIME签名具有返回当前时间的功能。

    val now: unit -> t
    

    【讨论】:

    • 应该可以。奇怪的想法是,我不止一次看过Time,但忽略了这一点。我的印象是 Time 旨在解析从 Timer 返回的值,但它本身不包含时钟信息。
    • 我在正常基础文档中也错过了它,将更新答案以反映其标准功能
    【解决方案2】:

    @matt 回答了问题本身,以便携式方式读取系统时钟。为了补充他的答案,这里有一个种子函数。作为一个技术问题,自 1970 年以来经过的秒数对于 SML/NJ 31 位整数来说太大了。我当然可以使用大整数,但一个简单的解决方案似乎是在转换为整数之前减少 14.8 亿(并使用时间的小数部分来获取第二个整数种子参数):

    fun seed () = 
        let
            val r = Time.toReal(Time.now()) - 1.48e9
            val f = Real.realFloor(r)
            val d = r - f
            val i = Real.floor(f)
            val j = Real.floor(1000.0*d)
        in
            Random.rand(i,j)
        end;
    

    几乎肯定有一种更原则的方法可以做到这一点,但上述方法有效:

    - val s = seed ();
    val s =
      RND
        {borrow=ref false,congx=ref 0wx4B7CD4CA,index=ref 0,
         vals=[|0wx40E9888B,0wx6F1B97FD,0wx4011C479,0wx2012F528,0wx3CDC0237,
               0wx7C36E91D,0wx5361B64D,0wx4B61A297,0wx61823821,0wx7C6CD6BD,
               0wx1683CA4D,0wx670A75AF,...|]} : Random.rand
    - Random.randRange(1,100) s;
    val it = 35 : int
    - val s = seed ();
    val s =
      RND
        {borrow=ref false,congx=ref 0wx512EBCFC,index=ref 0,
         vals=[|0wx456E115A,0wx27817499,0wx46A6BE48,0wx2C79BB3,0wx3FF47B4D,
               0wx5B48FC93,0wx53C3647F,0wx32E40F5A,0wx157AB4C8,0wx16E750D,
               0wx78BD3EA3,0wx7885CA23,...|]} : Random.rand
    - Random.randRange(1,100) s;
    val it = 73 : int
    

    不是很令人兴奋,但是相隔几秒钟的连续播种会产生不同的输出,正如预期的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      • 2011-11-24
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 2013-01-30
      相关资源
      最近更新 更多