Давайте подумаем о том, как идея вашего массива изменяет вероятности. Обычно каждый элемент от 1 до n имеет вероятность 1 / n и, таким образом, одинаково вероятен.
Поскольку у вас есть n записей для 1, n-1 записей для 2 ... 1 записи для n, то общее количество записей, которые у вас есть, представляет собой арифметический ряд. Сумма арифметического ряда от 1 до n равна n (1 + n) / 2. Итак, теперь мы знаем, что вероятность каждого элемента должна использовать это как знаменатель.
Элемент 1 имеет n записей, поэтому его вероятность равна n / n (1 + n) / 2. Элемент 2 равен n-1 / n (1 + n) / 2 ... n равен 1 / n (1 + n) / 2. Это дает общую формулу числителя в виде n + 1 -i, где i - номер, который вы проверяете. Это означает, что теперь у нас есть функция для вероятности любого элемента как n-i + 1 / n (1 + n) / 2. все вероятности находятся в диапазоне от 0 до 1, а по определению сумма равна 1, и это является ключом к следующему шагу.
Как мы можем использовать эту функцию, чтобы искажать число раз, когда элемент появляется? Это проще с непрерывным распределением (т.е. удваивается вместо целых), но мы можем это сделать. Сначала давайте создадим массив наших вероятностей, назовем его c, составим их текущую сумму (cumsum) и сохраним обратно в c. Если это не имеет смысла, это просто цикл вроде
for(j=0; j < n-1; j++)
if(j) c[j]+=c[j-1]
Теперь, когда у нас есть это кумулятивное распределение, сгенерируйте число i от 0 до 1 (двойное число, а не целое число. Мы можем проверить, находится ли i между 0 и c [0], вернуть 1. если i находится между c [ 1] и c [2] возвращают 2 ... вплоть до отрицательного
<pre>
for(j=0; j < n=1;j++)
if(i %lt;= c[j]) return i+1
Это распределит целые числа в соответствии с вычисленными вами вероятностями.