php - 如何在php中实现特殊的shuffle功能

标签 php arrays sorting random shuffle

我需要一个类似于 shuffle 的函数来随机化数组,不同之处在于每个元素都有不同的机会。

例如,考虑以下数组:

$animals = array('elephant', 'dog', 'cat', 'mouse');

大象比狗更有机会进入第一个索引。狗的机会比猫高等等。例如,在这个特定的例子中,大象可能有 40% 的机会获得第一位置,30% 的机会获得第二位置,20% 的机会获得第三位置,10% 的机会获得最后位置。

因此,在打乱之后,原始数组中的第一个元素将更有可能(但不确定)位于第一个位置,而最后一个元素则更有可能位于最后一个位置。

最佳答案

正常的随机播放可以像这样实现

  • 在一定范围内随机掉落元素
  • 从左到右拾取它们

我们可以调整下降步骤,将每个元素不下降到整个范围,而是下降到某个滑动窗口。令N 为数组中元素的数量,窗口宽度为w,我们将在每一步将其移动off。那么 off*(N-1) + w 将是范围的总宽度。

这是一个函数,它会扭曲元素的位置,但不是完全随机的。

function weak_shuffle($a, $strength) {
    $len = count($a);
    if ($len <= 1) return $a;
    $out = array();
    $M = mt_getrandmax();
    $w = round($M / ($strength + 1)); // width of the sliding window
    $off = ($M - $w) / ($len - 1); // offset of that window for each step.
    for ($i = 0; $i < $len; $i++) {
        do {
            $idx = intval($off * $i + mt_rand(0, $w));
        } while(array_key_exists($idx, $out));
        $out[$idx] = $a[$i];
    }
    ksort($out);
    return array_values($out);
}
  • $strength = 0 ~正常洗牌。
  • $strength = 0.25 ~您想要的结果(大象为 40.5%、25.5%、22%、12%)
  • $strength = 1 第一项永远不会在最后一项之后。
  • $strength >= 3 数组实际上从未被打乱

测试 Playground :

$animals = array( 'elephant', 'dog', 'cat', 'mouse' );
$pos = array(0,0,0,0);
for ($iter = 0; $iter < 100000; $iter++) {
    $shuffled = weak_shuffle($animals, 0.25);
    $idx = array_search('elephant', $shuffled);
    $pos[$idx]++;
}
print_r($pos);

关于php - 如何在php中实现特殊的shuffle功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9811562/

相关文章:

php - 具有大小属性​​的选择框是否适用于 $_POST?

php - 分页模式统计表的总记录数

php - 在同一服务器的外部脚本中使用自定义函数获取 WordPress 用户元数据

python - 按多列排序时为每列设置升序降序

java - 使用 Java 8 lambdas 按不同元素对数组列表进行排序

php - 单击链接后,我试图在 div 中包含一个页面,但它不起作用

javascript - js中迭代对象数组: skip when undefined

java - Java 中的 2D Int 数组反转

c++ - 请帮我用 C 或 C++ 排序

javascript - 将json对象插入javascript中的有序数组