如何在php中执行特殊的shuffle功能

Dio*_*ira 2 php arrays sorting random shuffle

我需要一个函数来随机化一个类似于shuffle的数组,不同的是每个元素有不同的机会.

例如,请考虑以下数组:

$animals = array('elephant', 'dog', 'cat', 'mouse');
Run Code Online (Sandbox Code Playgroud)

大象获得第一个指数的几率高于狗.狗比猫有更高的机会等等.例如,在这个特殊的例子中,大象可能有40%的机会获得第一名,30%获得第二名,20%获得第三名,10%获得最后一名.

因此,在改组之后,原始数组中的第一个元素将更有可能(但不是肯定)位于第一个位置,最后一个位于最后位置.

kir*_*oid 5

正常混洗可以实现为

  • 在某个范围内随机丢弃项目
  • 从左到右拾起它们

我们可以调整下降步骤,将每个元素放入不是整个范围,但是在某个滑动窗口.让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);
}
Run Code Online (Sandbox Code Playgroud)
  • $strength = 0 〜正常洗牌.
  • $strength = 0.25〜你想要的结果(40.5%,25.5%,22%,12%elephant)
  • $strength = 1 第一项永远不会在最后一项之后.
  • $strength >= 3 数组实际上从来没有洗过

游乐场进行测试:

$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);
Run Code Online (Sandbox Code Playgroud)