如何在给定边界内获得一个随机整数等于给定数量的给定机会?

时间:2011-08-10 18:40:39

标签: c# math random probability

我需要一个像

这样的功能

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和{{1} }%概率在给定范围内的所有其他结果中均匀分布。

我的解决方案是创建一个包含100个单元格的数组,用随机域兼容的非100-chance填充它 - 相等的数字,抛出xchance个数 - 相等的值并取一个随机单元格的值。但我相信,受过良好教育的开发人员可以提出更好的解决方案。你能吗?

4 个答案:

答案 0 :(得分:4)

您可以采取以下措施:

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作为随机数重复,但在实际使用中不是问题。

编辑:但是,如果你看一下Albin Sunnanbo的方法,他设法避免重复随机。如果第一个随机是x或更多(因此也排除x),只需避免最大值并递增就可以进行下一次调用。

答案 1 :(得分:3)

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;

可能会被某个错误偏移

答案 2 :(得分:1)

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;
    }   
}

答案 3 :(得分:0)

我认为这应该对你有用:

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);
}