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

时间:2016-04-01 07:39:20

标签: php

所以我有一个数组[ 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);

&GT;

最佳结果:

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可以更好地在数组前面

3 个答案:

答案 0 :(得分:0)

所以,我对代码进行了一些调整

<?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
)
--

------

答案 1 :(得分:0)

第三次尝试:

<?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"]

看来,分组没有帮助!

答案 2 :(得分:0)

  1. 尝试 - 没有我检查,如果有任何值等于之前的值,如果是,则重新生成。
  2. 代码:

    <?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"]