2013-05-25 280 views
0

我有重物即:C++倒加权随机播放/随机

A->1 B->1 C->3 D->2 E->3

是有在C++中的高效算法根据它们的重量挑选随机元素的列表?

例如可能性元件A或B具有较低的权重被拾取率较高(30%)比算法选择的可能性元件CE(10%)或d(20%)

+1

http://stackoverflow.com/questions/6052603的答案应该解决这个问题。您可能需要通过将每个权重除以所有权重的总和来标准化权重。 –

+1

你并不需要正常化。只是使随机范围去[0,总重量],而不是[0,1) – Billiska

+0

谢谢!但是如果我理解正确,那么只有当权重是“正常”时,该算法才有效:如果权重很高,则选择一个可能性较高的元素。 – ElPatzo

回答

1

作为@杜克林说,我们需要更多的信息。就像你如何解读和使用选择机会一样。

至少在进化算法领域,健身缩放(或选择机会缩放)是一个相当大的话题。

假设你开始了与不良得分

B[i] = how badly you don't want to select the i-th item 

,目标是计算健身 /选择得分S[i]我以为你是在roulette wheel的方式来使用它。

正如你所说,一个明显的方法是使用乘法逆:

S[i] = 1/B[i] 

但是,有可能是与一个小问题。 当B[i]已具有较高价值时,具有较低值的B[i]中的相同变化量的影响比同等变化量的影响要大得多。

问问你自己:

Say 
B[1] = 1  ->  S[1] = 1 
B[2] = 2  ->  S[2] = 0.5 
So item 1 is twice times as likely to be selected compared to item 2 

But with the same amount of change 
B[3] = 1000 ->  S[3] = 0.001 
B[4] = 1001 ->  S[4] = 0.000999001 
Item 3 is only 1.001 times as likely to be selected compared to item 4 

我就扔一个可能的替代方案,这里现在。

S[i] = max(B) - B[i] + 1 

+ 1部分帮助所以没有项目有零机会被选中。

这结束了计算选择分数的部分。


接下来,让我们来清楚如何在轮盘时尚中使用选择分数。 假设我们决定使用加法逆方案。

B[1] = 1  ->  S[1] = 1001 
B[2] = 2  ->  S[2] = 1000 
B[3] = 1000 ->  S[3] = 2 
B[4] = 1001 ->  S[4] = 1 

然后想象得分中的每个点对应一张彩票。 让我们为该故障单分配一个正在运行的ID。

| Item | Score = #ticket | ticket ID |   win chance  | 
| 1 |  1001  | 0 to 1000 | 1001/2004 ~ 0.499500998 | 
| 2 |  1000  | 1001 to 2000 | 1000/2004 ~ 0.499001996 | 
| 3 |   2  | 2001 to 2002 |  2/2004 ~ 0.000998004 | 
| 4 |   1  | 2003 to 2003 |  1/2004 ~ 0.000499002 | 

总共有2004张门票。

要进行选择,请随机选择获奖票证ID,即随机范围为[0,2004]。 二进制搜索可用于快速查找哪个项目拥有获奖彩票,正如您已在this question中看到的那样。使用二分查找需要查找的是票号为1001,2001,2003边界,而不是分数本身。


为了便于比较,这里是选择机会的情况下,使用乘法逆方案。

| Item |     win chance   | 
| 1 |   1/1.501999001 ~ 0.665779404 | 
| 2 |   0.5/1.501999001 ~ 0.332889702 | 
| 3 |  0.001/1.501999001 ~ 0.000665779 | 
| 4 | 0.000999001/1.501999001 ~ 0.000665114 | 

你可以注意到,在反加方案,1个单位的不良的一贯对应于围绕0.0005在选择机会的差异。

鉴于在乘法逆方案中,1个单位的不良导致变化选择机会的差异。

+0

你好!谢谢您的回答!我认为这正是我所追求的。 继续你的例子,我们将有像 S [1] = 1001,S [2] = 1000,S [3] = 2,S [4] = 1 现在我们使用如下所示的算法:http现在我选择范围[0,max(B)= 1001)中的一个随机数。 B [2]被挑选的概率是不是比B [1]高得多? – ElPatzo

+0

对不起:B [3]被选中的可能性B [4]在这种情况下更高(upper_bound) – ElPatzo

+0

@ user1086229从您的评论中,我可以看出您误解/误用了选择分数。请允许我详细阐述编辑。 – Billiska