如何在给定的边界内以给定的机会获得等于给定数字的随机整数?

发布于 2024-11-29 02:05:37 字数 485 浏览 0 评论 0原文

我需要一个函数,例如


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

我的解决方案是创建一个包含 100 个单元格的数组,用符合域的随机非 x 等于数字填充它,并添加 chance 数量的 x< /code>-等于值并取随机单元格的值。但我相信受过良好教育的开发人员可以提出更好的解决方案。你可以吗?

I need a function like


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

to return a random integer equal or greater than min, smaller or equal to max with chance% probability of the result to equal x and 100-chance% probability spread uniformly among all other results in the given range.

My solution is to create an array of 100 cells, fill it with random domain-compliant non-x-equal numbers, throw-in chance number of x-equal values and take a value of a random cell. But I believe there is to be a much better solution a better educated developer can suggest. Can you?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南城追梦 2024-12-06 02:05:37

处理此问题的一种方法是:

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 的方法,他会设法避免重复 random.Next 调用,只需避免最大值并在第一个随机数为 x 或更大时递增(因此也排除 x)。

One way you could handle this is to do:

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

Slightly nondeterministic in that you could theoretically get stuck repeating x as your random number, but in practical usage not a problem.

EDIT: If you look at Albin Sunnanbo's approach, however, he manages to avoid repeated random.Next invocations simply by avoiding the maximum value and incrementing if the first random is x or more (thus also excluding x).

单调的奢华 2024-12-06 02:05:37
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;

可能是某个地方的一个错误所抵消

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;

Might be an offset by one error somewhere

流殇 2024-12-06 02:05:37
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;
    }   
}
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;
    }   
}
緦唸λ蓇 2024-12-06 02:05:37

我认为这应该对你有用:

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

I think this should work good for you:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文