Elm随机生成器,时间戳作为initialSeed

dev*_*ide 3 random elm

我编写了一个简单的代码,显示 Random.bool 每毫秒出现 True 或 False 的时间。生成器以当前时间戳作为种子生成布尔值。

我预计布尔值几乎每次迭代都会改变,但我得到了意想不到的大系列 True 或 False。

这是怎么回事?

编辑:我使用 boolRandom (time*time) 得到了更好的结果。

share-elm 0.15 上的实时预览,带有 Random.int 0 1

这里是 0.16 中的 Random.bool :

import Signal
import Random
import Time exposing (Time)
import Graphics.Element exposing (Element, show, flow, down)

type alias Stat = {time: Time, true: Int, false: Int}

newStat: Stat
newStat = Stat 0 0 0 

scene : Stat -> Element
scene stat = 
  flow down 
    [ "Time: "++(toString stat.time)  |> show
    , "True: "++(toString stat.true)  |> show
    , "False: "++(toString stat.false)  |> show
    ]

boolRandom : Time -> Bool
boolRandom time = 
  Random.generate Random.bool (Random.initialSeed (round time)) |> fst

updateData : Time -> Stat -> Stat
updateData time stat = 
  if boolRandom time == True 
    then {stat | time = time , true = stat.true+1} 
    else {stat | time = time , false = stat.false+1} 

updateEvery : Signal Stat
updateEvery = 
  Signal.foldp updateData newStat (Time.every Time.millisecond)

main = Signal.map scene updateEvery
Run Code Online (Sandbox Code Playgroud)

mgo*_*old 5

不要使用当前时间作为随机种子,因为正是您遇到的问题。您应该在程序中只调用Random.initialSeed一次(这意味着一次调用,而不是在一个被调用 N 次的函数中)。每当你生成一个随机数时,它都会给你一个新的种子,你应该将种子保留在类型Stat而不是时间中。然后:

updateData : Time -> Stat -> Stat
updateData time stat = 
  let (bool, seed) = Random.generate Random.bool stat.seed
  in if bool
     then {stat | seed = seed , true = stat.true+1} 
     else {stat | seed = seed , false = stat.false+1}
Run Code Online (Sandbox Code Playgroud)

您也可以删除boolRandom- 扔掉新种子fst是不好的!

那么,首先如何获得好的随机种子呢?当前时间实际上是一个糟糕的选择,因为它不是均匀分布的。相反,Math.floor(Math.random()*0xFFFFFFFF)在您选择的 JS 控制台中进行评估并粘贴结果。要获得每次运行都不同的程序,请通过端口传递计算该表达式的结果。