Как получить случайное целое число в заданных границах, равное заданному числу с данным шансом? - PullRequest
2 голосов
/ 10 августа 2011

Мне нужна функция типа


int f(int min, int max, int x, int chance)
// where accepted chance values are 0 to 100 and x values are min to max

, чтобы вернуть случайное целое число, равное или большее min, меньшее или равное max с chance% вероятностью того, что результат равен x и 100-chance% вероятности равномерно распределены среди всех других результатов в данном диапазоне.

Мое решение состоит в том, чтобы создать массив из 100 ячеек, заполнить его случайными, не совместимыми с доменом, не x -равными числами, вбросить chance количество x -эквивалентных значений и принять значение случайной ячейки.Но я считаю, что должно быть гораздо лучшее решение, которое может предложить более образованный разработчик.Вы можете?

Ответы [ 4 ]

4 голосов
/ 10 августа 2011

Один из способов справиться с этим - сделать:

Random random = new Random();

int f(int min, int max, int x, int chance)
{
    if (random.Next(100) < chance) 
    {
        return x;
    } else { 
        int result = random.Next(min, max + 1);
        while (result == x) {
            result = random.Next(min, max + 1);
        }

        return result;
    }
}

Немного недетерминировано, поскольку теоретически вы можете застрять, повторяя x как ваше случайное число, но на практике это не проблема.

РЕДАКТИРОВАТЬ: Однако, если вы посмотрите на подход Альбина Суннанбо, ему удастся избежать повторных случайных. Следующие вызовы просто избегая максимального значения и увеличивая его, если первое случайное число равно x или более (таким образом, также исключая x).

3 голосов
/ 10 августа 2011
Random r = new Random();
if (r.Next(100) >= chance)
    return x;
var tmp = r.Next(min, max); // take one less than max to "exclude" x
if (tmp >= x)               // shift up one step if larger than or equal to the exceluded value
    return tmp + 1;
return tmp;

Может быть где-то смещением на одну ошибку

1 голос
/ 10 августа 2011
static Random r = new Random();

int f(int min, int max, int x, int chance)
{
    if (r.Next(100) < chance) return x;
    else 
    {
        int a;
        do { a = r.Next(min, max + 1); } while (a == x);
        return a;
    }   
}
0 голосов
/ 10 августа 2011

Я думаю, это должно сработать для вас:

public int f(int min, int max, int x, int chance)
{
    if (x < min || x > max)
    {
        throw new ArgumentException("x must be inbetween min and max");
    }

    var random = new Random();

    //generate a random number between 1 and 100, if it is less than the value of
    //chance then we will return x
    if (random.Next(1, 100) <= chance)
    {
        return x;
    }

    return random.Next(min, max);
}
...