<?php
// Weighted random (can't think of proper name for this :P)
//   Written for Mgccl in FriHost forums. Original topic at http://www.frihost.com/forums/vt-59011.html

// Return a random weighted value.
// $values = The actual values
// $weights = The weights
function rand_weighted($values$weights) {
    
// Loop through all values passed. If a weight isn't set for a value, assume 1
    
foreach ($values as $key => $value)    if (!isset($weights[$key])) $weights[$key] = 1;
    
// Now, get the total of the weights
    
$total array_sum($weights);
    
// Stuff for percentiles
    
$percentiles = array();
    
$percentileTemp 0;
    
$percentileLast 0;
    
    
// Loop through each weight
    
foreach ($weights as $key => $weight) {
        
// Get the percentage chance for this
        
$percent = ($weight $total) * 100;
        
// Add this to the running total, for the percentile
        
$percentileTemp += $percent;
        
// The last percentile value used. Used to find the minimum
        
$percentileLast $percent;
        
        
// Now, set the percentile
        
$percentiles[$key]['min'] = $percentileTemp $percentileLast;
        
$percentiles[$key]['max'] = $percentileTemp;
    }
    
    
// Get a random value (0 to 100). Get 4 decimal places (not sure if there's a better way to do this)
    
$random mt_rand(01000000) / 10000;
    
    
//echo $random, '<br />';
    //echo '<pre>'; print_r($percentiles); echo '</pre>';
    
    // Loop through all percentile values
    
foreach ($percentiles as $key => $percentile) {
        
// If value falls in this percentile...
        
if ($percentile['min'] < $random && $random $percentile['max'])
            
// We've found it. Return this string
            
return $values[$key];
    }
    
}

// Function originally from comments on PHP.NET, I think (can't remember, really)
// It's been in my function library for a while
function microtime_diff($a$b) {
   list(
$a_dec$a_sec) = explode(" "$a);
   list(
$b_dec$b_sec) = explode(" "$b);
   return 
$b_sec $a_sec $b_dec $a_dec;
}

// Used in a lot of my PHP scripts, like DanPHPSupport
function getTime($startTime) {
    
$duration microtime_diff($startTimemicrotime());
    
$duration sprintf("%0.4f"$duration);
    return 
'Took ' $duration ' seconds';
}


$start_time_total microtime();

$start_time microtime();
// Daniel15's test!
$FriHost_users = array('Daniel15 (1206)''Mgccl (12721)''Bondings (3)''Generic AntiVirus Product (14289)');
$weights = array(12502502501);
echo 
rand_weighted($FriHost_users$weights), '<br />'getTime($start_time);

// ---------------------------

$start_time microtime();
// Test stuff
$array[] = 'test for speed of no weight arrays'
$array[] = 'how fast is this'
$array[] = 'the final result for this * 2';
// Empty weight array for this test
$weights = array();
echo 
'<br /><br />'rand_weighted($array$weights), '<br />'getTime($start_time);

// ---------------------------

$start_time microtime();
// Clear the arrays
$array = array();
$weight =  array();
// Test stuff
$array[] = 'test for weight'
$weight[] = 30000
$array[] = 'with HUGE numbers'
$weight[] = 2000
$array[] = 'final result for this * 5'
$weight[] = 50000;
echo 
'<br /><br />'rand_weighted($array$weight), '<br />'getTime($start_time);

// ---------------------------

$start_time microtime();
// Clear the arrays
$array = array();
$weight = array();
// Test stuff
$array[]= 'test for weight array only on some'
$weight[] = 20000
$array[]= 'final result for this * 3';
echo 
'<br /><br />'rand_weighted($array$weight), '<br />'getTime($start_time);


echo 
'<br /><br />Total time taken: 'getTime($start_time_total)
?>