2013-07-25 97 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

当我尝试此代码时,出现此错误:致命错误:在第35行的test.php中调用未定义的方法a :: b()。b(array ... do? – 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"; 
} 

?>