在Powershell中,如何生成具有指定均值的随机变量(指数)?

时间:2015-06-27 04:35:19

标签: powershell random discrete-mathematics poisson exponential-distribution

我正在尝试编写基本模拟(队列),它依赖于生成随机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

1 个答案:

答案 0 :(得分:1)

我看到你正在使用[Math]::log10(),它是以10为基数的对数,我在链接中看到的所有函数都使用自然对数。您应该使用[Math]::Log()代替log10。应该这样做。