代码之家  ›  专栏  ›  技术社区  ›  Sijin

在具有定义概率的多个选项之间进行选择

  •  3
  • Sijin  · 技术社区  · 15 年前

    我有一个场景,我需要根据概率分布为同一个URL向用户显示不同的页面,

    因此,例如,对于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");
    } 
    
    1 回复  |  直到 15 年前
        1
  •  6
  •   dlras2    15 年前

    生成一个0-9的数字。如果数字小于3,给他们第一页。如果少于8页,给他们第二页,否则给他们第三页。


    一些代码,让您开始:

    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[j] 然后页 点击量是页面的两倍 j . 这很好,因为您可以随意增加或减少页面流量,而无需重新计算任何内容。或者,您可以确保总金额 N 和硬编码 n 而不是每次求和所有值。我敢肯定,你还可以做更多的优化。

    推荐文章