需要一个从正态(高斯)分布返回样本的随机数生成器,我已将以下部分移植到 F#John D. Cook 的 C# 生成器 http://www.codeproject.com/Articles/25172/Simple-Random-Number-Generation:
let mutable m_w = 521288629u
let mutable m_z = 362436069u
let private getUint () =
m_z <- 36969u * (m_z &&& 65535u) + (m_z >>> 16)
m_w <- 18000u * (m_w &&& 65535u) + (m_w >>> 16)
(m_z <<< 16) + m_w
let private setSeed () =
let dt = System.DateTime.Now
let x = dt.ToFileTime ()
m_w <- uint32 (x >>> 16)
m_z <- uint32 (x % 4294967296L)
let private getUniform () =
let u = getUint ()
(float u + 1.) * 2.328306435454494e-10
let private randomNormal () =
let u1 = getUniform ()
let u2 = getUniform ()
let r = sqrt (-2. * (log u1))
let theta = 2. * System.Math.PI * u2
r * sin (theta)
/// Returns a normal (Gaussian) random sample with mean 0 and standard deviation 1
let randn () =
setSeed ()
randomNormal ()
/// Returns an array of normal (Gaussian) random samples
let randns n m =
setSeed ()
[| for i in 0 .. n - 1 -> randomNormal () |]
此实现工作正常,但不是线程安全的。鉴于依赖它的代码广泛使用线程并行库,我需要使其线程安全。
这对我来说并不明显,因为该方法的核心在于两个几乎不可或缺的可变成员。有没有其他方法可以在不使用锁的情况下实现线程安全?
有没有其他方法可以仅使用不可变成员来实现普通的伪随机生成器?
使用可变成员,你别无选择,只能使用锁。
但是,你最好使用不可变的record http://msdn.microsoft.com/en-us/library/dd233184.aspx含有m_w
and m_z
您传递给随机函数。他们可以返回随机值的元组和包含更新的随机成员的新记录。更好的是,您可以创建一个计算表达式 http://msdn.microsoft.com/en-us/library/dd233182.aspx处理生成随机数,这样您就不必担心传递随机记录。
另外,打电话setSeed
从你的随机函数内部来看是很糟糕的。多次后续调用将返回相同的值。您只想设置种子一次。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)