74 votes

Générer des résultats aléatoires en poids en PHP?

Je sais comment générer un nombre aléatoire en PHP mais disons que je veux un nombre aléatoire compris entre 1 et 10 mais que je veux plus de 3,4,5 puis 8,9,10. Comment est-ce possible? Je publierais ce que j'ai essayé, mais honnêtement, je ne sais même pas par où commencer.

121voto

Brad Points 61171

Basé sur la réponse / le lien de @ Allain, j'ai développé cette fonction rapide en PHP. Vous devrez le modifier si vous souhaitez utiliser une pondération non entière.

   /**
   * getRandomWeightedElement()
   * Utility function for getting random values with weighting.
   * Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
   * An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
   * The return value is the array key, A, B, or C in this case.  Note that the values assigned
   * do not have to be percentages.  The values are simply relative to each other.  If one value
   * weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
   * chance of being selected.  Also note that weights should be integers.
   * 
   * @param array $weightedValues
   */
  function getRandomWeightedElement(array $weightedValues) {
    $rand = mt_rand(1, (int) array_sum($weightedValues));

    foreach ($weightedValues as $key => $value) {
      $rand -= $value;
      if ($rand <= 0) {
        return $key;
      }
    }
  }
 

34voto

bobince Points 270740

Pour un nombre aléatoire efficace biaisé systématiquement vers une extrémité de l'échelle:

  • Choisissez un nombre aléatoire continu compris entre 0..1
  • Élever à un pouvoir γ, pour le biaiser. 1 n'est pas pondéré, plus bas donne plus de nombres élevés et vice versa
  • Échelle à la plage désirée et arrondi à l'entier

par exemple. en PHP (non testé):

 function weightedrand($min, $max, $gamma) {
    $offset= $max-$min+1;
    return floor($min+pow(lcg_value(), $gamma)*$offset);
}
echo(weightedrand(1, 10, 1.5));
 

26voto

Allain Lalonde Points 28717

Il y a un très bon tutoriel pour vous .

Fondamentalement:

  1. Faites la somme des poids de tous les nombres.
  2. Choisissez un nombre aléatoire inférieur à celui
  3. soustrayez les poids dans l’ordre jusqu’à ce que le résultat soit négatif et renvoyez ce nombre s’il l’est.

11voto

Iain Holder Points 7930

Le hack naïf pour cela serait de construire une liste ou un tableau comme

1, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 10

Et puis sélectionnez au hasard à partir de cela.

8voto

Brad Parks Points 5513

Ce tutoriel vous guide , en PHP, avec plusieurs solutions de copier / coller:

Une fonction extraite du post:

 /**
 * weighted_random_simple()
 * Pick a random item based on weights.
 *
 * @param array $values Array of elements to choose from 
 * @param array $weights An array of weights. Weight must be a positive number.
 * @return mixed Selected element.
 */

function weighted_random_simple($values, $weights){ 
    $count = count($values); 
    $i = 0; 
    $n = 0; 
    $num = mt_rand(0, array_sum($weights)); 
    while($i < $count){
        $n += $weights[$i]; 
        if($n >= $num){
            break; 
        }
        $i++; 
    } 
    return $values[$i]; 
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X