Last active
July 20, 2016 04:40
-
-
Save sokil/ed38ca9ce072e716a0ba to your computer and use it in GitHub Desktop.
Get random key from array due to weight in value.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function array_rand_weight(array $array) | |
{ | |
reset($array); | |
$pointer = mt_rand(0, array_sum($array)); | |
if(!$pointer) { | |
return key($array); | |
} | |
$accumulator = 0; | |
while($accumulator < $pointer) { | |
$key = key($array); | |
$weight = current($array); | |
$accumulator += $weight; | |
next($array); | |
} | |
return $key; | |
} | |
/** | |
* Test | |
*/ | |
$array = array( | |
'apple' => 40, | |
'orange' => 30, | |
'lemon' => 20, | |
'tomato' => 7, | |
'potato' => 3, | |
); | |
$stat = array(); | |
for($i = 0; $i < 10000; $i++) { | |
$key = array_rand_weight($array); | |
if(!isset($stat[$key])) { | |
$stat[$key] = 0; | |
} | |
$stat[$key]++; | |
} | |
arsort($stat); | |
$weightSum = array_sum($stat); | |
foreach($stat as $key => $weight) { | |
echo $key . ' => ' . $weight . ' (' . floor($weight / $weightSum * 100) . '%)' . PHP_EOL; | |
} | |
/** | |
* Results: | |
* | |
* apple => 4107 (41%) | |
* orange => 2920 (29%) | |
* lemon => 1991 (19%) | |
* tomato => 693 (6%) | |
* potato => 289 (2%) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Currently implemented in https://github.com/sokil/php-structure/blob/master/src/WeightList.php