Java случайное число с высокой вероятностью - PullRequest
3 голосов
/ 26 августа 2011

У меня есть массив char[] Select = {'A','B','C','D','E','F','G','H','I','J'}, и каждый элемент в этом массиве имеет различную вероятность выбора. Например,

int[] Weight =  {10,30,25,60,20,70,10,80,20,30};

Мое требование - выбрать 5 элементов из этого массива, и элемент с высокими значениями веса имеет более высокую вероятность выбора, и эти 5 элементов должны быть разными.

Мой план - первая сумма веса

int[] weightSum = {10, 40, 65, 125, 145, 215, 225, 305, 325, 355}

Затем я использую Random, чтобы сгенерировать случайное число k в диапазоне [0,355]. Затем ищем первый элемент, который больше k в weightSum[]. Этот процесс повторяется 5 раз.

Проблема в том, что элемент с высокой вероятностью может быть выбран несколько раз. Я пытаюсь удалить дубликаты элементов на каждой итерации. Дубликаты удаляются, но элемент с высокими значениями веса не выбирается.

Как решить эту проблему?

спасибо.

Ответы [ 5 ]

3 голосов
/ 26 августа 2011

Не уверен, что я правильно понимаю, но как насчет этого:

  • после первого выбора вы удаляете выделенный элемент из char[] Select
  • Вы также удаляете соответствующий вес из int[] Weight
  • регенерация int[] weightSum
  • повторить весь процесс
1 голос
/ 26 августа 2011

не поддерживает совокупную сумму и не корректирует ее каждый раз: (хотя для каждого выбора требуется O (n))

char[] Select = {'A','B','C','D','E','F','G','H','I','J'};
int[] Weight = {10,30,25,60,20,70,10,80,20,30};
int sum = 355;
for(int a=0;i<5;i++){
    int rand = (int)(Math.random()*sum);
    int s=0;//temp cumulative sum
    int i=0;
    while( (s+=Weight[i])<rand)i++;
    result.add(Select[i]);

    sum-=Weight[i];//total weight is lower now
    Weight[i]=0;//if weight is 0 it will never be selected

}

edit: исправлено, поэтому я не вычитаю 0 из sum

1 голос
/ 26 августа 2011

Полагаю, каждый раз, когда вы удаляете дубликаты, вы также должны обновлять свой массив weightSum.

0 голосов
/ 26 августа 2011

Моя память статистики немного размыта, но я думаю, что вы хотите сделать, это удалить элемент из рассмотрения после того, как он был выбран. Другими словами, после выбора записи удалите эту запись из weightSum и вычтите ее Weight из всех последующих записей и диапазона случайного числа. Может быть проще управлять, если вы работаете с ArrayList s вместо примитивных массивов.

0 голосов
/ 26 августа 2011

Я не совсем понимаю вашу проблему, но ваш алгоритм звучит правильно: вы должны делать что-то вроде сохранения каждого сгенерированного значения в списке (на основе генератора случайных чисел), но сначала проверьте, существует ли это число всписок, прежде чем добавить его.Повторяйте, пока в списке не будет 5 цифр.

...