«У меня разные чашки кофе разных размеров. Чем они больше, тем больше я хочу взимать с них плату. У меня возникают проблемы с определением, как назначать цены».
Это не просто проблема программирования - вы указали, что вероятность увеличивается со значением, но вы не сказали, как увеличивается со значением. Как правило, в кофейнях плата не взимается прямо пропорционально количеству кофе. Вы не можете назначить вероятности пропорционально значению, потому что некоторые из ваших значений отрицательны, но вероятности не могут быть отрицательными.
Звучит так, как будто вам нужно еще немного прибить проблему, прежде чем вы сможете написать какой-либо код.
Если вам действительно все равно, как вероятность соотносится со значением, кроме того, что они увеличиваются в порядке значения, то одним простым способом будет:
- сортировка вашего массива
- присвойте вероятности 1 первому элементу, 2 второму и т. Д.
- Теперь ваши вероятности не составляют 1, что является проблемой. Поэтому разделите каждую вероятность на сумму всех назначенных вами вероятностей:
(1 + 2 + .. + n) = n(n+1)/2
. Это называется "нормализация".
Учитывая ваш список вероятностей, который в сумме составляет 1, самый простой способ повторно выбрать одну из них, как правило, рассчитать совокупные вероятности , которые я продемонстрирую на примере:
value (sorted): -12 -3 127 1000000
assigned probability: 0.1 0.2 0.3 0.4
cumulative probability: 0.1 0.3 0.6 1.0
Совокупная вероятность определяется как сумма всех вероятностей до этой точки.
Теперь, из вашего генератора случайных чисел вам нужно случайное (с плавающей запятой) значение в диапазоне от 0 до 1. Если оно лежит в диапазоне от 0 до 0,1, вы выбрали -12. Если он лежит между 0,1 и 0,3, вы выбрали -3 и так далее. Чтобы выяснить, в каком диапазоне он находится, вы можете линейно пройти по массиву или выполнить бинарный поиск.
Вы можете пропустить шаг нормализации и использование плавающей запятой, если хотите. Назначьте «кумулятивные вероятности» (1, 3, 6, 10 ...), но сделайте понятным, что фактическая вероятность - это сохраненное целочисленное значение, деленное на n (n + 1) / 2. Затем выберите случайное целое число от 0 до n (n + 1) / 2 - 1. Если оно меньше 1, вы выбрали первое значение, иначе, если меньше 3, второе и т. Д. Это может или не может сделать код более понятным, и ваш RNG может или не может делать выбор целочисленных значений из большого диапазона.
Обратите внимание, что вы могли назначить вероятности (0,001, 0,002, 0,003, 0,994) вместо (0,1, 0,2, 0,3, 0,4) и по-прежнему удовлетворять вашему требованию, что «чем выше значение, тем выше вероятность».