2017-01-31 3 views
0

У меня есть следующая проблема:Выберите объект случайным образом с различной вероятностью

Мне нужно, чтобы выбрать случайный объект из List. Это просто, если все элементы будут иметь одинаковый шанс.

В моем случае вероятность того, что объект будет выбран, сохраняется в другом List. Поэтому мне нужен метод, который случайным образом выбирает элемент из списка на основе другого List.

EDIT: E.g.

List<String> objects = Arrays.asList("one","two","three"); 
List<Double> chance = Arrays.asList(0.25, 0.25, 0.5); 

Теперь я хочу String «one» и «two» с вероятностью один из четырех и String «three» с вероятностью один из двух.

Благодарим за любые советы.

+0

Ваш вопрос не совсем понятен, можете ли вы поделиться каким-то кодом или результатом ввода вывода? –

+0

'тот же шанс' означает, что если ребенок уже выбирает, то больше не выбирайте выбранный интервал? –

+0

Я полагаю, что ваша сумма вероятностей равна 1? Затем просто используйте 'Math.random()', чтобы выбрать число '[0 .. 1)', а затем пройдите, вероятно, 'List' и суммируйте, пока не найдете первый элемент, который превышает вашу сумму. Верните элемент в этот индекс. –

ответ

2

Вы могли TreeMap с таким ключом текущего итог предыдущих вероятностей и в качестве значения соответствующего объекта, а затем сгенерировать случайное число между 0 и 1, и, наконец, использовать ceilingEntry(K key), чтобы получить объект, соответствующий первый ключ, который больше или равно текущему случайному значению.

Что-то вроде:

List<String> objects = Arrays.asList("one","two","three"); 
List<Double> chance = Arrays.asList(0.25, 0.25, 0.5); 

// Build the tree map 
TreeMap<Double, String> map = new TreeMap<>(); 
double total = 0.0d; 
for (int i = 0; i < objects.size(); i++) { 
    map.put(total += chance.get(i), objects.get(i)); 
} 
System.out.printf("The generated is map %s%n", map); 

// The generator of random numbers 
Random generator = new Random(); 
// Generate a random value between 0 and 1 
double value = generator.nextDouble(); 
// Get the object that matches with the generated number 
String object = map.ceilingEntry(value).getValue(); 
System.out.printf("The current value is %f corresponding to '%s'%n", value, object); 

Выход:

The generated map is {0.25=one, 0.5=two, 1.0=three} 
The current value is 0,048460 corresponding to 'one' 

Так вот:

  1. Если случайная величина меньше или равна 0.25, мы получим "one ».
  2. Если случайное значение находится между 0.25 (исключено) и 0.50 (включено), мы получим «two».
  3. Если случайное значение находится между 0.50 (исключено) и 1.0 (в комплекте), мы получим «three».

Благодаря тому, что nextDouble() возвращает значение doubleравномерно распределенную между 0.0 и 1.0, это достаточно хорошо, чтобы получить ожидаемое распределение.

+1

Спасибо, ваш solutuion отлично сработал для меня – Jermano

+0

Как вы получаете список ? я просто получаю сообщение об ошибке – TheCrazyProfessor

+0

какая ошибка? –

Смежные вопросы