我想为随机生成的数字指定权重,权重如下所示。
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 | | | | | |
最有效的方法是什么?
答案 0 :(得分: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
。
答案 1 :(得分: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
号码,并在此表格中查找最小x
以查找r <= P(x)
。这是您想要的随机值。
表查找可以使用二进制搜索完成,当直方图有很多区间时,这是一个好主意。
请注意,您正在有效地构建逆累积密度函数,因此有时将其称为inverse transforms的方法。
答案 2 :(得分: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);
}
然后您需要随机选择1
和max
包含之间的整数。
因此,如果你的随机整数是r
,那么最后一步就是找到哪个列包含第r个X.这样的东西应该有效:
for(int i=0;i<num_cols;i++)
{
r -= (num_cols-i);
if (r < 1) return i;
}