weighted random function [for the lack of better name]

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

Post Reply
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

weighted random function [for the lack of better name]

Post by Weirdan »

Code: Select all

/** Function returns weighted random result
 * @param $arr array array of the results with their weights:
 *               array("something"=>$something_weight,
 *                     "something_else"=>something_else_weight
 *               );
 * @return mixed something that was the key in the $arr
 */

/* Legals:
 * copyleft by Weirdan.
 *  You are granted the rights to use this function in any way. 
 *  NO WARRANTIES.
 */

/*  use this function as follows:
 *  $res=weighted_random(array("something"=>10,"something_else"=>40);
 * to get "something" in the 20% percents of calls and "something_else" - in the 80%.
 */

function weighted_random($arr){ 
  $weights=array(); 
  $total=0; 
  foreach($arr as $val=>$weight){ 
    $total+=$weight;
    if(!isset($weights[0])) {
       $weights[0]=array(
          "val"=>$val,
          "start"=>0.0,
          "end"=>$weight
       );
       continue;
     }
     $cur=current($weights);
     $weights[]=array(
        "val"=>$val, 
        "start"=>($cur["end"]+0.01),
        "end"=>($cur["end"]+$weight)
     );
  }
  //adjust the weight to be 1.00 in sum
  $scale=1.00/$total;
  foreach($weights as $id=>$weight)
    $weights[$id]=array(
       "val"=>$weight["val"],
       "start"=>$weight["start"]*$scale,
       "end"=>$weight["end"]*$scale
    );
  $seed=mt_rand(0,100)/100;
  foreach($weights as $weight)
     if($seed<=$weight["end"]&&$seed>=$weight["start"]) return($weight["val"]);
  return false; //in the strange case we haven't found the val
}
tylerdurden
Forum Commoner
Posts: 66
Joined: Mon Jul 28, 2003 11:52 am
Location: Austria

Post by tylerdurden »

sweet. Don't know yet where to use it, but I'll think of something ;-) Thanks.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

I found better variant at PHPClasses: http://www.phpclasses.org/browse/package/1940.html
Post Reply