【发布时间】:2013-10-16 03:56:59
【问题描述】:
假设给你三个“选项”,A、B 和 C。
您的算法必须选择并返回一个随机的。为此,只需将它们放入数组{A,B,C} 并生成一个随机数(0、1 或 2),这将是要返回的数组中元素的索引。
现在,这个算法有一个变种:假设A 有 40% 的机会被选中,B 有 20%,C 有 40%。如果是这种情况,您可以采用类似的方法:生成一个数组 {A,A,B,C,C} 并使用一个随机数 (0, 1, 2, 3, 4) 来选择要返回的元素。
这行得通。但是,我觉得它非常低效。想象一下将这个算法用于大量数量的选项。您将创建一个有点大的数组,可能有 100 个元素,每个元素代表 1%。现在,这仍然不是很大,但是假设您的算法每秒使用多次,这可能会很麻烦。
我考虑过创建一个名为Slot 的类,它有两个属性:.value 和.size。为每个选项创建一个槽,其中.value 属性是选项的值,.size 等于数组中此类选项的出现次数。然后生成一个从 0 到总出现次数的随机数,并检查该数字落在哪个槽上。
我更关心算法,但这是我的 Ruby 尝试:
class Slot
attr_accessor :value
attr_accessor :size
def initialize(value,size)
@value = value
@size = size
end
end
def picker(options)
slots = []
totalSize = 0
options.each do |value,size|
slots << Slot.new(value,size)
totalSize += size
end
pick = rand(totalSize)
currentStack = 0
slots.each do |slot|
if (pick <= currentStack + slot.size)
return slot.value
else
currentStack += slot.size
end
end
return nil
end
50.times do
print picker({"A" => 40, "B" => 20, "C" => 40})
end
哪些输出:
CCCCACCCCAAACABAAACACACCCAABACABABACBAAACACCBACAAB
是否有更有效的方法来实现一种选择随机选项的算法,其中每个选项被选择的概率不同?
【问题讨论】:
-
我最近讨论了如何从离散分布here 中生成随机变量。这很容易,我认为你在正确的轨道上。你说你主要关心的是效率。如果你的随机数是整数,我建议你构造一个哈希,比如
h[rand(..)] => 'A', 'B' or 'C',这取决于随机数的值。 -
Weighted random numbers 的可能副本。这本质上是“加权随机数,但在 Ruby 中”。不确定这是否算作不重复..