Mysql
 sql >> Database >  >> RDS >> Mysql

Selezione casuale ponderata di un evento

Due modi per farlo, che mi vengono in mente dall'alto della mia testa:

Opzione 1:riempi una nuova matrice con i valori chiave del set di dati, dove il peso determina la frequenza con cui un elemento viene ripetuto. La proporzione in questa matrice corrisponde quindi alla distribuzione ponderata. Prendi semplicemente usando $arr[array_rand($arr)] . Sebbene sia semplice e facile da capire, questo ti esploderà in faccia se ci sono MOLTI articoli o se i valori di peso sono davvero alti.

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

Opzione 2. Somma i pesi. Scegli un numero casuale compreso tra 0 e la somma dei pesi. Passa in rassegna gli elementi nel set di dati, confrontali con il numero casuale che hai scelto. Non appena ne trovi uno uguale o maggiore dell'indice casuale, seleziona quell'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;
}

Seguendo la nostra conversazione nei commenti qui sotto, ecco un Pastebin con il codice in esso:

http://pastebin.com/bLbhThhj