我正在尝试编写基本模拟(队列),它依赖于生成随机expovariates。虽然Powershell提供了Get-Random函数,但您可以指定min和max,但它没有任何接近Python的random.expovariate(lambd)函数。
据说这是我应该遵循的模型:log(1- $ u)/( - λ)
优秀的Python文档可以这么说:
“Exponential distribution。lambd是1.0除以所需的平均值。它应该是非零的。(该参数将被称为”lambda“,但这是Python中的保留字。)返回值的范围从0到如果lambd为正,则为正无穷大;如果lambd为负,则为负无穷大为0。“在另一个描述中,“expovariate()产生一个指数分布,用于模拟均匀Poisson过程中的到达或间隔时间值,例如放射性衰变的速率或进入Web服务器的请求。
帕累托,或幂律,分布与许多可观察的现象相匹配,并由克里斯安德隆的书“长尾”推广。 paretovariate()函数可用于模拟个人资源分配(人们的财富,对音乐家的需求,对博客的关注等)。“
我曾尝试在Powershell中写这篇文章,但我的发行版已经过时了。如果我的平均值为3,我得到的结果非常接近我应该从平均值1得到的结果。我的代码是在John D. Cook's SimpleRNG C# library上建模的。
function GetUniform #GetUint
{
Return Get-Random -Minimum -0.00 -Maximum 1
}
# Get exponential random sample with specified mean
function GetExponential_SpecMean{
param([double]$mean)
if ($mean -le 0.0)
{
Write-Host "Mean must be positive. Received $mean."
}
$a = GetExponential
$R = $mean * $a
Return $R
}
# Get exponential random sample with mean 1
function GetExponential
{
$x = GetUniform
Return -[math]::log10(1-$x) # -Math.Log( GetUniform() );
}
cls
$mean5 = 1
$rangeBottom = 0.0
$rangeTop = 1.0
$j = 0
$k = 0
$l = 0
for($i=1; $i -le 1000; $i++){
$a = GetExponential_SpecMean $mean5
if($a -le 1.0){Write-Host $a;$j++}
if($a -gt 1.0){Write-Host $a;$k++}
if(($a -gt $rangeBottom) -and ($a -le $rangeTop)){#Write-Host $a;
$l++}
Write-Host " -> $i "
}
Write-Host "One or less: $j"
Write-Host "Greater than one: $k"
Write-Host "Total in range between bottom $rangeBottom and top $rangeTop : $l"
对于1000的样本和1的平均值($ mean5),我应该(我相信)500个结果为1.0或更少,500个结果大于1.0(1:1比率),但是我得到了比率约为9:1,平均值为1,比率约为53:47,平均值为3.
这个Stack Overflow问题中有一些讨论有一些好的背景,但它并不是特定于Powershell:Pseudorandom Number Generator - Exponential Distribution
答案 0 :(得分:1)
我看到你正在使用[Math]::log10()
,它是以10为基数的对数,我在链接中看到的所有函数都使用自然对数。您应该使用[Math]::Log()
代替log10。应该这样做。