PHP MYSQL - Random Result With Weight?

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

Post Reply
idotcom
Forum Commoner
Posts: 69
Joined: Thu Mar 04, 2004 9:24 pm

PHP MYSQL - Random Result With Weight?

Post 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! :D
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post 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.
idotcom
Forum Commoner
Posts: 69
Joined: Thu Mar 04, 2004 9:24 pm

Post 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
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post 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.
smudge
Forum Contributor
Posts: 151
Joined: Sun May 20, 2007 12:13 pm

Post 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
artoonie
Forum Newbie
Posts: 10
Joined: Sat Jun 09, 2007 3:06 am

Post 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' />";
  }
}
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post 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.
idotcom
Forum Commoner
Posts: 69
Joined: Thu Mar 04, 2004 9:24 pm

Post 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) :lol: 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?
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post 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.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

gregambrose
Forum Newbie
Posts: 12
Joined: Thu Aug 07, 2003 11:01 pm
Location: Sydney, Australia

Post 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
idotcom
Forum Commoner
Posts: 69
Joined: Thu Mar 04, 2004 9:24 pm

Post 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 :)
Post Reply