php数组shuffle/randomize数组,所以没有两个相等的值不接近


php array shuffle/randomize array so no two equal values are not near

所以我有一个数组[ A,A,B,B,B,C,C,C,C,C ],我需要以一种方式洗牌/随机化,它会随机排列项目,但尽可能保持相等的值。最佳结果是[ C,A,B,C,A,B,C,B,C,C ]

到目前为止我的代码:

<?php
$UnitedList = [
    'A',
    'A',
    'B',
    'B',
    'B',
    'C',
    'C',
    'C',
    'C',
    'C'
];
$mixed_list = [];
$i = 0;
function getKey(&$array, $not) {
    $rk = array_rand($array);
    // echo $rk;
    if ($array[$rk] !== $not || count(array_unique($array)) === 1) {
        return $rk;
    }
    return getKey($array, $not);
}
while (!empty($UnitedList)) {
    $randomk = array_rand($UnitedList);
    if ( $i === 0 ) {
        $mixed_list[] = $UnitedList[$randomk];
        unset($UnitedList[$randomk]);
        ++$i;
        continue;
    }
    if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] !== $UnitedList[$randomk]) {
        $mixed_list[] = $UnitedList[$randomk];
        unset($UnitedList[$randomk]);
        ++$i;
        continue;
    }
    if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] === $UnitedList[$randomk]) {
        $newk = getKey($UnitedList, $UnitedList[$randomk]);
        $mixed_list[] = $UnitedList[$newk];
        unset($UnitedList[$newk]);
        ++$i;
        continue;
    }
    ++$i;
    continue;
}
print_r($mixed_list);

?>

最佳结果:

Array
(
    [0] => A
    [1] => C
    [2] => A
    [3] => C
    [4] => B
    [5] => C
    [6] => B
    [7] => C
    [8] => B
    [9] => C
)

最差结果:

Array
(
    [0] => A
    [1] => B
    [2] => A
    [3] => C
    [4] => B
    [5] => C
    [6] => B
    [7] => C
    [8] => C
    [9] => C
)

我需要以某种方式,不允许最差结果类型的结果,当一行中有3个C时,最好是至少有3个。C可以在阵列前面

因此,我对代码进行了一些调整

<?php
    function getKey(&$array, $not) {
        $rk = array_rand($array);
        if ($array[$rk] !== $not || count(array_unique($array)) === 1) {
            return $rk;
        }
        return getKey($array, $not);
    }
    function getRandomizedList($listToRandomize) {
        $mixed_list = [];
        $i = 0;
        shuffle($listToRandomize);
        while (!empty($listToRandomize)) {
            $randomk = array_rand($listToRandomize);
            if ( $i === 0 ) {
                $mixed_list[] = $listToRandomize[$randomk];
                unset($listToRandomize[$randomk]);
                ++$i;
                continue;
            }
            if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] !== $listToRandomize[$randomk]) {
                $mixed_list[] = $listToRandomize[$randomk];
                unset($listToRandomize[$randomk]);
                ++$i;
                continue;
            }
            if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] === $listToRandomize[$randomk]) {
                $newk = getKey($listToRandomize, $listToRandomize[$randomk]);
                if ($mixed_list[$i - 1] === $listToRandomize[$newk] && $mixed_list[0] !== $listToRandomize[$newk]) {
                    array_unshift($mixed_list, $listToRandomize[$newk]);
                } else {
                    $mixed_list[] = $listToRandomize[$newk];
                }
                unset($listToRandomize[$newk]);
                ++$i;
                continue;
            }
            ++$i;
            continue;
        }
        return $mixed_list;
    }

    $UnitedList1 = [
        'C',
        'C',
        'C',
        'C',
        'C',
        'A',
        'A',
        'B',
        'B',
        'B'
    ];
    $UnitedList2 = [
        'C',
        'C',
        'C',
        'C',
        'C',
        'A',
        'A',
        'A',
        'A',
        'A',
        'B',
        'B',
        'B'
    ];
    for ($i=0; $i < 5; $i++) {
        echo "UnitedList1 i = $i";
        print_r(getRandomizedList($UnitedList1));
        echo "--'n'r";
    }
    echo "------'n'r";

    for ($i=0; $i < 5; $i++) {
        echo "UnitedList2 i = $i";
        print_r(getRandomizedList($UnitedList2));
        echo "--'n'r";
    }
    echo "------'n'r";
 ?>

