Home  >  Q&A  >  body text

Generate unique random numbers within a certain range

I need to generate random unique numbers within a certain range, how should I do it? I can generate random numbers by

generator:
$arr = [];
$x = rand($min, $max);
$len = count($arr);
$flag = 0;
for($i = 0; $i < $len; $i++)
{
 if ($flag === 1)
   goto generator;
 if ($x === $arr[$i])
   $flag = 1;
}
$arr[$index] = $x;
$index++; 
goto generator;

I know this code is bad, so I need to make my version better optimized code! help!

Example: If I need to generate 3 numbers between 1 and 15, they should be like 5, 9, 1, but not 3, 1, 2 [in 1 - 3 (the numbers I want to generate)]

P粉087951442P粉087951442393 days ago510

reply all(2)I'll reply

  • P粉668146636

    P粉6681466362023-10-16 18:17:22

    $len = 10;   // total number of numbers
    $min = 100;  // minimum
    $max = 999;  // maximum
    $range = []; // initialize array
    foreach (range(0, $len - 1) as $i) {
        while(in_array($num = mt_rand($min, $max), $range));
        $range[] = $num;
    }
    print_r($range);

    I'd be interested to know how the accepted answer differs from my answer. It's worth noting that a mix of the two can be advantageous; in fact, here's a function that conditionally uses one or the other based on some value:

    # The accepted answer
    function randRange1($min, $max, $count)
    {
        $numbers = range($min, $max);
        shuffle($numbers);
        return array_slice($numbers, 0, $count);
    }
    
    # My answer
    function randRange2($min, $max, $count)
    {
        $i = 0;
        $range = array();
        while ($i++ < $count) {
            while(in_array($num = mt_rand($min, $max), $range));
            $range[] = $num;
        }
        return $range;
    }
    
    echo 'randRange1: small range, high count' . PHP_EOL;
    $time = microtime(true);
    randRange1(0, 9999, 5000);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange2: small range, high count' . PHP_EOL;
    $time = microtime(true);
    randRange2(0, 9999, 5000);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange1: high range, small count' . PHP_EOL;
    $time = microtime(true);
    randRange1(0, 999999, 6);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;
    
    echo 'randRange2: high range, small count' . PHP_EOL;
    $time = microtime(true);
    randRange2(0, 999999, 6);
    echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

    result:

    randRange1: small range, high count
    0.019910097122192
    
    randRange2: small range, high count
    1.5043621063232
    
    randRange1: high range, small count
    2.4722430706024
    
    randRange2: high range, small count
    0.0001051425933837

    The accepted answer is definitely optimal if you use a smaller range and a higher number of return values; however, as I expected, a larger range and smaller count will take longer Time to accept the answer since it has to store every possible value in the range. You even run the risk of exceeding PHP's memory limit. Evaluating the ratio between range and count and conditionally choosing a hybrid of generators would be the best of both worlds.

    reply
    0
  • P粉180844619

    P粉1808446192023-10-16 11:11:30

    Array with ranges of numbers in random order:

    $numbers = range(1, 20);
    shuffle($numbers);

    Packaging function:

    function UniqueRandomNumbersWithinRange($min, $max, $quantity) {
        $numbers = range($min, $max);
        shuffle($numbers);
        return array_slice($numbers, 0, $quantity);
    }

    Example:

    <?php
    print_r( UniqueRandomNumbersWithinRange(0,25,5) );
    ?>

    result:

    Array
    (
        [0] => 14
        [1] => 16
        [2] => 17
        [3] => 20
        [4] => 1
    )

    reply
    0
  • Cancelreply