2

我想为随机生成的数字分配权重,权重如下所示。

  0  |  1  |  2  |  3  |  4  |  5  |  6
─────────────────────────────────────────
  X  |  X  |  X  |  X  |  X  |  X  |  X
  X  |  X  |  X  |  X  |  X  |  X  |   
  X  |  X  |  X  |  X  |  X  |     |   
  X  |  X  |  X  |  X  |     |     |   
  X  |  X  |  X  |     |     |     |   
  X  |  X  |     |     |     |     |   
  X  |     |     |     |     |     |   

最有效的方法是什么?

4

3 回答 3

3

如果您的数组很小,只需在以下数组中选择一个统一的随机索引:

int a[] = {0,0,0,0,0,0,0, 1,1,1,1,1,1, 2,2,2,2,2, 3,3,3,3, 4,4,4, 5,5, 6};

如果要在运行时生成分布,请使用std::discrete_distribution.

于 2012-10-21T02:08:44.183 回答
3

@Kerrek 的回答很好。

但是如果权重的直方图不都是小整数,你需要更强大的东西:

将 [0..1] 划分为按权重大小调整的区间。在这里,您需要相对大小比率为 7:6:5:4:3:2:1 的段。所以一个区间单元的大小是1/(7+6+5+4+3+2+1)=1/28,区间的大小是7/28, 6/28, ... 1/ 28.

这些构成一个概率分布,因为它们总和为 1。

现在找到累积分布:

P        x
7/28  => 0
13/28 => 1
18/28 => 2
22/28 => 3
25/28 => 4
27/28 => 5
28/28 => 6

现在在 [0..1] 中生成一个随机数,并在此表中通过找到最小的这样来r查找它。这是您想要的随机值。xr <= P(x)

表查找可以通过二分查找来完成,当直方图有很多 bin 时,这是一个好主意。

请注意,您正在有效地构造逆累积密度函数,因此有时将其称为逆变换方法。

于 2012-10-21T02:45:07.147 回答
0

为了得到你想要的分布,首先你基本上把你在那里写的 X 的数量加起来。你可以这样做(我的 C 超级生锈,所以把它当作伪代码)

int num_cols = 7; // for your example
int max;
if (num_cols % 2 == 0) // even
{
    max = (num_cols+1) * (num_cols/2);
}
else // odd
{
    max = (num_cols+1) * (num_cols/2) + ((num_cols+1)/2);
}

然后你需要随机选择一个介于1max inclusive之间的整数。

因此,如果您的随机整数是r最后一步,就是找出哪一列包含第 r 个 X。这样的事情应该可以工作:

for(int i=0;i<num_cols;i++)
{
    r -= (num_cols-i);
    if (r < 1) return i;
}
于 2012-10-21T02:31:58.767 回答