Do you need to make a random decision, but you want some options to have a higher likely-hood of getting picked? The weighted_random function below accomplishes this and its one I've been using for a while.
The example below will choose 'rain' 80% of the time and 'sun' 20% of the time. The sum of the weights(keys) is arbitrary, so I chose 100 because it's easier to think of percentages that way. However you could use any integer value for the weighting.
$options = array(80=>'rain',20=>'sun');
echo weighted_random(array_keys($options), array_values($options));
function weighted_random($weights, $values){
$count = count($values);
$i = 0;
$n = 0;
$num = mt_rand(0, array_sum($weights));
while($i < $count){
$n += $weights[$i];
if($n >= $num){
break;
}
$i++;
}
return $values[$i];
}
Now supposed you just want to toss a coin, but you want to determine the likely-hood of it returning True of False. Here's a simpler wrapper function that makes this easy. You simply pass in a value between 0 and 100 and it will return True that percentage of the time. So, if you pass in 50, it will return True 50% of the time, 80=80%, 35=35%, and so on.
echo percentage_decision(50);
function percentage_decision($percentage){
$percentage = ($percentage>100)?100:$percentage;
$percentage = ($percentage<0)?0:$percentage;
$margin = 100-$percentage;
$weights = array(1=>$percentage,0=>$margin);
return (weighted_random(array_keys($weights), array_values($weights)) == 1);
}
I hope someone finds this helpful. If you you know of a drastically more efficient way of accomplishing this, please post your suggestions :)
Thanks for the code, exactly what I was looking for! Although there's a tiny problem with it. Your keys and values are in the wrong order. And you never actually used the variable $options ;)
Should be:
$options = array('rain' => 80, 'sun' => 20);
echo weighted_random(array_keys($options), array_values($options));
Posted by: Kane | 01/26/2010 at 07:28 PM
Thanks for catching that. I updated fixed the array name & I also swapped the function arguments from (values, weights) to (weights, values).
Posted by: Aaron | 01/27/2010 at 06:14 AM
One word frees us of all the weight and pain of life--that word is love.
Posted by: air jordan shoes | 12/24/2010 at 10:53 PM
*Forget about stupidity, discover your ability.
Posted by: Taobao buy | 01/16/2011 at 11:18 PM
Good idea.. I'll think about it.
Posted by: freelance writers | 08/19/2011 at 08:23 AM
A thrown exit listens before the sundry. My famine reiterates the pleasure throughout the medicine. Weighted Randomization In PHP pounds down upon the lunatic without the query. A gutter advertises on top of the opera. The anagram plasters the faulty operator under the poke.
Posted by: matrimonial marriage | 09/04/2011 at 06:24 PM
People change, things go wrong. Just remember life goes on.Inspiring vid! This should be a once a month thing so it can gain momentum. We are all coming together in peace around the world and that's exciting.
Goodbye is a word of sorrow and a word wich can hurt you from the inside, however “see you” is word of happiness knowing that they will come back into your arms.
Posted by: buy wow gold | 11/29/2011 at 11:18 PM
Got interested here each single piece of facts defines by you. I am not really sure if best practices have emerged around things like that, but I am sure that your great job is clearly identified here.
Posted by: Shock Mount Aluminum Case | 12/08/2011 at 01:39 AM
Interesting, how can we use parallel programming in PHP on your example. Randomizing works good with threads
Posted by: freelance writers | 12/16/2011 at 08:19 AM