Php随机序列发生器

时间:2014-02-07 16:58:15

标签: php random sequence

我希望创建一个包含与我的条件相对应的随机序列的数组。

  1. 序列应由1-8个8个不同的数字组成。
  2. 前4个或后4个数字不应超过2个连续数字。例如:1,2,3不好也不是5,3,4 因为它们是连续的(3,4,5)。
  3. 这是一个很好的例子:1,4,5,7,| 8,6,3,2

    这不是一个好例子:1,3,2,6,| 5,7,8,4因为1,3,2是连续数字,如果在前4位中排序(1,2,3)

    我做到了:

             $sequences = array();
        while(count($sequences) < 100){
    
            //Random 8 numbers sequence from 1-8
             $sequence = array();  
        while(count($sequence) < 8){
                $rand = rand(1,8);
          if(!in_array($rand, $sequence)){
                array_push($sequence, $rand);
             }
          }
    
            //Insert if numbers are not successive. 
            //Struggling here
            if(?????){
                array_push($sequences, $sequence);
            }
        }
               print_r($sequences); 
    

    它适用于它的生成部分,但我无法确定如何插入不包含连续数字的序列。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您可以将两组数字表示为1或0,并通过选择其中一个8位二进制字符串(四个1和0)以及没有3个连续1或0的序列来选择每个集合中的哪些元素。这些二进制字符串中的每一个都由以下整数之一表示:

 43  45  51  53  54  75  77  83  85  86  89  90 101 102 105 106 108
147 149 150 153 154 165 166 169 170 172 178 180 201 202 204 210 212

下半部分与前半部分都是对称的,所以我们可以从上半部分中选出一个数字,然后进行一些处理以选择整个集合:

$combinations = array(43,45,51,53,54,75,77,83,85,86,89,90,101,102,105,106,108);

// Pick a random combination
$combination = $combinations[array_rand($combinations)];
if (mt_rand() & 1)
    $combination = 255 - $combination;  
$combination = str_split(str_pad(decbin($combination), 8, '0', STR_PAD_LEFT));

// Get the first four values
$first = array_keys(array_filter($combination, function($x){ return $x == '0'; }));
shuffle($first); // Permute them

// Get the last four values
$last = array_keys(array_filter($combination, function($x){ return $x == '1'; }));
shuffle($last); // Permute them

$result = array_map(function($x){ return $x + 1; }, array_merge($first, $last));

这将是随机序列,您的约束一致随机,应该非常有效。一些样本输出:

[6, 2, 3, 8, 1, 4, 5, 7]
[1, 6, 2, 4, 3, 5, 8, 7]
[6, 3, 1, 8, 2, 4, 5, 7]
[5, 8, 4, 2, 7, 1, 6, 3]
[5, 2, 8, 1, 3, 6, 7, 4]
[8, 6, 2, 4, 7, 1, 3, 5]
[7, 1, 5, 4, 8, 3, 2, 6]
[5, 1, 3, 6, 2, 7, 8, 4]
[1, 7, 2, 5, 3, 8, 4, 6]
[5, 6, 3, 8, 2, 7, 4, 1]

答案 1 :(得分:0)

这可能是一种无效的方式(在资源方面),可能更多地被视为黑客攻击,但是;

$sequence = array(1,2,4,5,8,9,5,7);
    usort($sequence, function($a, $b) {
        //if $a + 1 = $b, then $b + 1;
        return ($a + 1) == $b ? $b = $b + 1 : 1;
    });

print_r($sequence);

这会回来;

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

答案 2 :(得分:0)

这不是一个非常漂亮的代码,我可以缩短它但仍然有效。

    $sequence = array();
    $sequences = array();
    $loops = 0;

    while($loops < 10000){
        $loops++;
        //Get a sequence
        while(count($sequence) < 8){
            $rand = rand(1,8);
            if(!in_array($rand, $sequence)){
                array_push($sequence, $rand);
            }
        }

        //Checks if sequence meet requirements
        //This part could be summarized in a function
        $first = array($sequence[0], $sequence[1], $sequence[2],$sequence[3]);
        $last = array($sequence[4], $sequence[5], $sequence[6],$sequence[7]);

        sort($first);
        sort($last);

        if($first[1] != $first[0]+1 || $first[1] !=$first[2]-1){
            if($first[2] != $first[1]+1 || $first[2] !=$first[3]-1){
                if($last[1] != $last[0]+1 || $last[1] !=$last[2]-1){
                    if($last[2] != $last[1]+1 || $last[2] !=$last[3]-1){

                        $sequence = array_merge($first, $last);
                        if(!in_array($sequence, $sequences)){
                            array_push($sequences, $sequence);
                        }
                    }
                }
            }
        }

        $sequence = array();        
    }
    print_r($sequences);