为什么在Clojure中使用种子时不会重复生成可重复的随机数? [英] Why doesn't repeatedly generate reproducible random numbers when using a seed in Clojure?
问题描述
我有一些需要一系列随机数的函数,所以我已经采取了一些简单的原语,例如#(inc(g / uniform 0 n))
似乎不能产生可重复的一系列随机数,即使我重新绑定 * rnd *
,除非我如下所示生成它们。我不能想象这是最好的方式,所以任何人都可以指出如何做得更好?
I have some functions that require a series of random numbers so I've taken some simple primitives such as #(inc (g/uniform 0 n))
and I can't seem to generate a reproducible series of random numbers, even though I'm rebinding *rnd*
, unless I generate them as shown below. I can't imagine that's the best way, so can anyone point out how to do it better?
注意:我运行下面的每个例子三次,如图所示,给定结果。
Note: I run each example below three times as shown to produce the given results.
(ns example.show
(:require [clojure.data.generators :as g]))
(binding [g/*rnd* (java.util.Random. 42)]
(take 10 (repeatedly #(inc (g/uniform 0 n))))
=> (9 4 5 4 4 5 1 8 2 9)
=> (2 1 1 6 3 10 10 4 1 9)
=> (10 4 7 8 9 6 10 1 8 3)
(binding [g/*rnd* (java.util.Random. 42)]
(g/reps 10 #(inc (g/uniform 0 n)))
=> (3 9 4 6 3 8 6 6 5 4)
=> (7 8 4 7 7 5 7 4 8 7)
=> (2 8 7 8 8 8 9 2 6 5)
;; This seems to work
(binding [g/*rnd* (java.util.Random. 42)]
(letfn [(roll [n] #(inc (g/uniform 0 n)))]
[((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10)) ((roll 10))]))
=> [8 7 4 3 7 10 4 3 5 8]
=> [8 7 4 3 7 10 4 3 5 8]
=> [8 7 4 3 7 10 4 3 5 8]
推荐答案
因为懒惰。在序列实现之前,从 binding
返回。因此,惰性序列永远不会看到您设置的绑定。一个解决方案是在绑定内的序列上强制实现 doall
。
Because of laziness. You return from binding
before the sequence is realized. Therefore, the lazy sequence never sees the bindings you set. One solution would be to force realization with a doall
on the sequence inside the binding.
这篇关于为什么在Clojure中使用种子时不会重复生成可重复的随机数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!