【问题标题】:C++ Inverted Weighted Shuffle/RandomC++ 倒置加权随机/随机
【发布时间】:2013-05-25 12:18:53
【问题描述】:

我有一个加权对象列表,即:

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

C++ 中有没有一种有效的算法来根据权重选择随机元素?

例如,选择权重较低的元素 A 或 B 的可能性(30%)高于算法选择元素 C E(10%)或 D(20%)的可能性

【问题讨论】:

  • stackoverflow.com/questions/6052603 的答案应该可以解决这个问题。您可能需要通过将每个权重除以所有权重的总和来标准化权重。
  • 你真的不需要标准化。只需使随机范围变为 [0,total weight) 而不是 [0,1)
  • 谢谢!但如果我理解正确,这个算法只有在权重“正常”时才有效:如果权重很高,则选择一个可能性更高的元素。
  • 如果权重为 1,1,100,7,100,概率是否相同? (这意味着实际值没有任何作用,只有顺序。)无论如何,我认为我们需要更多细节来准确地确定您希望分布的概率。
  • 如果我简单地反转值,我认为它应该适用于这种方法:A->1/1 B->1/1 C->1/3 D->1/2 E-> 1/3 .. @Dukeling no:如果权重为 1,1,100,7,100,概率也会改变

标签: c++ algorithm random selection weighted


【解决方案1】:

正如@Dukeling 所说,我们需要更多信息。就像您如何解释和使用选择机会一样。

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

假设你从 badness 分数开始

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

目标是计算 fitness/selection 分数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 部分有帮助,因此没有项目被选中的机会为零。

计算选择分数的部分到此结束。


接下来,让我们弄清楚如何在轮盘赌中使用选择分数。 假设我们决定使用 additive inverse 方案。

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 中已经看到的,二分搜索 可用于快速查找哪个项目拥有中奖彩票。二分查找需要查找的是票证ID的boundary1001,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 个单位的不良率会导致选择机会的变化差异。

【讨论】:

  • 您好!谢谢您的回答!我认为这正是我所追求的。继续您的示例,我们将有如下值 S[1] = 1001, S[2] = 1000, S[3] = 2, S[4] = 1 现在我们使用如下所示的算法:stackoverflow.com/questions/6052603 和现在我在 [0,max(B)=1001) 范围内选择一个随机数。 B[2]被选中的概率不是比B[1]高很多吗?
  • 抱歉:B[3] 被选中的可能性在这种情况下 B[4] 更高(upper_bound)
  • @user1086229 从您的评论中,我可以看出您误解/误用了选择分数。请允许我在编辑中详细说明。
猜你喜欢
  • 2018-03-15
  • 1970-01-01
  • 2010-12-18
  • 2015-07-05
  • 2010-09-08
  • 2014-07-21
  • 1970-01-01
相关资源
最近更新 更多