Avatar billede j1x4r4 Nybegynder
19. september 2006 - 16:46 Der er 10 kommentarer og
1 løsning

Kontrolleret rand()

Jeg forsøger for tiden at lave noget bannerotation.. Hvor man skal kunne styre hvor stor sandsynlighed der er for et bestemt banner kommer frem.

Til dette vil jeg høre om der findes, eller kan laves en kontrolleret rand()?

Indtil videre er det eneste jeg kan komme i tanken om at lave 100 felter i en tabel MySQL tabel, og så indsætte "Banner_1" i 30 af felterne, "Banner_2" i 20 af felterne og "Banner_3" i de sidste 50 felter.. Men årsagen til at jeg ikke bruger dette, er at jeg ikke ved hvordan jeg kan få php til at ændre det igen, uden at overskrive de gamle værdier.. :)

Håber i kan hjælpe
J1x4r4
Avatar billede j1x4r4 Nybegynder
19. september 2006 - 16:51 #1
Jeg skulle måske have beskrevet hvad jeg mener med en "kontrolleret rand()"

Det jeg mener er at der skal være fx 30% chance for at den rammer lige netop en bestemt værdi..
Avatar billede well_r Nybegynder
19. september 2006 - 17:26 #2
prøv evt. sådan her:
$rand = rand(10);
if ($id < 3){ // dvs. 0,1,2
  $værdi = blah;
  //blah kunne udskiftes med noget andet
}
else {
værdi = $id
}

det er bare illustrativt
Avatar billede well_r Nybegynder
19. september 2006 - 17:30 #3
du kunne jo skrive det ind i en php fil.. hvor mange procent..

$cfg[banner_1] = 30;
$cfg[banner_2] = 20;

$rand = rand(100);
if ($rand < $cfg[banner_1]){ // under 30 = banner 1
  blah
}
elseif($rand < $cfg[banner_1]+$cfg[banner_2]){ // alt under 50 = banner 2
osv..
Avatar billede well_r Nybegynder
19. september 2006 - 17:31 #4
eller selvfølgelig hente det fra en database, hvis du ikke gider at gøre det i en fil..
bare husk at sørge for at de samlet set giver 100%
Avatar billede j1x4r4 Nybegynder
19. september 2006 - 17:36 #5
Problemet er bare at der muligvis skal laves flere bannere i rotationen, hvilket også gerne skal foregå dynamisk :)
Avatar billede coderdk Praktikant
19. september 2006 - 18:20 #6
Her er et script jeg lige har smidt sammen, det er måske lidt forvirrende, og det kan måske gøres bedre, men gider ikke bruge mere tid på det, da det ser ud til at fungere :)

<?php

    class WeighedSelect
    {
        var $weights = 0;
        var $array = array();
       
        function WeighedSelect( $array )
        {
            $this->array = $array;
            $sum = 0;
            foreach ( $this->array as $item )
            {
                if ( !array_key_exists( 'weight', $item ) )
                {
                    $sum += 1;   
                }
                else
                {
                    $sum += $item['weight'];
                }
            }
            $weights = 1000 / $sum;
            $n = count( $this->array );
            $sum = 1000;
            for ( $i = 0; $i < $n; $i++ )
            {
                $w = 0;
                if ( !array_key_exists( 'weight', $this->array[$i] ) )
                {
                    $w += $weights;   
                }
                else
                {
                    $w += ( $weights * $this->array[$i]['weight'] );
                }
                $this->array[$i]['max'] = $sum;
                $sum -= $w;
                $this->array[$i]['min'] = $sum;
            }
        }
       
        function GetItem()
        {
            $rand = mt_rand( 1, 1000 );
            $n = count( $this->array );
            foreach ( $this->array as $item )
            {
                if ( $item['min'] < $rand && $rand <= $item['max'] )
                {
                    return $item['value'];
                }               
            }
        }
    }

/* Test data */
    $array = array(
            array(
                "value" => "værdi nummer 1"
                ,"weight" => "1"
            )
            ,array(
                "value" => "værdi nummer 2"
                ,"weight" => "20"
            )
            ,array(
                "value" => "værdi nummer 3"
                ,"weight" => "5"
            )
            ,array(
                "value" => "værdi nummer 4"
                // Default weight er 1
            )
        );

/* Eksempeldata for at se spredningen af valgene */
    $select = new WeighedSelect( $array );
    $result = array();
    for ( $i = 0; $i < 100; $i++ )
    {
        $item = $select->GetItem();
        if ( array_key_exists( $item, $result ) )
        {
            $result[$item]++;
        }
        else
        {
            $result[$item] = 1;
        }
    }
    ksort( $result );
    foreach ( $result as $item => $count )
    {
        echo "$item : $count<br>";
    }

?>
Avatar billede j1x4r4 Nybegynder
19. september 2006 - 18:47 #7
coderdk... Jeg forstår endnu ikke classes.. Hvordan bruger jeg det der script? :)
Avatar billede coderdk Praktikant
19. september 2006 - 18:56 #8
Antag at du har en tabel "banner" i MySQL med bannere:

bannerid | weight | url
1          1          http://www.example.com/banner1
2          5          http://www.example.com/banner2
3          2          http://www.example.com/banner3

Så vil du kunne bruge klassen sådan:

$sql = "SELECT weight, url FROM banner";
$qh = mysql_query( $sql ) or die( mysql_error() );
$banners = array();
while ( $row = mysql_fetch_assoc( $qh ) )
{
  $banners[] = array( "value" => $row['url'], "weight" => $row['weight'] );
}

$randBanner = new WeighedSelect( $banners );
echo $randBanner->GetItem();
Avatar billede j1x4r4 Nybegynder
19. september 2006 - 22:09 #9
Jeg bryder mig ikke meget om at bruge et system jeg ikke kender :-)

Kan det ikke laves som noget mindre avanceret? eller findes der er en god artikkel, som forklarer classes helt fra bunden? :)
Avatar billede coderdk Praktikant
19. september 2006 - 22:21 #10
Et system du ikke kender? Der er trods alt ikke så megen kode, og den laver det du efterlyser ;) Men ok, det må du selvfølgelig selv om ;)
Prøv en af disse tutorials:

http://google.com/search?q=oop+php+tutorial
Avatar billede j1x4r4 Nybegynder
02. oktober 2006 - 15:43 #11
Jeg har "desværre for jer andre" løst problemet..

Jeg lavede en tabel med 100 felter, og så skriver den banner_id i fx 45 af felterne, hvis det skal være 45 procent..

Mange tak for jeres hjælp, det var lærerigt..
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester