За последние 24 часа нас посетили 17844 программиста и 1613 роботов. Сейчас ищут 1470 программистов ...

Генерация случайной последовательности чисел

Тема в разделе "Решения, алгоритмы", создана пользователем Dagdamor, 20 ноя 2007.

  1. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    В качестве приложения к теме http://php.ru/forum/viewtopic.php?p=71709#71709

    Функция, генерирующая равномерно распределенный случайный набор чисел без повторов из заданного диапазона.

    $min, $max - границы диапазона, $count - количество генерируемых значений.
    Диапазон может быть любым, скорость алгоритма от него не зависит.
    Если диапазона недостаточно для генерации $count различных значений, возвращается столько значений, сколько их оказалось в диапазоне.

    PHP:
    1. <?php
    2.  
    3. // by Dagdamor
    4. function generateRandomSelection($min, $max, $count)
    5. {
    6.   $result=array();
    7.   if($min>$max) return $result;
    8.   $count=min(max($count,0),$max-$min+1);
    9.   while(count($result)<$count) {
    10.     $value=rand($min,$max-count($result));
    11.     foreach($result as $used) if($used<=$value) $value++; else break;
    12.     $result[]=$value;
    13.     sort($result);
    14.   }
    15.   shuffle($result);
    16.   return $result;
    17. }
    Примеры использования:

    PHP:
    1. <?php
    2.  
    3. // Выбрать 5 различных случайных значений из диапазона [1-1000]
    4. $selection=generateRandomSelection(1,1000,5);
    5. echo implode(", ",$selection)."<br>"; // 824, 704, 21, 370, 385
    6.  
    7. // Выбрать 10 различных случайных значений из диапазона [1-10]
    8. $selection=generateRandomSelection(1,10,10);
    9. echo implode(", ",$selection)."<br>"; // 3, 1, 4, 10, 7, 9, 5, 6, 2, 8
    10.  
    11. // Выбрать 3 различных случайных значения из диапазона [1-10]
    12. $selection=generateRandomSelection(1,10,3);
    13. echo implode(", ",$selection)."<br>"; // 6, 4, 9
    14.  
    15. // Выбрать 10 различных случайных значений из диапазона [1-3]
    16. $selection=generateRandomSelection(1,3,10);
    17. echo implode(", ",$selection)."<br>"; // 1, 3, 2
     
  2. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Вот ещё решение http://ru2.php.net/manual/ru/function.rand.php#77065
    PHP:
    1. <?php
    2. function randiff($min, $max, $num) {
    3.     if ($min<$max && $max-$min+1 >= $num && $num>0) {
    4.         $random_nums = array();
    5.         $i=0;
    6.         while($i<$num) {
    7.             $rand_num = rand($min, $max);
    8.             if (!in_array($rand_num, $random_nums)) {
    9.                 $random_nums[] = $rand_num;
    10.                 $i++;
    11.             }
    12.         }
    13.         return $random_nums;
    14.     } else {
    15.         return false;
    16.     }
    17. }
    18. ?>
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    shuffle($result); - это чит =)
     
  4. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    если уж читерить, так по полной :)
    PHP:
    1. <?php
    2. function randiff( $min, $max, $num ){
    3.     return array_slice( shuffle( range( $min, $max ) ), 0, $num );
    4. }
    5. ?>
     
  5. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Sergey89
    Это нелинейный алгоритм, в случае, когда мы выбираем 100 чисел из 100 и уже набрали 99, функция будет долбиться по интервалу снова и снова, пока случайно не попадет в свободное значение. Я специально стремился этого избежать в своем варианте :)

    dark-demon
    Твой вариант будет тормозить (либо не пройдет по памяти), если $max-$min - достаточно большое число.
     
  6. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    твой вариант тоже будет тормозить, если $count сравнима с $max-$min :)
     
  7. Dimko

    Dimko Активный пользователь

    С нами с:
    28 ноя 2007
    Сообщения:
    3
    Симпатии:
    0
    я у тебя ничего не понимаю...раскомментировал бы хоть чтоли(((((
     
  8. stas_t

    stas_t Активный пользователь

    С нами с:
    24 апр 2007
    Сообщения:
    500
    Симпатии:
    0
    Адрес:
    Courbevoie, France
    "угадай источник". том 2, глава 3 - случайные числа, пункт 3.4.2 - случайные выборки и перемешивания, алгоритм s:
    PHP:
    1. <?php
    2. /**
    3. 0 < n <= N
    4. выбор n случайных чисел из диапазона 1..N
    5. t - текущее число
    6. m - количество выбранных чисел
    7. */
    8. function rand_selection ($n, $N)
    9. {
    10.     $res = array ();
    11.    
    12.     for ($t = 1, $m = 0; $m < $n; $t++)
    13.     {
    14.         if (rand (0, $N - $t) < $n - $m)
    15.         {
    16.             $res[] = $t;
    17.             $m++;
    18.         }
    19.     }
    20.  
    21.     return $res;
    22. }
    23. ?>