Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Seleção ponderada aleatória de um evento


Duas maneiras de fazer isso, que eu posso pensar do topo da minha cabeça:

Opção 1:Preencha um novo array com os valores-chave do conjunto de dados, onde o peso determina com que frequência um item é repetido. A proporção nesta matriz corresponde à distribuição ponderada. Simplesmente pegue usando $arr[array_rand($arr)] . Embora simples e fácil de entender, isso explodirá na sua cara se houver muitos itens ou se os valores de peso forem realmente altos.
$weighted = array();
foreach($items as $item) {
    array_merge($weighted, array_fill(0, $item['weight'], $item['value']);
}
$result = $weighted[array_rand($weighted)];

Opção 2. Some os pesos. Escolha um número aleatório entre 0 e a soma dos pesos. Faça um loop sobre os elementos no conjunto de dados, compare com o número aleatório que você escolheu. Assim que você encontrar um que seja igual ou maior que o índice aleatório, selecione esse 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;
}

Seguindo nossa conversa nos comentários abaixo, aqui está um Pastebin com o código nele:

http://pastebin.com/bLbhThhj