Существует простой алгоритм случайного выбора предмета, при котором предметы имеют индивидуальный вес:
1) посчитайте сумму всех весов
2) выберите случайное число, которое равно 0 или больше и меньше суммы весов
3) просматривайте элементы по одному, вычитая их вес из случайного числа, пока не получите элемент, случайное число которого меньше веса этого элемента.
Псевдокод, иллюстрирующий это:
int sum_of_weight = 0;
for(int i=0; i<num_choices; i++) {
sum_of_weight += choice_weight[i];
}
int rnd = random(sum_of_weight);
for(int i=0; i<num_choices; i++) {
if(rnd < choice_weight[i])
return i;
rnd -= choice_weight[i];
}
assert(!"should never get here");
Это должно быть легко адаптировать к вашим буст-контейнерам и тому подобному.
Если ваши веса редко меняются, но вы часто выбираете один случайным образом, и пока ваш контейнер хранит указатели на объекты или имеет длину более нескольких десятков элементов (в основном, вы должны профилировать, чтобы знать, помогает это или мешает) , то идет оптимизация:
Сохраняя сумму совокупного веса в каждом элементе, вы можете использовать двоичный поиск, чтобы выбрать элемент, соответствующий весу выбора.
Если вы не знаете количество элементов в списке, тогда существует очень удобный алгоритм, называемый отбором проб резервуара, который можно адаптировать для взвешивания.