sql >> Base de Datos >  >> RDS >> Mysql

Selección aleatoria ponderada de un evento

Dos formas de hacer esto, que puedo pensar desde la parte superior de mi cabeza:

Opción 1:complete una nueva matriz con los valores clave del conjunto de datos, donde el peso determina la frecuencia con la que se repite un elemento. La proporción en esta matriz entonces coincide con la distribución ponderada. Simplemente tome usando $arr[array_rand($arr)] . Si bien es simple y fácil de entender, esto le explotará en la cara si hay MUCHOS artículos o si los valores de peso son realmente altos.

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

Opción 2. Suma los pesos. Elija un número aleatorio entre 0 y la suma de pesos. Recorra los elementos en el conjunto de datos, compárelos con el número aleatorio que eligió. Tan pronto como encuentre uno que sea igual o mayor que el índice aleatorio, seleccione ese elemento.

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

Siguiendo nuestra conversación en los comentarios a continuación, aquí hay un Pastebin con el código:

http://pastebin.com/bLbhThhj