Re: Random With Odds
| From: | php3 at developersdesk dot com | Date: | Tue, 04 Jul 2000 06:54:20 +0000 |
| Subject: | Re: Random With Odds | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-4687@lists.php.net to get a copy of this message | ||
** Reply to note from richard@zend.com (Richard Lynch) Mon, 03 Jul 2000 22:03:42 -0500
> I am about to create a BIG script that will allow a banner to rotate.. I
> want to allow the user to select a weight for each banner.. 1 showing up
> 1.5x as much as 2, 2 showing up 1.5x more than 3, 3 showing up 1.5x more
> than 4, etc... how would I do that?? is there a way to setup rand to take in
> account the odds of picking one number, and is it possible to change those
> odds??
>
so 4 = 1 # 1 for the base
3 = 1.5 # 1 * 1.5
2 = 2.25 # 1.5 * 1.5
1 = 3.375 # 2.25 * 1.5
Multiply by 8 to eliminate fractions
4 = 1 * 8 = 8
3 = 1.5 * 8 = 12
2 = 2.25 * 8 = 18
1 = 3.375 * 8 = 27
------
Add them together 65
So you have 65 possibilities, 8 of them result in 4, 12 result in 3, 18
result in 2 and 27 result in 1. If you have an evenly distributed
random number it is easy to say:
0- 7 = 4
8-19 = 3
20-37 = 2
38-65 = 1
IF those are the only choices, and the frequencies, all the above can be
done by hand. You end up with an array like
$Ods = array( 4,4,4,4,4,4,4,4, # 8 fours
3,3,3,3,3,3,3,3,3,3,3,3, # 12 threes
2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2, # 18 twos
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1 ); # 27 ones
Now all you have to do:
$Result = $Ods[ rand( 0, 65 ) ];
By definition the result of the random value should be evenly
distributed, so the array above should be valid. Most people looking at
it would think it fixed, and would be happer seeing an array like:
array( 1,1,1,2,2,3,4,1,1,1,2,2,3,4,1,1,1,2,2,3,4,3,
1,1,1,2,2,3,4,1,1,1,2,2,3,4,1,1,1,2,2,3,4,3,
1,1,1,2,2,3,4,1,1,1,2,2,3,4,1,1,1,2,2,3,3 );
But realy mixing them up does nothing to change the ods.
Since you are writing a big script to do the job, you probably want a
variable number of entries, and a varialble hit probablility. That
means you need to script all of this.
Hint: Don't allow fractions in your frequencies. You can't have half
an array entry, so if you have fractions you have to multiply all the
items to eliminate the fractional part. If you can eliminate the
fractions up front you can do much easier.
If you numbers were 2 instead of 1.5 it would be
4 = 1 # number hits on 4 (1)
3 = 2 # Hits on 4 * 2
2 = 4 # Hits on 3 * 2
1 = 8 # Hits on 2 * 2
The ods array could be
array( 1,1,1,1,1,1,1,1,2,2,2,2,3,3,4 );
Or you could calculate the breakpoints as
1 = 0 - 7 # 8 entries or 0 - thru the number of hits on 1
2 = 8 - 11 # 4 entries or Last end + 1 thru last end + hits on 2
3 = 12 - 13 # 2 entries or last end + 1 thru last end + hits on 3
4 = 14 # 1 entry or last end + 1 thru nothing, since there
is only 1
Clear as mud, I presume...
Rick Widmer
Internet Marketing Specialists
www.developersdesk.com