2013-07-25 2 views
1

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

function randomUniquePairs($ranges, $reset = false){ 
    if ($reset === false){ 
     // some code for reseting 
    } 
    /* 
    some code for creating random unique pair numbers 
    */ 
    return $result; 
} 

randomUniquePairs(range(1,10), range(1,20)); 
/* 
    this function returns for example: 
    array(2,9) 
*/ 
randomUniquePairs(range(1,10), range(1,20)); 
/* 
    this function returns for example: 
    array(5,19) 
*/ 

randomUniquePairs(range(1,10), range(1,20)); 
/* 
    this function returns for example: 
    array(5,19) 
*/ 
//this function returns random unique pairs until we pass reset paramer true 

Стараюсь два подхода:

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

class a { 
    private $asqar; 

    function __construct() ($range) { 

     // cycle for ranges 
     foreach ($range[0] as $v1) { 
      foreach ($range[1] as $v2) { 
       $asqar[] = array(
        $v1, 
        $v2, 
       ); 
      } 
     } 
    } 

    function randomUniquePairs($reset = false){ 

     if ($reset === true){ 
      $this->asgar = array(); 
     } 

     $rndKey = array_rand($this->asgar); 
     $result = $this->asqar[$rndkey]; 
     unset($this->asqar[$rndkey]); 
     return $result; 
    } 
} 

$c = new a(range(1,10), range(1,20)); 
$c->randomUniquePairs(); 

2) второе написать функцию, которая производить пару из этих диапазонов, а затем сохранить его в переменной, каждый раз, когда функция вызывает после получения пары, он проверяет, является ли эта пара, произведенных до вызывать функцию рекурсивно, она продолжается до тех пор, пока не создаст уникальную пару. этот код:

class a{ 

    private $__uniqueVariables = array(); 

    public function randomUniquePairs($range, $reset = false) { 

     if ($reset === true){ 
     $this->__uniqueVariables = array(); 
    } 

    // cycle for each value 
    foreach ($range as $value) { 

     // shuffle 
     shuffle($value); 

     // selected id 
     $selectedId[] = $value[0]; 
    } 

    // check for selected variable 
    if (in_array($rndUnqNum, $this->__uniqueVariables)) { 

     // return for try again 
     return $this->uniqueVariable($range); 
    } 

    // added to current unique variables 
    $this->__uniqueVariables[] = $rndUnqNum; 

    // return 
    return $rndUnqNum; 
} 

} 

но это вопрос, который иногда бросить Fatal error: Maximum function nesting level of '100' reached.

Мне нужен лучший алгоритм.

+0

когда я пытаюсь этот код, я получаю эту ошибку: Фатальная ошибка: Вызов неопределенной методы A :: B() в test.php на линии 35. Что б (массив ... делать? – Maximus2012

ответ

1

Это, кажется, хорошо даже при больших диапазонах:

rand() function это отличный способ, чтобы получить случайное число в заданном диапазоне без необходимости строить или манипулировать массив значений, как в ваших примерах выше.

Обновление Я добавил случай остановки (когда история равна или больше максимально возможных уникальных пар, она возвращает пустой массив). Не стесняйтесь изменять этот код для автоматического сброса диапазона.

<?php 
class c { 

    function c($min_X,$max_X,$min_Y,$max_Y) { 
     $this->setRange($min_X,$max_X,$min_Y,$max_Y); 
    } 

    function getRandUniquePair($reset = false) { 
     if ($reset) { 
      $this->__history = array(); 
     } 

     if (count($this->__history) >= $this->__max_pairs) { 
      return array(); 
     } 

     $candidate = array(rand($this->__range[0],$this->__range[1]),rand($this->__range[2],$this->__range[3])); 

     if (in_array($candidate,$this->__history)) { 
      return $this->getRandUniquePair(); 
     } 

     $this->__history[] = $candidate; 

     return $candidate; 
    } 

    function setRange($min_X,$max_X,$min_Y,$max_Y) { 
     $this->__range = array($min_X,$max_X,$min_Y,$max_Y); 
     $this->__max_pairs = ($max_X - $min_X) * ($max_Y - $min_Y); 
     $this->__history = array(); 
    } 
} 

// test 

$c = new c(0,10,0,20); 

$i = 0; 
$pairs = array(); 
while ($i < 100) { 
    $i++; 
    $pair = $c->getRandUniquePair(); 

    if (in_array($pair,$pairs)) { 
     die('Duplicate pairs!'); 
    } 

    echo $pair[0].', '.$pair[1]."\n"; 
    $pairs[] = $pair; 
} 

$c->setRange(0,100000000000,0,100000000000); 
echo "I perform well even at large ranges!\n"; 

$i = 0; 
while ($i < 1000) { 
    $i++; 
    $pair = $c->getRandUniquePair(); 

    echo $pair[0].', '.$pair[1]."\n"; 
} 

?> 
Смежные вопросы