存在给定的有限长度 N 的浮点序列(介于 0 和 1 之间),表示整数 0..N-1 上的分布函数。我们试图从这个分布中抽取一个随机数。一种方法是在 [0, 1](浮点数)中绘制一个均匀随机变量,然后计算该数字的逆累积分布函数。
如果分布在数组中,则代码将如下所示:
let matched distribution draw =
let rec matchRest distribution draw start =
if start = Array.length distribution then start-1
else
let left = draw - distribution.[start]
if left <= 0 then start
else matchRest distribution left (start+1)
matchRest distribution draw 0
where distribution
是分布函数并且draw
是统一的[0,1]数。
当分布是任意序列时,如何重写此函数以使其工作?显然我可以创建一个临时数组,但这似乎不是一个优雅的解决方案......
Your matched
函数是一个搜索过程。您不必分解序列来搜索合适的索引;高阶函数来自序列模块 http://msdn.microsoft.com/en-us/library/ee353635.aspx可以帮助你:
/// Taken from http://missingfaktor.blogspot.in/2012/02/f-option-cheat-sheet.html
let getOrElse d = function
| Some a -> a
| None -> d
let matched distribution draw =
distribution
|> Seq.scan (fun (s, d0) d -> (s+1, d0-d)) (0, draw)
|> Seq.tryPick (fun (s, d) -> if d <= 0 then Some s else None)
|> getOrElse (Seq.length distribution-1)
在最坏的情况下,您仍然可以通过以下方式枚举整个序列Seq.length
。我认为最好改变一下Seq.length distribution-1
如果可能的话,为已知常数。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)