结果:

UnitedList1 i = 0Array
(
    [0] => C
    [1] => B
    [2] => C
    [3] => A
    [4] => B
    [5] => C
    [6] => A
    [7] => C
    [8] => B
    [9] => C
)
--
UnitedList1 i = 1Array
(
    [0] => C
    [1] => A
    [2] => B
    [3] => C
    [4] => A
    [5] => C
    [6] => B
    [7] => C
    [8] => B
    [9] => C
)
--
UnitedList1 i = 2Array
(
    [0] => C
    [1] => B
    [2] => A
    [3] => C
    [4] => B
    [5] => C
    [6] => A
    [7] => B
    [8] => C
    [9] => C
)
--
UnitedList1 i = 3Array
(
    [0] => C
    [1] => A
    [2] => B
    [3] => C
    [4] => A
    [5] => B
    [6] => C
    [7] => B
    [8] => C
    [9] => C
)
--
UnitedList1 i = 4Array
(
    [0] => C
    [1] => B
    [2] => C
    [3] => B
    [4] => A
    [5] => C
    [6] => B
    [7] => C
    [8] => A
    [9] => C
)
--
------
UnitedList2 i = 0Array
(
    [0] => C
    [1] => A
    [2] => C
    [3] => A
    [4] => C
    [5] => A
    [6] => B
    [7] => C
    [8] => B
    [9] => C
    [10] => A
    [11] => B
    [12] => A
)
--
UnitedList2 i = 1Array
(
    [0] => C
    [1] => A
    [2] => C
    [3] => A
    [4] => C
    [5] => A
    [6] => B
    [7] => C
    [8] => A
    [9] => C
    [10] => B
    [11] => A
    [12] => B
)
--
UnitedList2 i = 2Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => A
    [4] => C
    [5] => A
    [6] => C
    [7] => B
    [8] => A
    [9] => C
    [10] => B
    [11] => C
    [12] => A
)
--
UnitedList2 i = 3Array
(
    [0] => C
    [1] => A
    [2] => C
    [3] => B
    [4] => A
    [5] => C
    [6] => B
    [7] => A
    [8] => B
    [9] => A
    [10] => C
    [11] => A
    [12] => C
)
--
UnitedList2 i = 4Array
(
    [0] => A
    [1] => C
    [2] => A
    [3] => B
    [4] => C
    [5] => B
    [6] => A
    [7] => C
    [8] => A
    [9] => B
    [10] => C
    [11] => A
    [12] => C
)
--
------

第三次尝试:

