Randomising a no. between 0 and 100.....

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Randomising a no. between 0 and 100.....

Post by megaming »

Ok, I have found half of the answer here: http://www.devnetwork.net/forums/viewtopic.php?t=4906

So at the moment, I have:

Code: Select all

<?php 
   // define re-mapping function 
   function remap($floatNumber) &#123; 
      return pow($floatNumber,2) ; 
   &#125; 

   // get a random number between 0 and 1 
   $randval = mt_rand() / mt_getrandmax() ; 
   // apply the remapping function 
   $skewrandval = remap($randval) ; 
   // make the new number fit in the original range 
   $skewrandval = $skewrandval * (100 - 1) + 1; 
   // you can make the result an integer now 
   $finalrandval = floor($skewrandval) ; 
?>
The thing is, I need it to be affected by $var which has a value between 1 and 250.

So if $var is 250, $finalrandval is pretty likely to be higher than if $var was 1.

Anyone know how to do this? I hope you understand what I mean...

Thanks :D
User avatar
hob_goblin
Forum Regular
Posts: 978
Joined: Sun Apr 28, 2002 9:53 pm
Contact:

Post by hob_goblin »

try this, i dont know if it will work, but its worth a try:

Code: Select all

<?php 
   // define re-mapping function 
   function remap($floatNumber) &#123; 
      return pow($floatNumber,2) ; 
   &#125; 


   $var = 250; // Upper boundry


   // get a random number between 0 and 1 
   $randval = mt_rand() / mt_getrandmax() ; 
   // apply the remapping function 
   $skewrandval = remap($randval) ; 
   // make the new number fit in the original range 
   $skewrandval = $skewrandval * ($var - 1) + 1; 
   // you can make the result an integer now 
   $finalrandval = floor($skewrandval) ; 
?>
megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Post by megaming »

no, thats not what I meant :(
User avatar
hob_goblin
Forum Regular
Posts: 978
Joined: Sun Apr 28, 2002 9:53 pm
Contact:

Post by hob_goblin »

maybe this?

Code: Select all

<?php 

   assist_val($variable)&#123;
   $foo = $variable / 250;
   $rand = mt_rand() / mt_getrandmax();
   $bar = $foo * rand;
   return floor($bar);
   &#125;


   $var = 250;

   echo assist_val($var);

?>
megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Post by megaming »

i'm getting a parse error on line 3 of that code :(
User avatar
hob_goblin
Forum Regular
Posts: 978
Joined: Sun Apr 28, 2002 9:53 pm
Contact:

Post by hob_goblin »

Oh, woops, typo:

[edit]

doesn't work anyways... i dont know, this is hard, i'll think of something

[/edit]
Rob the R
Forum Contributor
Posts: 128
Joined: Wed Nov 06, 2002 2:25 pm
Location: Houston

Post by Rob the R »

Like the earlier post you referenced mentioned, you can tweak the second argument of the pow function to skew less or more. IN this case, a number lower than one will skew toward the higher numbers. You could therefore pass $var to the remap() function to do something like this:

Code: Select all

<?php
   // define re-mapping function 
   function remap($floatNumber,$skewfactor) { 
      // assume $skewfactor is between 1 and 250
      // we want the minimum $exponent value to be 1/25,
      // which will skew toward the high values quite a lot.
      // The "10" value below can be increased if the skew
      //  is too severe.
      $exponent = 10 / $skewfactor ;
      // make sure we don't have any positive exponents
      // (which would remap values toward the low numbers)
      if ($exponent > 1) {
         $exponent = 1 ;
      }
      return pow($floatNumber,$skewfactor) ; 
   } 

   // 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 in the original range 
   $skewrandval = $skewrandval * (100 - 1) + 1; 
   // you can make the result an integer now 
   $finalrandval = floor($skewrandval) ; 
?>
You should still experiment to see how skewed your results are for different values of $var. A $var of 250 might produce way too much skew toward the high numbers; if so, just increase the "10" in the remap() function.
megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Post by megaming »

Rob, thats great, but the $finalrandval is always 1....
Rob the R
Forum Contributor
Posts: 128
Joined: Wed Nov 06, 2002 2:25 pm
Location: Houston

Post by Rob the R »

Well, perhaps the "10" should be changed. Try changing it to "100" and see what happens.
megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Post by megaming »

I'm still getting 1 every time :(

I tried it on 1000 too....
User avatar
Elmseeker
Forum Contributor
Posts: 132
Joined: Sun Dec 22, 2002 5:48 am
Location: Worcester, MA

Post by Elmseeker »

Hmmm...$exponent is defined as 10 divided by the $skewfactor and then reset to 1 if it's larger than 1...so $exponent is always .(something) or 1. Not sure if this is affcting the output or not but I am just wondering why it is being done this way?

Code: Select all

<?php
      $exponent = 10 / $skewfactor ; 
      // make sure we don't have any positive exponents 
      // (which would remap values toward the low numbers) 
      if ($exponent > 1) { 
         $exponent = 1 ; 
      } 
?>
Rob the R
Forum Contributor
Posts: 128
Joined: Wed Nov 06, 2002 2:25 pm
Location: Houston

Post by Rob the R »

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.
User avatar
Elmseeker
Forum Contributor
Posts: 132
Joined: Sun Dec 22, 2002 5:48 am
Location: Worcester, MA

Post by Elmseeker »

Ahhh, yes, thank you. IMHO the new way makes a bit more sense...I can at least understand what it does by looking at it now anyway lol...Thanks again, appreciate the explanation. :)
megaming
Forum Commoner
Posts: 27
Joined: Wed Dec 25, 2002 12:31 pm

Post by megaming »

cool!

Thanks for dedicating so much time to this everyone (rob especially)!

I can finally get my script working now :D
S_henry
Forum Contributor
Posts: 148
Joined: Sun Jan 25, 2004 10:25 pm
Location: M'sia

Math Problem

Post by S_henry »

I want to display 12345.6789 as 1.23456789e+4. Anybody knows what function in PHP I should use?
Post Reply