random numbers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alexander Ross

    random numbers

    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

    #2
    Re: random numbers

    uhh sorry my english suxs but i dunno what u mean maybe reading this
    will help:
    PHP is a popular general-purpose scripting language that powers everything from your blog to the most popular websites in the world.

    with array_rand() u can get just random stuff out of a array and else
    try reading this just the basic random stuff:
    PHP is a popular general-purpose scripting language that powers everything from your blog to the most popular websites in the world.


    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]

    Comment

    • Andy Hassall

      #3
      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)

      Comment

      Working...