2013-07-25 5 views
1

재설정 할 때까지 범위에서 호출 할 때마다 임의의 고유 한 쌍 번호를 반환하는 함수를 작성하고 싶습니다. ,배열의 고유 한 조합

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 

나는 두 가지 방법을 시도 그것은 많은 메모리를 소비합니다. 코드 :

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()를 35 행의 test.php에서 호출합니다. b (배열 ... 무엇을합니까? – 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"; 
} 

?>