Connecting Tech Pros Worldwide Forums | Help | Site Map

random numbers

Alexander Ross
Guest
 
Posts: n/a
#1: Jul 17 '05
is there any way to get a weighted random number other than something like
this:

array = (1,2,2,3,3,3,4,4,4,5,5,6)
and then get a random val from teh array?

Alex



warstar
Guest
 
Posts: n/a
#2: Jul 17 '05

re: random numbers


uhh sorry my english suxs but i dunno what u mean maybe reading this
will help:
http://nl.php.net/manual/nl/function.array-rand.php
with array_rand() u can get just random stuff out of a array and else
try reading this just the basic random stuff:
http://nl.php.net/manual/nl/function.rand.php

good luck

On Sat, 11 Oct 2003 23:04:33 GMT, "Alexander Ross"
<alexross@bleen.net> wrote:
[color=blue]
>is there any way to get a weighted random number other than something like
>this:
>
>array = (1,2,2,3,3,3,4,4,4,5,5,6)
>and then get a random val from teh array?
>
>Alex
>[/color]

Andy Hassall
Guest
 
Posts: n/a
#3: Jul 17 '05

re: random numbers


On Sat, 11 Oct 2003 23:04:33 GMT, "Alexander Ross" <alexross@bleen.net> wrote:
[color=blue]
>is there any way to get a weighted random number other than something like
>this:
>
>array = (1,2,2,3,3,3,4,4,4,5,5,6)
>and then get a random val from teh array?[/color]

Yes, but that's probably the simplest. You can produce that array from an
array of weights if you wanted.

<pre>
<?php
function weighted_rand($weights) {
foreach ($weights as $value => $weight)
for ($i=0; $i<$weight; $i++)
$values[] = $value;

return $values[mt_rand(0, count($values)-1)];
}

$num_runs = 40000;
$weights = array(1=>1, 2=>2, 3=>3);

for ($i=0; $i < $num_runs; $i++) {
$rand = weighted_rand($weights);

if (isset($results[$rand]))
$results[$rand]++;
else
$results[$rand] = 1;
}
ksort($results);

$total_weight = 0;
foreach ($weights as $weight)
$total_weight += $weight;

foreach ($results as $value => $freq) {
printf("%d : expected %8d (%3.2f%%), actual %8d (%3.2f%%)\n",
$value,
$num_runs * ($weights[$value] / $total_weight),
($weights[$value] / $total_weight) * 100.0,
$freq, $freq/$num_runs * 100.0);
}
?>
</pre>

Outputs:

1 : expected 6666 ( 16.67%), actual 6624 ( 16.56%)
2 : expected 13333 ( 33.33%), actual 13383 ( 33.46%)
3 : expected 20000 ( 50.00%), actual 19993 ( 49.98%)

Or you could skip creating the array with repeated values and work directly
off the weight array:

function weighted_rand($weights) {
$total_weight = 0;
foreach ($weights as $weight)
$total_weight += $weight;

$rand = mt_rand(1, $total_weight);

$total_weight = 0;
foreach ($weights as $value => $weight) {
$total_weight += $weight;
if ($rand <= $total_weight)
return $value;
}
}

Output to make sure it's still weighting correctly:

1 : expected 6666 ( 16.67%), actual 6554 ( 16.38%)
2 : expected 13333 ( 33.33%), actual 13352 ( 33.38%)
3 : expected 20000 ( 50.00%), actual 20094 ( 50.23%)

--
Andy Hassall (andy@andyh.co.uk) icq(5747695) (http://www.andyh.co.uk)
Space: disk usage analysis tool (http://www.andyhsoftware.co.uk/space)
Closed Thread


Similar PHP bytes