我有一个场景,我需要根据概率分布向用户显示相同网址的不同页面,
所以例如3页的分布可能是
page 1 - 30% of all users
page 2 - 50% of all users
page 3 - 20% of all users
在决定为给定用户加载哪个页面时,我可以使用哪种技术来确保整体分布与上述内容相匹配?
我想我需要一种从集合X {x1,x2 ...... xn}中“随机”选择一个对象的方法,除了不是所有对象同样可能定义对象被选中的概率预先。
感谢大家的投入,在做了一些原型设计之后,这就是我最终使用
private static int RandomIndexWithPercentage(Random random, int[] percentages) {
if (random == null) {
throw new ArgumentNullException("random");
}
if (percentages == null || percentages.Length == 0) {
throw new ArgumentException("percentages cannot be null or empty", "percentages");
}
if(percentages.Sum() != 100) {
throw new ArgumentException("percentages should sum upto 100");
}
if (percentages.Any(n => n < 0)) {
throw new ArgumentException("percentages should be non-negative");
}
var randomNumber = random.Next(100);
var sum = 0;
for (int i = 0; i < percentages.Length; ++i) {
sum += percentages[i];
if (sum > randomNumber) {
return i;
}
}
//This should not be reached, because randomNumber < 100 and sum will hit 100 eventually
throw new Exception("Unexpected");
}
答案 0 :(得分:6)
生成数字0-9。如果数字小于3,请给第一页。如果小于8,请给第2页,或者给第3页。
一些代码,为了帮助您入门:
private int ChoosePage()
{
int[] weights = new int[] { 3, 5, 2 };
int sum = 0;
int i;
for (i = 0; i < weights.Length; i++)
sum += weights[i];
int selection = (new Random()).Next(sum);
int count = 0;
for (i = 0; i < weights.Length - 1; i++)
{
count += weights[i];
if (selection < count)
return i;
}
return weights.Length - 1;
}
请注意,权重不必特别加起来。如果sum
= 100,则weight[i]
获得网页i
的概率为百分之百。但是,如果不是,那只是相对的 - 如果weight[i]
是weight[j]
的两倍,则页面i
将获得两倍于页面j
的点击次数。这很好,因为您可以在不重新计算任何内容的情况下随意增加或减少页面流量。或者,您可以确保总和始终为N
,并且硬编码N
,而不是每次都汇总所有值。你可以做很多优化,我敢肯定。