복붙노트

범위 내에서 고유 한 난수 생성 - PHP

PHP

범위 내에서 고유 한 난수 생성 - PHP

한 범위 내에서 임의의 UNIQUE 숫자를 생성해야합니까? 수행하는 방법 ?

나는 난수를 다음과 같이 생성 할 수있다.

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;

나는이 코드가 나쁘다는 것을 알고있다. 그래서 나는 나의 버전의보다 최적화 된 코드가 필요하다! 도와주세요!

예: 내가 1에서 15 사이에서 3 개의 숫자를 생성해야한다면 5, 9, 1과 같아야하지만 3,1,2가 아니라 [1에서 3으로 (생성하고자하는 숫자)]

해결법

  1. ==============================

    1.무작위 순서로 숫자 범위의 배열 :

    무작위 순서로 숫자 범위의 배열 :

    $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
    )
    
  2. ==============================

    2.

    $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의 메모리 캡을 불어 넣을 위험이 있습니다. 범위와 개수 사이의 비율을 평가하고 조건에 따라 발전기를 선택하는 하이브리드는 두 가지 모두에서 가장 좋습니다.

  3. ==============================

    3.아이디어는 배열 키에 값이 이미있을 때 키를 사용하도록 구성되어 있습니다. 배열 크기는 동일하게 유지됩니다.

    아이디어는 배열 키에 값이 이미있을 때 키를 사용하도록 구성되어 있습니다. 배열 크기는 동일하게 유지됩니다.

    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); 
    }
    

    프로 :이 방법은 in_array의 사용을 피하고 거대한 배열을 생성하지 않습니다. 그래서, 그것은 빠르고 많은 메모리를 보존합니다.

    단점 : 속도 (범위 / 수량)가 감소하면 속도도 감소합니다 (그러나 올바른 상태로 유지됨). 동일한 속도의 경우 상대 속도는 범위 크기와 함께 증가합니다. (*)

    (*) 나는 (특히 첫 번째 단계에서) 선택할 수있는 더 많은 정수가 있기 때문에 사실을 이해하고 있지만, 누군가이 행동을 설명하는 수학 공식을 가지고 있다면, 나는 주저하지 않고 흥미를 느낀다.

    결론 : 가장 좋은 "일반"함수는이 함수와 약간의 속도로 더 효율적인 @Anne 함수를 혼합 한 것 같습니다. 이 기능은 특정 양이 필요하고 비율 (범위 / 양)에 도달 할 때 두 가지 방법을 전환해야합니다. 따라서 테스트의 복잡성 / 시간을 알아야하며이를 고려해야합니다.

  4. ==============================

    4.무작위 인 100 개의 숫자를 생성하고 싶지만 각 숫자가 한 번만 나타나는 경우 좋은 순서는 순서대로 숫자가있는 배열을 생성 한 다음 다시 섞는 것입니다.

    무작위 인 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
    )
    
  5. ==============================

    5.1에서 15 사이의 5 개의 임의 숫자가 필요한 경우 다음을 수행해야합니다.

    1에서 15 사이의 5 개의 임의 숫자가 필요한 경우 다음을 수행해야합니다.

    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를 반환합니다.

  6. ==============================

    6.다음 코드를 시도해보십시오.

    다음 코드를 시도해보십시오.

    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;
    }
    
  7. ==============================

    7.임의의 숫자를 가져옵니다. 이미 배열에 저장되어 있습니까? 그렇지 않다면 저장하십시오. 그렇다면 다른 난수를 가져 와서 반복하십시오.

    임의의 숫자를 가져옵니다. 이미 배열에 저장되어 있습니까? 그렇지 않다면 저장하십시오. 그렇다면 다른 난수를 가져 와서 반복하십시오.

  8. ==============================

    8.나는 이것이 아마도 대부분의 문제가 아닌 것 같지만 해결하려고 노력했다. 나는 꽤 괜찮은 해결책이 있다고 생각한다. 다른 누구도이 문제에 걸림돌이되는 경우.

    나는 이것이 아마도 대부분의 문제가 아닌 것 같지만 해결하려고 노력했다. 나는 꽤 괜찮은 해결책이 있다고 생각한다. 다른 누구도이 문제에 걸림돌이되는 경우.

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

  9. ==============================

    9.이것은 아마 당신의 문제를 해결할 것입니다 :

    이것은 아마 당신의 문제를 해결할 것입니다 :

    <?php print_r(array_rand(range(1,50), 5)); ?>
    
  10. ==============================

    10.이것이 내가하는 방법이다.

    이것이 내가하는 방법이다.

    $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";
    
  11. ==============================

    11."셔플"방법은 전제가 있습니다. 숫자가 크면 30 억 개의 인덱스가 즉시 500 개의 오류를 일으킬 것입니다. 정말 큰 숫자를위한 최상의 솔루션이 여기에 있습니다.

    "셔플"방법은 전제가 있습니다. 숫자가 크면 30 억 개의 인덱스가 즉시 500 개의 오류를 일으킬 것입니다. 정말 큰 숫자를위한 최상의 솔루션이 여기에 있습니다.

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

    10 억에서 40 억으로 10 개의 고유 한 난수를 얻고 싶습니다.

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

    추신 : 실행 시간 : 0.027 마이크로 초

  12. ==============================

    12.이 함수를 사용하고 생성하려는 숫자의 수를 전달하기 만하면됩니다.

    이 함수를 사용하고 생성하려는 숫자의 수를 전달하기 만하면됩니다.

    암호:

    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;}
    
  13. ==============================

    13.고유 한 난수를 생성하는 가장 좋은 방법은 다음과 같습니다.

    고유 한 난수를 생성하는 가장 좋은 방법은 다음과 같습니다.

    <?php
         echo md5(uniqid(mt_rand(), true).microtime(true));
    ?>
    
  14. from https://stackoverflow.com/questions/5612656/generating-unique-random-numbers-within-a-range-php by cc-by-sa and MIT license