У меня есть List<Double>
, который содержит вероятности (веса) для выборки элемента. Например, List
содержит 5 следующих значений.
0.1, 0.4, 0.2, 0.1, 0.2
Каждое i-е Double
значение представляет собой вероятность выборки i-го элемента из другого List<Object>
.
Как я могу построить алгоритм для выполнения выборки в соответствии с этими вероятностями?
Я пробовал что-то вроде этого, где я сначала преобразовал список вероятностей в кумулятивную форму.
0.1, 0.5, 0.7, 0.8, 1.0
Тогда мой подход следующий. Я генерирую случайное двойное число и перебираю список, чтобы найти первый элемент, который больше, чем случайное двойное, а затем возвращаю его индекс.
Random r = new Random();
double p = r.nextDouble();
int total = list.size();
for(int i=0; i < total; i++) {
double d = list.get(i);
if(d > p) {
return i;
}
}
return total-1;
Этот подход медленный, поскольку я просматриваю список последовательно. На самом деле мой список состоит из 800 000 пунктов, связанных с весами (вероятностями), из которых мне нужно выбрать. Так что, разумеется, этот последовательный подход медленный.
Я не знаю, чем может помочь двоичный поиск. Скажем, я сгенерировал p = 0,01. Затем бинарный поиск может использовать рекурсию со списком следующим образом.
compare 0.01 to 0.7, repeat with L = 0.1, 0.5 compare 0.01 to 0.1, stop compare 0.01 to 0.5, stop
0,01 меньше 0,7, 0,5 и 0,1, но я, очевидно, хочу только 0,1. Так что критерии остановки мне все еще не ясны при использовании бинарного поиска.
Если есть библиотека, которая поможет с подобными вещами, мне тоже было бы интересно.