开发者

How to get a random integer in given boundaries equal to a given number with a given chance?

开发者 https://www.devze.com 2023-03-27 09:00 出处:网络
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

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 e开发者_C百科qual 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?


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).


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


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


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

精彩评论

暂无评论...
验证码 换一张
取 消