在PHP中生成一个随机数不接近X上一个元素的数组


Generate an array in PHP of random number not close to the X previous element

我想在PHP中生成一个随机数数组,但每个数字都不应该与前面的任何X(例如2)个数字相同,甚至不应该与它们中的任何一个接近一个定义范围(例如5)。

例如:

  • 我需要1到100之间的数字
  • 我已将"范围"设置为5
  • 前两个生成的数字是20和50
  • 第三个数字将是介于1和100之间的随机数,不包括介于15和25之间以及介于45和55之间的所有数字

我想不出一个函数来实现它。理想情况下,我想调用这样的东西:

getRandomNumbers($min,$max,$previor,$range)

其中$previor是生成下一个元素时要考虑的前一个元素的数量,$范围表示与我不希望下一个数字出现的数字的"接近度"。

我希望我能体面地解释我的请求如果您对此有任何疑问,请添加评论。

我刚刚想到了这个:

function getRandomNumbers($min, $max, $previous, $range) {
    static $generated = array();
    $chunk = array_slice($generated, -$previous);
    // Added this infinite loop check to save you some headache.
    if (((($max - $min + 1) / (($range * 2) + 1)) + 1) <= $previous) {
        die("Values set have the potential of running into an infinite loop. Min: $min, Max: $max, Previous: $previous, Range: $range");
    }
    while(true) {
        $number = rand($min, $max);
        $found = true;
        foreach ($chunk as $value) {
            if (in_array($number, range($value-$range, $value+$range))) {
                $found = false;
            }
        }
        if ($found) {
            $generated[] = $number;
            return $number;
        }
    }
}

使用以下方法进行测试:

for ($i = 1; $i < 25; $i++) {
    echo getRandomNumbers(1, 100, 5, 5) . "<br />";
}

PHP隐藏链接:http://phpfiddle.org/main/code/51ke-4qzs

编辑:添加了一个检查,以防止可能的无限循环。例如:如果您设置以下值:

$min = 1;
$max = 100;
$previous = 5;
$range = 12;
echo getRandomNumbers($min, $max, $previous, $range);

比方说,在一个非常不幸的情况下,它会产生13、38、63和88。因此,第五个数字不能是介于1和25、26和50、51和75、76和100之间的任何数字。因此,它将导致一个无限循环。我也更新了PHPFiddle链接。

getRandomNumbers( $previous, $range ) {
  //I'm assuming that previous will be an array of your previous X that you don't want to be close to
  $num = getRandomNumber() //However you are doing this now
  foreach( $previous as $key => $value ) {
    if ( ( $value - $range ) > $num && ( $value + $range ) < $num ) {
      return getRandomNumbers($previous, $range);
    }
  }
  //You need to also replace a value in previous
  return num;
}