Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Zufällig gewichtete Auswahl eines Ereignisses

Zwei Möglichkeiten, dies zu tun, die mir spontan einfallen:

Option 1:Füllen Sie ein neues Array mit den Schlüsselwerten aus dem Datensatz, wobei die Gewichtung bestimmt, wie oft ein Element wiederholt wird. Der Anteil in diesem Array entspricht dann der gewichteten Verteilung. Greifen Sie einfach mit $arr[array_rand($arr)] . Obwohl es einfach und leicht zu verstehen ist, wird es Ihnen ins Gesicht springen, wenn es viele Artikel gibt oder wenn die Gewichtswerte sehr hoch sind.

$weighted = array();
foreach($items as $item) {
    array_merge($weighted, array_fill(0, $item['weight'], $item['value']);
}
$result = $weighted[array_rand($weighted)];

Option 2. Summieren Sie die Gewichte. Wählen Sie eine Zufallszahl zwischen 0 und der Summe der Gewichte. Wiederholen Sie die Elemente im Datensatz und vergleichen Sie sie mit der von Ihnen ausgewählten Zufallszahl. Sobald Sie eines treffen, das gleich oder größer als der zufällige Index ist, wählen Sie dieses Element aus.

function findRandomWeighted(array $input) {
   $weight = 0;
   // I'm assuming you can get the weight from MySQL as well, so this loop really should not be required. In that case $weight becomes a parameter.
   foreach($items as $item) {
      $weight += $item['weight'];
   }

   $index = rand(1, $weight);
   foreach($items as $item) {
      $index -= $item['weight'];
      if($index <= 0) { return $item['value'] }
   }

   return null;
}

Nach unserem Gespräch in den Kommentaren unten ist hier ein Pastebin mit dem darin enthaltenen Code:

http://pastebin.com/bLbhThhj