php - unique combination of arrays -
i want write function return random unique pair numbers every time call range until resetting it. this:
function randomuniquepairs($ranges, $reset = false){ if ($reset === false){ // code reseting } /* code creating random unique pair numbers */ return $result; } randomuniquepairs(range(1,10), range(1,20)); /* function returns example: array(2,9) */ randomuniquepairs(range(1,10), range(1,20)); /* function returns example: array(5,19) */ randomuniquepairs(range(1,10), range(1,20)); /* function returns example: array(5,19) */ //this function returns random unique pairs until pass reset paramer true
i try 2 approaches:
1)one them make of possible pairs select them randomly, inefficient, because if ranges wide, consumes lot of memory. code:
class { private $asqar; function __construct() ($range) { // cycle ranges foreach ($range[0] $v1) { foreach ($range[1] $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)second write function produce pair these ranges, store in variable, every time function calls after producing pair , checks if pair produced before call function recursively, continues until produce unique pair. code:
class a{ private $__uniquevariables = array(); public function randomuniquepairs($range, $reset = false) { if ($reset === true){ $this->__uniquevariables = array(); } // cycle each value foreach ($range $value) { // shuffle shuffle($value); // selected id $selectedid[] = $value[0]; } // check selected variable if (in_array($rndunqnum, $this->__uniquevariables)) { // return try again return $this->uniquevariable($range); } // added current unique variables $this->__uniquevariables[] = $rndunqnum; // return return $rndunqnum; } }
but has issue throw fatal error: maximum function nesting level of '100' reached
.
i want better algorithm.
this seems @ large ranges:
the rand() function great way random integer in specified range without having construct or manipulate array of values, in examples above.
update added stop case (when history equal or greater max possible unique pairs returns empty array). feel free change code automatically reset range.
<?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 @ large ranges!\n"; $i = 0; while ($i < 1000) { $i++; $pair = $c->getranduniquepair(); echo $pair[0].', '.$pair[1]."\n"; } ?>
Comments
Post a Comment