Создание UNIQUE случайных чисел в пределах диапазона - PHP

Мне нужно генерировать случайные УНИКАЛЬНЫЕ числа в пределах диапазона? как это сделать?

i может генерировать число randoms на

generator:
$arr=array();
$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;

Я знаю, что этот код плохой, поэтому мне нужен лучший оптимизированный код моей версии! помощь!

Пример: если мне нужно сгенерировать 3 числа в пределах от 1 до 15, они должны быть похожими на 5, 9, 1, но не 3,1,2 [с в 1 - 3 (числа, которые я хочу создать)]

40
задан 10 апр. '11 в 18:10
источник поделиться
13 ответов

Массив с диапазоном чисел в случайном порядке:

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

Обернутая функция:

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

Пример:

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

Результат:

 Array
(
    [0] => 14
    [1] => 16
    [2] => 17
    [3] => 20
    [4] => 1
)
104
ответ дан 10 апр. '11 в 18:19
источник
$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);

Мне было интересно увидеть, как принятый ответ складывается против моего. Полезно отметить, что гибрид обоих может быть выгодным; на самом деле функция, которая условно использует тот или иной в зависимости от определенных значений:

# 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)
{
    $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;

Результаты:

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

Если вы используете меньший диапазон и более высокий счет возвращаемых значений, принятый ответ, безусловно, оптимален; однако, как я и ожидал, большие диапазоны и меньшие подсчеты займет много времени с принятым ответом, так как он должен хранить все возможные значения в диапазоне. Вы даже рискуете выбросить крышку памяти PHP. Гибрид, который оценивает соотношение между диапазоном и количеством и условно выбирает генератор, был бы лучшим из обоих миров.

11
ответ дан 10 апр. '11 в 18:22
источник

Идея состоит в том, чтобы использовать ключи, когда значение уже присутствует в ключах массива, размер массива остается прежним:

function getDistinctRandomNumbers ($nb, $min, $max) {
    if ($max - $min + 1 < $nb)
        return false; // or throw an exception

    $res = array();
    do {
        $res[mt_rand($min, $max)] = 1;
    } while (count($res) !== $nb);
    return array_keys($res); 
}

Pro: Этот способ позволяет избежать использования in_array и не генерирует огромный массив. Таким образом, он быстро и сохраняет много памяти.

Минусы: когда скорость (диапазон/количество) уменьшается, скорость также уменьшается (но остается верной). При такой же скорости относительная скорость увеличивается с размером диапазона. (*)

(*) Я понимаю этот факт, так как для выбора (в частности, для первых шагов) больше свободных целых чисел, но если у кого-то есть математическая формула, описывающая это поведение, меня интересует, не стесняйтесь.

Заключение: лучшая "общая" функция, по-видимому, представляет собой комбинацию между этой функцией и функцией @Anne, которая более эффективна с небольшой скоростью. Эта функция должна переключаться между двумя способами, когда требуется определенное количество, и достигается скорость (диапазон/количество). Поэтому сложность/время теста, чтобы знать это, должны приниматься во внимание.

5
ответ дан 26 янв. '15 в 19:31
источник

Если вам нужны 5 случайных чисел от 1 до 15, вы должны сделать:

var_dump(getRandomNumbers(1, 15, 5));

function getRandomNumbers($min, $max, $count)
{
    if ($count > (($max - $min)+1))
    {
        return false;
    }
    $values = range($min, $max);
    shuffle($values);
    return array_slice($values,0, $count);
}

Он вернет false, если вы укажете значение счета больше, чем возможный диапазон чисел.

3
ответ дан 10 апр. '11 в 18:17
источник

Вы можете попробовать следующий код:

function unique_randoms($min, $max, $count) {

 $arr = array();
 while(count($arr) < $count){
      $tmp =mt_rand($min,$max);
      if(!in_array($tmp, $arr)){
         $arr[] = $tmp;
      }
 }
return $arr;
}
3
ответ дан 30 июня '14 в 18:26
источник

Если вы хотите генерировать 100 чисел, которые являются случайными, но каждое число появляется только один раз, хорошим способом было бы сгенерировать массив с порядковыми номерами, а затем перетасовать его.

Что-то вроде этого:

$arr = array();

for ($i=1;$i<=101;$i++) {
    $arr[] = $i;
}

shuffle($arr);

print_r($arr);

Результат будет выглядеть примерно так:

Array
(
    [0] => 16
    [1] => 93
    [2] => 46
    [3] => 55
    [4] => 18
    [5] => 63
    [6] => 19
    [7] => 91
    [8] => 99
    [9] => 14
    [10] => 45
    [11] => 68
    [12] => 61
    [13] => 86
    [14] => 64
    [15] => 17
    [16] => 27
    [17] => 35
    [18] => 87
    [19] => 10
    [20] => 95
    [21] => 43
    [22] => 51
    [23] => 92
    [24] => 22
    [25] => 58
    [26] => 71
    [27] => 13
    [28] => 66
    [29] => 53
    [30] => 49
    [31] => 78
    [32] => 69
    [33] => 1
    [34] => 42
    [35] => 47
    [36] => 26
    [37] => 76
    [38] => 70
    [39] => 100
    [40] => 57
    [41] => 2
    [42] => 23
    [43] => 15
    [44] => 96
    [45] => 48
    [46] => 29
    [47] => 81
    [48] => 4
    [49] => 33
    [50] => 79
    [51] => 84
    [52] => 80
    [53] => 101
    [54] => 88
    [55] => 90
    [56] => 56
    [57] => 62
    [58] => 65
    [59] => 38
    [60] => 67
    [61] => 74
    [62] => 37
    [63] => 60
    [64] => 21
    [65] => 89
    [66] => 3
    [67] => 32
    [68] => 25
    [69] => 52
    [70] => 50
    [71] => 20
    [72] => 12
    [73] => 7
    [74] => 54
    [75] => 36
    [76] => 28
    [77] => 97
    [78] => 94
    [79] => 41
    [80] => 72
    [81] => 40
    [82] => 83
    [83] => 30
    [84] => 34
    [85] => 39
    [86] => 6
    [87] => 98
    [88] => 8
    [89] => 24
    [90] => 5
    [91] => 11
    [92] => 73
    [93] => 44
    [94] => 85
    [95] => 82
    [96] => 75
    [97] => 31
    [98] => 77
    [99] => 9
    [100] => 59
)
3
ответ дан 10 апр. '11 в 18:18
источник

Получить случайное число. Он уже хранится в массиве? Если нет, сохраните его. Если да, тогда перейдите к другому случайному числу и повторите.

2
ответ дан 10 апр. '11 в 18:18
источник

Я думаю, что это, вероятно, не проблема для большинства, но я пытался ее решить. Я думаю, что у меня довольно приличное решение. В случае, если кто-то еще наткнется на эту проблему.

function randomNums($gen, $trim, $low, $high)
{
    $results_to_gen = $gen;
    $low_range      = $low;
    $high_range     = $high;
    $trim_results_to= $trim;

    $items = array();
    $results = range( 1, $results_to_gen);
    $i = 1;

    foreach($results as $result)
    {
        $result = mt_rand( $low_range, $high_range);
        $items[] = $result;

    }


    $unique = array_unique( $items, SORT_NUMERIC);
    $countem = count( $unique);
    $unique_counted = $countem -$trim_results_to;

    $sum = array_slice($unique, $unique_counted);


    foreach ($sum as $key)
    {
        $output = $i++.' : '.$key.'<br>';
        echo $output;
    }

}

randomNums (1100, 1000, 890000, 899999);

1
ответ дан 08 мая '14 в 11:26
источник

Метод "тасования" имеет ОСНОВНОЕ ПОЛНОЕ. Когда цифры будут большими, перетасовать 3 миллиарда индексов немедленно вызовет ошибку CAUSE 500. Это лучшее решение для действительно больших чисел.

function getRandomNumbers($min, $max, $total) {
    $temp_arr = array();
    while(sizeof($temp_arr) < $total) $temp_arr[rand($min, $max)] = true;
    return $temp_arr;
}

Скажем, я хочу получить 10 уникальных случайных чисел от 1 миллиарда до 4 миллиардов.

$random_numbers = getRandomNumbers(1000000000,4000000000,10);

PS: Время выполнения: 0,027 микросекунды

0
ответ дан 05 янв. '16 в 13:04
источник

Просто используйте эту функцию и передайте счетчик числа, которое вы хотите сгенерировать

Код:

function randomFix($length)
{
    $random= "";

srand((double)microtime()*1000000);

$data = "AbcDE123IJKLMN67QRSTUVWXYZ";
$data .= "aBCdefghijklmn123opq45rs67tuv89wxyz";
$data .= "0FGH45OP89";

for($i = 0; $i < $length; $i++)
{
    $random .= substr($data, (rand()%(strlen($data))), 1);
}
return $random;}
0
ответ дан 22 июля '16 в 8:56
источник

Вероятно, это решит вашу проблему:

<?php print_r(array_rand(range(1,50), 5)); ?>
0
ответ дан 09 апр. '13 в 23:30
источник

Вот как я это сделаю.

$randnum1 = mt_rand(1,20);

$nomatch = 0;

while($nomatch == 0){

$randnum2 = mt_rand(1,20);

if($randnum2 != $randnum1){

$nomatch = 1;

}

}

$nomatch = 0;

while($nomatch == 0){

$randnum3 = mt_rand(1,20);

if(($randnum3 != $randnum1)and($randnum3 != $randnum2)){

$nomatch = 1;

}

}

Затем вы можете повторить результаты, чтобы проверить

echo "Random numbers are " . $randnum1 . "," . $randnum2 . ", and " . $randnum3 . "\n";
0
ответ дан 27 июля '15 в 0:33
источник

Лучший способ генерации уникального случайного числа -

<?php
     echo md5(uniqid(mt_rand(), true).microtime(true));
?>
-1
ответ дан 15 июня '17 в 8:17
источник

Другие вопросы по метке или Задайте вопрос