Этот вопрос закрыт для ответов, так как повторяет вопрос Как выбрать случайный элемент из списка с учётом его веса?
Gremlin92
@Gremlin92
Целеустремленный

Генерировать числа с заданной вероятностью?

Допустим есть вектор с целыми числами от 0 до 6 включая. У меня есть гуй где напротив каждого числа от 0 до 6 включая стоит число от 0.00 до 1 (вероятности) причем в сумме эти 7 чисел дают 1цу. Как сделать генератор чтобы выдавал числа от 0 до 6 включая с этими заданными вероятностями и как бы еще сделать чтобы гуй при изменении чисел вероятностей в ячейках как-то нормировал сумму всех вероятностей в 1цу?
  • Вопрос задан
  • 195 просмотров
Ответы на вопрос 5
Griboks
@Griboks
В каждом языке программирования присутствует специальная функция для генерирования случайных чисел от 0 до 1. Соответственно, вы представляете ваши числа в виде интервалов, а случайное число в виде относительной координаты. В какой интервал укажет координата, то число и является искомым.

Пример
Дана таблица:
1 - 0.9
2 - 0.8
3 - 0.7

Тогда интервалы будут следующие: 0-0.9, 0.9-1.7, 1.7-2.4.
Допустим, сгенерировано случайно число 0.65 - примем его за относительные координаты.
Переводим координаты в абсолютные 0.65*2.4=1.56. Следовательно, случайно число попадает в интервал 0.9-1.7, значит искомое число - 2.
Ответ написан
Maksim_64
@Maksim_64
Data Analyst
приведу пример кода на python с использованием библиотеки numpy
import numpy as np
sample_space = [0,1,2,3,4,5,6]
probabilities = [0.3,0.2,0.05,0.05,0.1,0.15,0.15]
n = 20
result = np.random.choice(sample_space,size=n,p=probabilities)
print(result)

sample_space - лист откуда будет производится выборка
probabilities - лист соответствующих вероятностей (0 с вероятностью 0.3, 1 с вероятностью 0.2, и.т.д) вероятности я взял свои, вы поставите свои главное чтобы вероятности в сумме были 1.
n - количество сгенерированных чисел для примера я взял 20, вы зададите сколько ва нужно.
функция choice также имеет параметр replace по умолчанию установленный в True он регулирует может ли ранее выбранный элемент, быть выбранном снова, в нашем случае могут ли быть повторения при выборке из sample_space (по умолчанию может).
Насчет нормирования вероятностей, такое возможно только если n=2, или если есть дополнительная информация позволяющая создать систему уравнений. В вашем случае это невозможно например
возьмем нашу дистрибуцию мы имеем 0 с вероятностью 0.3, мы меняем ее 0.2, у нас будет существовать бесконечное количество сценариев как мы можем раскидать 0.1 на остальные 6 элементов. Уникального решения не существует.
Ответ написан
@alexalexes
Как сделать логику гуя:
Выставляете все интервалы поровну 1 / n или рандомно-нормированно.
При движении ползунка n он "отбирает" значение приращения у ползунка n+1.
Ползунок n+1 ограничивает движение ползунка n.
Последний ползунок влияет на значение первого.
Ответ написан
Можно разрешить вводить любые неотрицательные веса в GUI.
Например, [ 1, 1, 1, 100000000, 100, 10, 1 ]

Сложить все веса: это длина отрезка, на котором равновероятно выбрать любую точку.
И посмотреть, на «чей» отрезок она попала.

Например, для всего 3 вариантов ввели значение 1, 2, 5. В сумме 8.
Получаем равновероятно случайное число от 0 до 8 [включая 0, исключая 8):
-++=====
01234567

Например, выпало 4.321, попадает на отрезок принадлежащий варианту «3»
(который с «вероятностью» весом 5 )
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Алгоритм простой, подготовка O(n), расчёт O(log n). Вычислить функцию распределения (она кусочно-постоянная). Сгенерировать равномерно распределённое число, определить, в какой кусок оно попадает.
Для целых «шансов» — если сумма этих «шансов» 123, то генерируем число от 0 до 122, а дальше понятно.

Алгоритм многопамятный, подготовка O(sum ai), расчёт O(1). Годится только для небольших целых шансов.
Его предложил Сергей Соколов.

Алгоритм палочный, подготовка O(n log n), расчёт O(1).
https://elementy.ru/problems/2263/Razdelyay_i_uravnivay
Алгоритм легко переделывается на ситуацию, когда все палки имеют целую длину, резать-клеить их можно только по целым длинам, при этом последняя палка может оказаться короче. В общем, простым делением определяем, в какую палку попали, а потом доступом к массиву и сравнением — в какой компонент данной палки.

Например, у нас есть четыре шанса — 100, 20, 2 и 1. Палочный алгоритм даст, например, такие палки (у всех длина 31, и у последней — 30).
Палка [0..31): 1 (x<1); 100 (x>=1)
Палка [31..62): 2 (x<33); 100 (x>=33)
Палка [62..93): 20 (x<82); 100 (x>=82)
Палка [93..123): всегда 100
Разыграв 32, получаем: [32/31] = 1, первая палка. 32<33 — та шмотка, у которой два шанса.
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы