OK. I have it. Try this:
Code: Select all
<?php
function remap($floatnumber,$skewfactor) {
// when $skewfactor is 1, we want the $exponent to be 1 (no skew)
// when $skewfactor is 250 (maximum), we want $skewfactor
// to be 0.1 (heavily skewed to larger numbers)
// create a linear function to determine $exponent
$exponent = (((0.1 - 1) / (250 - 1)) * $skewfactor) +
(1 + ((1 - 0.1) / (250 - 1))) ;
// the second argument to "pow" is the key: values greater
// than 1 remaps preferentially to smaller numbers, values
// between 0 and 1 remaps to larger numbers.
return pow($floatnumber,$exponent) ;
}
function get_random($var) {
// get a random number between 0 and 1
$randval = mt_rand() / mt_getrandmax() ;
// apply the remapping function
$skewrandval = remap($randval,$var) ;
// make the new number fit the original range
$skewrandval = $skewrandval * (100 - 1) + 1 ;
// you can make the result an integer now
$finalrandval = floor($skewrandval) ;
return $finalrandval ;
}
?>
My main problem before was I forgot to change the "pow" function - the second argument should have been "$exponent".
I tested this code by generating 1000 random numbers for each value of $var and averaged the results. It looks to be pretty smooth:
$var = 1, Average: 49.842
$var = 50, Average: 53.968
$var = 100, Average: 61.596
$var = 150, Average: 68.35
$var = 200, Average: 78.58
$var = 250, Average: 89.938
Based on the math, I would expect to not see any holes in the random numbers (that is, this does not just get a random number and add 20 to it so that you never get any numbers below 20), but I did not test to that degree.
Elmseeker,
I used the code you pointed out to make sure I never got an $exponent value greater than 1, since that would actually skew the results to smaller numbers. It was kludgy, though, so I've made the calculation of $exponent more precise in the above code.