Page 1 of 1
PHP MYSQL - Random Result With Weight?
Posted: Sun Jul 01, 2007 4:35 pm
by idotcom
Hi,
I am trying to put together a script for a small and simple banner rotation script. But I need to be able to add more "weight" to certain banners, so that some banners display more than others. I tried to find info online but no luck yet. If you know of a good tutorial for this, please let me know. I would greatly appreciate any code samples or suggestions.
Thank you!

Posted: Sun Jul 01, 2007 5:08 pm
by artoonie
i'll give this a shot
If you have two banners, image 1 and image 2, this will give image 1 30% chance, and image 2 70%.
Code: Select all
$number = random(100);
if($number<=30)
echo("<img src=\"image1.gif\">");
else
echo("<img src=\"image2.gif\">");
If you have an array of banners, this will give them 20, 30, and 50 percent chances, respectively
Code: Select all
$banners = array{"image1.gif","image2.gif","image3.gif"};
$number = random(100);
if($number<=20)
echo("<img src=\"{$banners[0]}\">");
else if ($number<=50)
echo("<img src=\"{$banners[1]}\">");
else
echo("<img src=\"{$banners[2]}\">");
the second can be easily modified to fit however many banners you want. you need to give the percentages though.
Posted: Sun Jul 01, 2007 5:19 pm
by idotcom
Hi,
Thanks for your reply.
I actually saw that same code on a tutorial site (the only one I found), but I tried using it with a database and I get weird results.
Here's how I tried it:
Code: Select all
$weight=rand(1, 100);
$banner="SELECT * FROM banner_rotator WHERE weight<=$weight LIMIT 1";
In the db banners are like this:
Bannerid, weight
Bannerid 15
Bannerid 45
Bannerid 20
Bannerid 75
Bannerid 90
Bannerid 50
Posted: Sun Jul 01, 2007 5:23 pm
by superdezign
Randomizing it still leaves chance that any of them will have more weight. If you want to give it more weight, just loop thrugh all of the banners, and give the ones with more weight more entries into the loop. That's the simplest way to do it.
Posted: Sun Jul 01, 2007 5:37 pm
by smudge
artoonie's got the right idea. This should work better yet:
Code: Select all
$n=random(100);
$banners["image1.gif"]=array(0,20);
$banners["image2.gif"]=array(21,50);
$banners["image3.gif"]=array(51,100);
foreach($banners as $img => $chance){
if($n >= $chance[0] && $n <= $chance[1]){
echo "<img src='$img' />";
}
}
Just note that I haven't tested this, but it's the general idea
Posted: Sun Jul 01, 2007 5:40 pm
by artoonie
to smudge, i messed up. its actually << rand(lowest, highest >>, not << random(highest) >>
so to correct the code:
Code: Select all
$n=rand(1,100);
$banners["image1.gif"]=array(0,20);
$banners["image2.gif"]=array(21,50);
$banners["image3.gif"]=array(51,100);
foreach($banners as $img => $chance){
if($n >= $chance[0] && $n <= $chance[1]){
echo "<img src='$img' />";
}
}
Posted: Sun Jul 01, 2007 5:47 pm
by superdezign
The problem with randomization is the fact that it's random. If advertisers are paying you, they are likely paying for the weight, not for the chance of having the weight. You can return all low random numbers or all high random numbers and it still be completely randomized.
If these people are paying for their banners, they'll want a guarantee of being shown a certain amount of times. Banners are typically cycled through and the advertisers who pay more have more spots in that cycle.
Posted: Sun Jul 01, 2007 6:11 pm
by idotcom
Thank you all for your help so far. I think there's a good number of people who are looking for something like this, yet there's not much info on it, and most of the scripts that do this already, cost money. In my case, I don't need the script, just the small piece of code to grab the banner with weight.
Technically it does work. However, I don't see how this would work with more than 100 banners. Maybe I'm just tired or (retarted)

But how can you do it with more banners when you're working with 1-100? Or, when you're setting up the weight value for the banner, how do you not duplicate?
Is this the same as doing percentage values? Or is there a way to do this with just percentage based?
superdezign You make good points. And just for the record, this is not for people paying for banner spots.
Do you have any suggestions or code samples to do that? Randomizing higher values? But what about lower values?
Posted: Sun Jul 01, 2007 6:22 pm
by superdezign
As you add banners, all other banners will have less weight. Doing it with percentages won't work. If you use multiple database entries, you can still use the random number, but make it from 0 to the highest id, and select a banner that way.
Posted: Sun Jul 01, 2007 6:27 pm
by Weirdan
Posted: Sun Jul 01, 2007 7:27 pm
by gregambrose
I won't write the PHP code, but here is an algorithm that might work.
Give every ad a weighting between 1 and 100.
To select one to display, do the following
1. choose a random number between 1 and 100, X
2. select all ads with a weight greater then X
3. from the resulting list list, choose one at randon.
Thus, the higher a weighting, the more chance it will be chosen.
Does this help?
Regards,
Greg
Posted: Sun Jul 01, 2007 9:03 pm
by idotcom
I suppose there is more than one way to do it...
I ended up with this, which seems to be working ok.
Weight scale: 1-10
Code: Select all
$query = "SELECT * FROM banners ORDER BY id ASC";
$results = mysql_db_query ($dbname,$query,$conn);
while($row = mysql_fetch_array($results))
{
for($i=1; $i <= $row['weight']; $i++)
{
$banner_id_array[] = $row['id'];
}
}
srand ((double) microtime() * 1000003);
$rand_id = rand(0, count($banner_id_array)-1);
$selected_banner_id = $banner_id_array[$rand_id];
Thank you for your help everyone
