Mysql
 sql >> Base de données >  >> RDS >> Mysql

Sélection aléatoire pondérée d'un événement

Deux façons de le faire, auxquelles je peux penser du haut de ma tête :

Option 1 :remplissez un nouveau tableau avec les valeurs de clé de l'ensemble de données, où le poids détermine la fréquence de répétition d'un élément. La proportion dans ce tableau correspond alors à la distribution pondérée. Saisissez simplement en utilisant $arr[array_rand($arr)] . Bien que simple et facile à comprendre, cela vous explosera au visage s'il y a BEAUCOUP d'articles ou si les valeurs de poids sont vraiment élevées.

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

Option 2. Additionnez les poids. Choisissez un nombre aléatoire entre 0 et la somme des poids. Faites une boucle sur les éléments de l'ensemble de données, comparez-les au nombre aléatoire que vous avez choisi. Dès que vous en touchez un qui est égal ou supérieur à l'index aléatoire, sélectionnez cet élément.

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;
}

Suite à notre conversation dans les commentaires ci-dessous, voici un Pastebin contenant le code :

http://pastebin.com/bLbhThhj