Выбор между несколькими вариантами с определенной вероятностью - PullRequest
3 голосов
/ 12 июня 2010

У меня есть сценарий, в котором мне нужно показать пользователю другую страницу для того же 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 Ответ

6 голосов
/ 12 июня 2010

Создайте число 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[i] в два раза больше weight[j], то страница i получит вдвое больше обращений, чем страница j.Это хорошо, потому что вы можете произвольно увеличивать или уменьшать трафик страницы, ничего не пересчитывая.В качестве альтернативы, вы можете убедиться, что сумма всегда равна N, а жесткий код N в, а не суммировать все значения каждый раз.Я уверен, что вы могли бы провести гораздо больше оптимизаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...