我有一个函数,它接受一系列随机数/浮点数,并使用它们来生成一个值/结构(即,随机速度和一个球被抛出的点的位置,并输出它着陆的坐标) .我需要连续生成数千个。
我实现一切的方式是每个计算都接受一个 stdGen,使用它来生成几个数字,然后传递一个新的 stdGen 以允许它链接到另一个。
为了对 10000 个项目执行此操作,我从 generate_item n
制作了一个列表基本上输出一个 (value,gen)
元组(该值是我要计算的值),其中 gen
的值是从 generate_item n-1
中获取值所涉及的计算中递归输出的 stdGen
然而,这个程序似乎在大约一千个结果时爬行速度慢得不切实际。而且似乎绝对不可扩展。这可能与我存储所有 generate_item
的事实有关吗?结果在内存中?
或者在 Haskell 中使用 Monads 或其他比我上面描述的方法来解决这个问题的方法更符合习惯吗?
请注意,即使在 ruby 和 python 等高级脚本语言中,从随机值生成算法的代码也会在几秒钟内生成 10k;这些计算并不密集。
代码
-- helper functions that take in StdGen and return (Result,new StdGen)
plum_radius :: StdGen -> (Float,StdGen)
unitpoint :: Float -> StdGen -> ((Float,Float,Float),StdGen)
plum_speed :: Float -> StdGen -> (Float,StdGen)
-- The overall calculation of the value
plum_point :: StdGen -> (((Float,Float,Float),(Float,Float,Float)),StdGen)
plum_point gen = (((px,py,pz),(vx,vy,vz)),gen_out)
where
(r, gen2) = plum_radius gen
((px,py,pz),gen3) = unitpoint r gen2
(s, gen4) = plum_speed r gen3
((vx,vy,vz),gen5) = unitpoint s gen4
gen_out = gen5
-- Turning it into some kind of list
plum_data_list :: StdGen -> Int -> (((Float,Float,Float),(Float,Float,Float)),StdGen)
plum_data_list seed_gen 0 = plum_point seed_gen
plum_data_list seed_gen i = plum_point gen2
where
(_,gen2) = plum_data_list seed_gen (i-1)
-- Getting 100 results
main = do
gen <- getStdGen
let data_list = map (plum_data_list gen) [1..100]
putStrLn List.intercalate " " (map show data_list)
最佳答案
考虑只使用mersenne-twister 和vector-random package ,它经过专门优化以生成大量高质量的随机数据。
列表不适合分配大量数据 - 最好使用打包表示 - 除非您正在流式传输。
关于haskell - 在 Haskell 中程序生成大量值列表——最惯用的方法?内存管理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15266920/