Медленный, но простой способ сделать это - заставить каждого члена выбрать случайное число, основанное на его вероятности, и выбрать значение с наибольшим значением.
Аналогия:
Представьте, что нужно выбрать 1 из 3 человек, но у них разные вероятности. Вы даете им умереть с разным количеством лиц. У кубика первого лица 4 лица, у 2-го - 6, а у третьего - 8. Они бросают кубик, и выигрывает тот, у кого наибольшее число.
Допустим, у нас есть следующий список:
[{A,50},{B,100},{C,200}]
псевдокод:
A.value = random(0 to 50);
B.value = random(0 to 100);
C.value = random (0 to 200);
Мы выбираем тот, который имеет наибольшее значение.
Этот метод выше точно не отображает вероятности. Например, у 100 не будет удвоенного шанса на 50. Но мы можем сделать это, немного подправив метод.
Метод 2
Вместо выбора числа от 0 до веса мы можем ограничить их от верхнего предела предыдущей переменной до добавления текущей переменной.
[{A,50},{B,100},{C,200}]
псевдокод:
A.lowLimit= 0; A.topLimit=50;
B.lowLimit= A.topLimit+1; B.topLimit= B.lowLimit+100
C.lowLimit= B.topLimit+1; C.topLimit= C.lowLimit+200
результирующие пределы
A.limits = 0,50
B.limits = 51,151
C.limits = 152,352
Затем мы выбираем случайное число от 0 до 352 и сравниваем его с пределами каждой переменной, чтобы увидеть, находится ли случайное число в его пределах.
Я считаю, что этот твик имеет лучшую производительность, поскольку существует только 1 случайное поколение.
В других ответах есть аналогичный метод, но для этого метода не требуется, чтобы сумма составляла 100 или 1,00.