给定一个类似[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]的数组,我想得到一个考虑位置的随机值。
我希望出现1的可能性远远大于10
有可能吗?

最佳答案

为了简单起见,让我们假设一个数组arr = [x, y, z],我们将从该数组中获取采样值。我们希望看到xyz的以下相对频率:

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按我们的预期工作。

10-07 17:49