Zufallsfunktion mit Priorisierung

PhoenixDH

Erfahrenes Mitglied
Suche eine gute Möglichkeit, Werbenanner zufällig anzuzeigen.
Das ganze soll so sein, dass die Möglichkeiten für alle Banner möglichst gleich ist.

Im Moment löse ich das so:
Code:
     srand ((double)microtime()*1000000);
     $random = rand(0,300);
     if ($random > 200)
     {
     }
     elseif ($random > 100)
     {
     }
     else
     {
     }
... für hier 3 Möglichkeiten. Ist es besser die Intervalle runterzusetzen, damit die Anzeigechancen besser/gleicher werden (z.B. rand(0,300))?

Gibt es noch ne Möglichkeit zu priorisieren? Z.B. wenn ich für eines der 3 das Intervall auf 200 setze und die anderen jeweils auf 50? Müsste ja klappen oder?

Das ganze soll so einfach wie möglich sein, also ne SQL Unterstützung brauche ich eigentlich im Moment noch nicht.

Dank euch recht herzlich.
 
Du könntest Folgendes machen:
PHP:
$array = array(
	'high'   => array(
		// höhere Wahrscheinlichkeit (3:6)
	),
	'normal' => array(
		// normale Wahrscheinlichkeit (2:6)
	),
	'low'    => array(
		// geringere Wahrscheinlichkeit (1:6)
	),
);
switch( rand(0, 1*2*3 - 1) ) {
	case 0:
	case 1:
	case 2:
		echo array_rand($array['high']);
		break;
	case 3:
	case 4:
		echo array_rand($array['normal']);
		break;
	case 5:
		echo array_rand($array['low']);
		break;
}
 
Das würde meiner Meinung nach so aussehen:
Code:
     srand ((double)microtime()*1000000);
     $random = rand(0,500);
     if ($random > 200)
     {
     }
     elseif ($random > 100)
     {
     }
     else
     {
     }

oder z.B.

Code:
     srand ((double)microtime()*1000000);
     $random = rand(0,300);
     if ($random > 100)
     {
     }
     elseif ($random > 50)
     {
     }
     else
     {
     }

Denke ich.

Wie würde dein Bsp. denn aussehen, denn ich verstehe den Part hier z.B. nicht:
Code:
switch( (int) rand(0, 1*2*3) % 1*2*3 ) {

Hier würde dann ja der Code hinkommen oder:
Code:
    'high'   => array(
        // höhere Wahrscheinlichkeit (3:6)
 
In deinen Beispielen wäre die Wahrscheinlichkeitsverteilung 3:5, 1:5 und 1:5 beziehungsweise 4:6, 1:6 und 1:6.
 
Ok, mein System hab ich somit verstanden ;)
Bei 3:5 und 1:5 und 1:5 würde eine also 3 mal so oft angezeigt werden!
Also würde mein System ja auch gehen oder?

Kannst du mir dein Bsp. bitte noch etwas erläutern?
 
In meinem Beispiel wird mit dem „(int) rand(0, 1*2*3) % 1*2*3“ eine zufällige Ganzzahl im geschlossenen Intervall [0, 5] ermittelt, die dann auf die drei Fälle mit den unterschiedlichen Wahrscheinlichkeitsverteilungen abgebildet wird.

Nachtrag: Ich merke gerade, dass bereits „rand(0, 1*2*3 - 1)“ nur Ganzzahlwerte zwischen 0 und 5 liefert. Ich hab mein oben genanntes Beispiel entsprechend angepasst.
 
Achso ok!

Wenn ich dann in deinem Bsp. noch mehr Fälle haben will, muss ich die Variable erhöhen oder? Also rand(0, 1*2*3*4 - 4) für 20? Oder wie bei mir rand(0,19)? Um die wahrscheinlichkeit zu erhöhen, mehr leere CASES vorher einfügen oder?

Die letzte Frage, wo muss der Code hin der ausgegeben werden soll?

Dank dir recht herzlich!
 
Ich habe mal eben eine Funktion geschrieben, mit der neben dem Array auch eine Wahrscheinlichkeitsverteilung angegeben werden kann:
PHP:
function getRandomElement( $array, $propDistr=null )
{
	$retVal = null;
	if( !is_array($array) ) {
		return false;
	}
	$keys = array_keys($array);

	if( !is_string($propDistr) ) {
		$retVal = array_rand($array);
	} else {
		$propDistr = explode(':', $propDistr);
		if( count($array) !== count($propDistr) ) {
			return false;
		}
		$rand = rand() / getrandmax();
		$propSum = array_sum($propDistr);
		$sum = 0;
		foreach( $propDistr as $key => $value ) {
			if( $value > 0 ) {
				$sum += $value/$propSum;
				if( $rand < $sum ) {
					$retVal = $array[$keys[$key]];
					break;
				}
			}
		}
	}
	return $retVal;
}
Der zweite Parameter ist optional, muss aber falls angegeben das Format „m:n“ haben, wobei die Anzahl der Wahscheinlichkeitsverteilungswerte mit der Anzahl der Arrayelemente übereinstimmen muss. Bei drei Elementen wäre es also „m:n:o“, bei vier „m:n:o:p“ und so weiter.
 
Zurück