在PHP中,如何将0和1之间的浮点概率(包括0和1)转换为数组索引?

nbnkbykc  于 12个月前  发布在  PHP
关注(0)|答案(1)|浏览(173)

我正在寻找一种方法来转换0和1之间的浮点值,包括,到数组索引。
我们的想法是根据一个浮点概率值随机选择一个数组元素。我想出了下面的代码,它试图这样做1000次。然后跟踪每个值在$counts数组中被选择的频率。
get_rand_index_1()函数使用round(),$count - 1。这里的问题是第一个和最后一个索引,在本例中为0/Apples和5/Pineapples,只被选中一半。导致$counts类似于:

Array
(
    [Apples] => 142
    [Oranges] => 236
    [Bananas] => 269
    [Pineapples] => 104
    [Pears] => 249
)

字符串
我还写了get_rand_index_2()。它使用floor()而不是round(),使用$count而不是($count - 1)。我认为这可以完成任务,但如果浮点数为1,则会有一个问题。在这种情况下,索引将无效。当然,这是极不可能的,但理论上仍然是可能的。如果一次生成数百万个随机值,可能会有问题。
所以我减去了1 / mt_getrandmax()。然后在极少数情况下,数字变成负数,我使用max(0,.)。
我认为这个get_rand_index_2()可以工作,结果$counts数组似乎有均匀分布的值。但它似乎有点笨拙。而且我不确定它是否是最有效的方法。
有没有更优雅或更有效的方法来做我想做的事?
下面是我正在测试的代码。

<?php

$array = ["Apples", "Bananas", "Oranges", "Pears", "Pineapples"];
$count = count($array);
$counts = [];
for ($i = 0; $i < 1000; $i++) {
    //$index = get_rand_index_1($count);
    $index = get_rand_index_2($count);
    $value = $array[$index];
    if (!isset($counts[$value])) $counts[$value] = 1;
    else $counts[$value]++;
}
print_r($counts);

function get_rand_index_1(int $count)
{
    $float_rand = mt_rand() / mt_getrandmax();
    $index = round($float_rand * ($count - 1));
    return $index;
}

function get_rand_index_2(int $count)
{
    $float_rand = max(0, mt_rand() / mt_getrandmax() - 1 / mt_getrandmax());
    $index = floor($float_rand * $count);
    return $index;
}

w1jd8yoj

w1jd8yoj1#

尝试下面的函数,通过将随机float缩放到数组长度,使用floor进行舍入,并确保索引保持在范围内,来均匀分布随机索引选择。

function get_rand_index(int $count) {
    $float_rand = mt_rand() / mt_getrandmax();
    $index = floor($float_rand * $count);
    $index = min($index, $count - 1);
    return $index;
}

字符串

相关问题