随机选择,按等级加权

时间:2011-05-03 15:49:19

标签: algorithm random

假设我有 n 对象的集合,并且每个对象都有与之关联的排名,这些排名对应于整数值1到 n

现在假设我想从集合中随机选择一个对象。但我不想随便从1到 n 中选择一个数字;相反,我想这样做,以便我更有可能在列表中选择一个更高的数字(排名接近1)。

建议的解决方案:而不是从1选择 n ,而是选择1到 m ,其中 m 是一些显着大于 n 的数字;然后使用一些映射函数 f :[1, m ]→[1, n ]将更多数字映射到更高的排名而不是排名较低。例如, f (1), f (2), f (3)可能都返回1,而 f (m)是映射到 n 的唯一一个,因此获得1的可能性是 n 的三倍。希望这是有道理的。

所以我的问题是:如果这看起来像一个合理的算法,那么实现这个的合理函数 f 是什么, m / n 的比例足够大整数舍入不会阻止数字永远不会被选中?

[在我的特定场景中, n 可能相当大(成千上万),因此像here这样的解决方案对于这种情况并不是很实用。此外,选择是“替换”;即我选择一个物体然后返回;我不在乎下次我是否立即再次选择它。]

5 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

double bias = 1.5; 
int index = (int)(n * (bias - sqrt(bias*bias -4.0*(bias-1.0)* random()))
                  / 2.0 / (bias-1));

通过更改偏见参数,您可以控制您对排名较高的个人的偏好程度。

编辑:这是一些python代码。

def pick(n, bias):
    return int(n * (bias - sqrt(bias*bias -4.0*(bias-1.0)*random())) / 2.0 / (bias-1))

vals = [0]*10
for i in xrange(1000):
    vals[pick(10,1.5)] += 1
print vals
[153, 151, 115, 116, 97, 96, 87, 69, 66, 50]

答案 1 :(得分:1)

我尝试使用普通的随机方法(random.uniform(0, 1)),但是将概率平方。

由于P{x}的范围为0 -> 1,因此P {x ^ 2} also ranges from 0 - > 1`。

但是重量是不均匀的,因为小数字的平方仍然很小,而且数字的平方变小。

只是一个想法。

答案 2 :(得分:1)

从区间1..n(K> 1)生成K个随机数并选择最小值!

这具有您想要的属性,请查看http://www.sjsu.edu/faculty/watkins/samplemin.htm

上的分发演示

要使用小数值K(1

int m = random_int(1..n)
if (random_double(0..1) <= K - 1):
     m = min(m, random_int(1..n))

因此,当K从上方接近1时,分布变得越来越平坦。

答案 3 :(得分:0)

按等级标准化,然后构建二叉树。选择一个随机双精度并找到相应的值。

答案 4 :(得分:0)

我认为你真正想要的是功能 f :[1, n ]→ N (自然数0,1,2) ,...)。这将为每个等级分配权重。那么你想用概率 f (* k *)/(Σ f (* i *))选择等级 k ,换句话说,等级的权重超过所有等级的权重之和。要做到这一点,你可以在区间[1,Σ f (* i *)]中随机均匀地选择一个整数,并根据你的位置找出你所处的等级;如果你在1 ... f (1),选择1,如果你在 f (1)+1 ... f (1)+ f (2),选择2,依此类推。

f 的一个可能选择是将小排名高于大排名 f (* i *)= n - + 1.还有许多其他可能的选择。