Случайные вхождения - PullRequest
       11

Случайные вхождения

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

Я не совсем уверен, как это сделать.

Мне нужно сгенерировать 14 296 случайных чисел с различными уровнями вероятности.

, поэтому, например, мне нужен массив, содержащий числа 18, 1 и 17. Каждое число имеет различный процент вероятности возникновения.Итак:

55% = 18
(7 862,8 раза)

30% = 1
(4 288,8 раза)

15% = 17
(2144,4 раза)

результат будет примерно таким же, как new Array () {18, 18, 1, 17, 1, 18 ...}

Ответы [ 5 ]

4 голосов
/ 10 августа 2011

Если у вас всегда будут значения в виде целочисленных процентов, я бы заполнил массив из 100 элементов значениями в соответствии с вероятностью, поэтому в этом случае в вашем массиве будет 55 вхождений из 18, 30 вхождений из 1 и15 вхождений из 17. Тогда вам просто нужно выбрать 14 296 случайных значений из этого массива.(т.е. выберите целое число в диапазоне [0, 100) и возьмите этот элемент.)

Для разных способов выражения вероятностей, конечно, существуют разные подходы.Но если вам дают целочисленные проценты, это легко понимаемый вариант.(Другой способ - масштабировать все вероятности по сумме, т.е. в диапазон [0, 1), а затем взять случайный дубль в этом диапазоне.)

2 голосов
/ 10 августа 2011

Разделите диапазон генератора случайных чисел на пропорциональные сегменты и, исходя из того, в какой сегмент попало следующее случайное число, выберите соответствующее число из вашего набора.

Что-то вроде (упрощенно):

const int numbers[3] = { 1, 17, 18 };
const int borders[2] = { 0.30*MAX_RANDOM, (0.30 + 0.15) *  MAX_RANDOM };

int i = random.next(), num;

if      (i < borders[0]) num = number[0];
else if (i < borders[0]) num = number[1];
else num = number[2];

Конечно, если чисел больше трех, лучше использовать цикл.

Примечание: в отличие от решения Джона Скита, оно может обеспечить любую желаемую степень детализации до 1 / (MAX_RANDOM + 1) (что часто составляет до 2 ^ 32 на 32-битных машинах), а не строго 1%.

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

Как на счет этого (не проверено):

struct np
{
    int n;
    int p;
}

Создайте List<np> и добавьте его в пары значение / процент (например, n = 18, p = 55).

Затем просто сделайте следующее, чтобы выбрать номер:

List<np> npl = new List<np>();
// (fill the list here)



int r = rnd.next(total_of_all_p_values); // get random number
int res = 0; // result
for(int i = 0; i < npl.Length(); r -= npl[i++].n)
{
    if(r < npl[i].p) // remaining vlaue is smaller than current percentage
    {
        res = npl[i].n;
        break;
    }
}
1 голос
/ 10 августа 2011
Random r = new Random();

// for each number to generate
int nextNumber;
double probability = r.NextDouble();
if (probability < 55.0 / 100.0)
    nextNumber = 18;
else if (probability < (55.0 + 30.0) / 100.0)
    nextNumber = 1;
else
    nextNumber = 17;
0 голосов
/ 10 августа 2011

Вы можете заполнить List<T> соответствующим номером каждого из 3 чисел, а затем рандомизировать список .

...