There is an array of N elements, and an array of coefficients of probability of loss of each element. How can I implement the selection of a random element from this array?

I implemented it like this, but I think it is not very good.

$items = array(10, 20, 30); $factors = array(0.2, 0.5, 0.3); $values = array(); foreach ($factors as $indexFactors => $valueFactors) { $values[$indexFactors] = summ($factors, $indexFactors); } echo $items[ getIndex($values) ]; function getIndex($values) { $random = rand(0, 10) / 10; foreach ($values as $key => $value) { if ($random <= $value) return $key; } } function summ($array, $index) { if ($index) { return $array[$index] + summ($array, $index - 1); } else { return $array[$index]; } } 
  • one
    Just keep in mind that the sum of the elements of the array db. 1 and they should be ordered in ascending order. It would be nice to check these conditions, for example, on the first call. - avp
  • I know about the unit, I did just that. Why ascending? - Bender
  • Orderliness of birth does not play due to the uniform distribution. - Stas0n

2 answers 2

I do not write in php, but the idea would suggest the following:
If I were you, I would implement a random number generator that obeys your distribution (factors)
Look, you have a random function that can generate a uniform distribution on the [0,1] segment. With the help of this you can subordinate the uniform distribution to any other, in particular, to yours. For example, you generated a random variable — then you simply add up the sum in its distribution, until it becomes larger than this randomly larger value. How many times you add items from an array of probabilities will give the index of the corresponding item from items. Example: prob = {0.1, 0.2, 0.5 0.3} val = {10, 20, 30, 40} You generate a random value from 0 to 1 - let, for example, it is equal to 0.7. Then you have such amount: 0.1 + 0.2 + 0.5 = 0.8> 0.7 So the element index = 2, i.e. thirty

  • Thank! =) But my code does just that) - Bender
  • Glimpsed the code, saw something similar, but did not peer much ... And the reception is standard) Good luck! - Stas0n
  1. There is an array of probabilities: array(0.2, 0.5, 0.3);

  2. Generating N numbers from 1 to 100, and multiplying by probabilities, we get something like:

     array(0.2 * 56, 0.5 * 23, 0.3 * 43); => array(11,2, 11,5, 12,9) 
  3. Choose the largest number after multiplication. If there are identical, you can randomly among them on equal terms.