<?php
    $groups = [
        [ 'A','A' ],
        [ 'B','B','B' ],
        [ 'C','C','C','C','C' ]
    ];
    function generateRandomList($groups) {
        $output = [];
        $prev_k = null;
        shuffle($groups);
        do {
            $active_group_k = array_rand($groups);
            if ($prev_k === $active_group_k && count($groups) > 1) {
                continue;
            }
            $output[] = array_pop($groups[$active_group_k]);
            if (empty($groups[$active_group_k])) {
                unset($groups[$active_group_k]);
            }
            $prev_k = $active_group_k;
        } while (!empty($groups));
        return $output;
    }
    echo "randomize when in groups: 'n";
    for ($i=0; $i < 5; $i++) {
        echo json_encode(generateRandomList($groups)) . "'n";
    }
    echo "--- 'n";
    function getKey(&$array, $not) {
        $rk = array_rand($array);
        if ($array[$rk] !== $not || count(array_unique($array)) === 1) {
            return $rk;
        }
        return getKey($array, $not);
    }
    function getRandomizedList($listToRandomize) {
        $mixed_list = [];
        $i = 0;
        shuffle($listToRandomize);
        while (!empty($listToRandomize)) {
            $randomk = array_rand($listToRandomize);
            if ( $i === 0 ) {
                $mixed_list[] = $listToRandomize[$randomk];
                unset($listToRandomize[$randomk]);
                ++$i;
                continue;
            }
            if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] !== $listToRandomize[$randomk]) {
                $mixed_list[] = $listToRandomize[$randomk];
                unset($listToRandomize[$randomk]);
                ++$i;
                continue;
            }
            if (isset($mixed_list[$i - 1]) && $mixed_list[$i - 1] === $listToRandomize[$randomk]) {
                $newk = getKey($listToRandomize, $listToRandomize[$randomk]);
                if ($mixed_list[$i - 1] === $listToRandomize[$newk] && $mixed_list[0] !== $listToRandomize[$newk]) {
                    array_unshift($mixed_list, $listToRandomize[$newk]);
                } else {
                    $mixed_list[] = $listToRandomize[$newk];
                }
                unset($listToRandomize[$newk]);
                ++$i;
                continue;
            }
            ++$i;
            continue;
        }
        return $mixed_list;
    }

    $UnitedList1 = [
        'A',
        'A',
        'B',
        'B',
        'B',
        'C',
        'C',
        'C',
        'C',
        'C'
    ];
    echo "randomize when all in one array: 'n";
    for ($i=0; $i < 5; $i++) {
        echo json_encode(getRandomizedList($UnitedList1)) . "'n";
    }
?>

和结果:

randomize when in groups: 
["A","C","A","C","B","C","B","C","B","C"]
["C","A","C","B","A","C","B","C","B","C"]
["C","A","C","B","C","A","B","C","B","C"]
["C","A","C","B","A","C","B","C","B","C"]
["A","B","A","B","C","B","C","C","C","C"]
--- 
randomize when all in one array: 
["C","A","C","B","C","B","A","C","B","C"]
["C","B","C","A","C","B","C","A","B","C"]
["C","B","A","C","A","C","B","C","B","C"]
["C","B","A","B","C","A","C","B","C","C"]
["C","A","C","A","C","B","C","B","C","B"]

看来,这种分组没有帮助!

  1. try-no我做了它来检查,是否有任何值等于之前的值,如果是,则重新生成

代码:

<?php
    $groups = [
        [ 'A','A' ],
        [ 'B','B','B' ],
        [ 'C','C','C','C','C' ]
    ];
    function generateRandomList($groups) {
        $output = [];
        $prev_k = null;
        $orginal_groups = $groups;
        shuffle($groups);
        do {
            $active_group_k = array_rand($groups);
            if ($prev_k === $active_group_k && count($groups) > 1) {
                continue;
            }
            $output[] = array_pop($groups[$active_group_k]);
            if (empty($groups[$active_group_k])) {
                unset($groups[$active_group_k]);
            }
            $prev_k = $active_group_k;
        } while (!empty($groups));
        foreach ($output as $key => $value) {
            if ($key > 0) {
                if ($value === $output[$key - 1]) {
                    $output = generateRandomList($orginal_groups);
                }
            }
        }
        return $output;
    }
    echo "randomize when in groups: 'n";
    for ($i=0; $i < 5; $i++) {
        echo json_encode(generateRandomList($groups)) . "'n";
    }

结果:

randomize when in groups: 
["A","C","A","C","B","C","B","C","B","C"]
["C","B","A","C","A","C","B","C","B","C"]
["A","C","A","C","B","C","B","C","B","C"]
["C","A","C","A","C","B","C","B","C","B"]
["C","A","C","A","C","B","C","B","C","B"]