【发布时间】:2013-02-22 09:35:00
【问题描述】:
我有一个函数,它采用一系列随机数/浮点数,并使用它们来生成一个值/结构(即,获取一个随机速度和一个球被抛出的点的位置,并输出它的坐标会降落)。而且我需要连续生成几千个。
我实现所有东西的方式是每次计算都接受一个 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)
【问题讨论】:
-
您介意发布您正在使用的代码吗,通常更容易理解并帮助创建一个可以使用的示例。
-
在代码中添加;希望有帮助!
-
plum_data_list到底是怎么回事,它生成了一堆点并将它们全部扔掉,但第一个?这可能不是您想要的——请参阅我的答案,了解如何编写一个生成随机事物列表的函数。 -
@luqui 好吧,
plum_data_list中的项目是按顺序访问的,所以我想我有点天真地假设它们被缓存了。