给定一个类似[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
的数组,我想得到一个考虑位置的随机值。
我希望出现1
的可能性远远大于10
。
有可能吗?
最佳答案
为了简单起见,让我们假设一个数组arr = [x, y, z]
,我们将从该数组中获取采样值。我们希望看到x
、y
和z
的以下相对频率:
frequencies = [5, 2, 1]
预处理这些频率以计算后续骰子掷骰的边距:
thresholds = frequencies.clone
1.upto(frequencies.count - 1).each { |i| thresholds[i] += thresholds[i - 1] }
让我们总结一下。
max = frequencies.reduce :+
现在选择一个随机数
roll = 1 + rand max
index = thresholds.find_index { |x| roll <= x }
结果返回
arr[index]
。总结一下:def sample arr, frequencies
# assert arr.count == frequencies.count
thresholds = frequencies.clone
1.upto(frequencies.count - 1).each { |i| thresholds[i] += thresholds[i - 1] }
max = frequencies.reduce :+
roll = 1 + rand(max)
index = thresholds.find_index { |x| roll <= x }
arr[index]
end
让我们看看它是如何工作的。
data = 80_000.times.map { sample [:x, :y, :z], [5, 2, 1] }
data
的直方图显示sample
按我们的预期工作。