Istnieje prosty algorytm do losowego wybierania przedmiotu, w którym przedmioty mają indywidualną wagę:
1) obliczyć sumę wszystkich wag
2) wybierz liczbę losową równą 0 lub większą i mniejszą niż suma wag
3) przeglądaj elementy pojedynczo, odejmując ich wagę od liczby losowej, aż otrzymasz przedmiot, w którym liczba losowa jest mniejsza niż waga tego przedmiotu
Pseudokod ilustrujący to:
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");
Powinno to być proste, aby dostosować się do twoich pojemników do przyspieszania i tym podobnych.
Jeśli twoje ciężary są rzadko zmieniane, ale często wybierasz jeden losowo i tak długo, jak twój pojemnik przechowuje wskaźniki do obiektów lub ma więcej niż kilkadziesiąt przedmiotów (w zasadzie musisz profilować, aby wiedzieć, czy to pomaga, czy przeszkadza) , to jest optymalizacja:
Przechowując skumulowaną sumę wag w każdej pozycji, możesz skorzystać z wyszukiwania binarnego w celu wybrania pozycji odpowiadającej masie pobrania.
Jeśli nie znasz liczby pozycji na liście, istnieje bardzo zgrabny algorytm zwany próbkowaniem zbiorników, który można dostosować do ważenia.