Существует хэш с идентификаторами и весами этих идентификаторов.Случайно перетасовывайте взвешенный массив
y = { 1 => 0.7, 2 => 0.2, 3 => 0.1 }
Я хотел бы перетасовать этот хеш в соответствии с весами.
Я пробовал несколько разных способов, все из которых дают мне похожие неожиданные результаты. Вот наиболее краткий я нашел.
y.sort_by {|v| -v[1]*rand()}
Когда я запускаю это в десять тысяч раз и выбрать первые идентификаторы, я получаю следующие счетчики:
{1=>8444, 2=>1316, 3=>240}
Я ожидал, что эти счетчики с учетом веса выше (например, 1
=>7000
). Мне немного туманно, почему эта перетасовка не соответствует этим весам. Может кто-то очистить мою путаницу и рассказать, как это исправить?
Вот некоторые из полезных источников я нашел:
- Random item by weight
- Weighted Shuffle of an Array or Arrays?
- How to implement a Weighted shuffle
- One-line ruby weighted shuffle
Примером того, почему t его работа не работает. Предположим, что мы имеем хэш '{1 => 0,7, 2 => 0,3}'. Когда мы выбираем случайный вес для 1, он будет больше 0,3 точно 4/7 времени и, следовательно, определенно больше, чем число, которое мы выбираем для 2. Другие 3/7 времени, это будет случайным образом между 0.0 и 0.3 и вероятность 1/2 быть больше, чем число, которое мы выбираем для 2. Таким образом, он упорядочивается первым «4/7 + (3/7) * (1/2) == 78,6%» времени , когда он должен быть заказан в первую очередь в 70% случаев. – JKillian
Что вам нужно сделать, так это построить (кумулятивную) функцию распределения, затем, разрешив 'rn = rand' (число между' 0.0' и '1.0'), выберите' 1', если 'rn <0.7',' 2 if 0,7 <= rn <0,9' и '3', если rn <= 0,9'. –