开发者

Non-uniform random number generator

I am not sure if any language(preferably C# .NET) supports non-uniform random number generator. Is there any? I w开发者_JAVA百科as wondering what could be the best design approach to implement our own non-uniform random number generator?

Thanks.


Well, it’s 2016, this question has no points, and already has an accepted answer. But since, it came up second when I googled “c# random non uniform”, I’ll go ahead and give my approach.

Before starting, you have to consider what kind of non-uniform distribution you want. In my case, I needed most numbers to be low, while a few should be high. For any distribution, we need only consider numbers between 0 and 1 (so properties outside that range are irrelevant). The result can be multiplied or otherwise manipulated to fit any desired range. In the end, (x-1)^4 worked for me. It has a value of 1 when x = 0, a value of 0 when x = 1, but is on average more likely to be low than high.

Non-uniform random number generator

In C#, the generator of the Random class only produces integers. So the first step is to convert it so that it instead produces a rational number between 0 and 1.

var rnd = new Random();
var x = (double)rnd.Next(0,10000) / 10000;

Then, simply plug the random number into the distribution you desired.

x = Math.Pow(x-1,4);

I created a list of randomly generated numbers with this method and got the following result (sorted and rounded):

0
0.0001
0.0109
0.0115
0.042
0.1615
0.3077
0.5713
0.7217
0.8087

As you can see, the distribution is not uniform: it has a bias toward 0, but can still take on exactly 0 or 1 as a value.

Because of the implications when searching for answers on SO, I’m answering the question as asked. But in @applefreak's comments to his own question, it seems that he may also/instead be looking for a truly, non-pseudo-random number generator. @JonHanna’s response that “that can’t quite be done” is then appropriate. Using a source external to the computer may eliminate the dependency on the time-clock, but it still won't be truly random. You could argue that nothing truly is, but that's a question of philosophy.


I was able to created semi non uniform distribution using uniform distribution for my requirements. Basically I generate the required M numbers from 1 to N range and then again just generate (N-M) numbers and throw them away. Like this way when I generate next set of numbers, I get almost equal probability for all numbers between 1 to N. It worked for me!

Example code in C#:

        int low=1, high=50;
        Random random = new Random();
        int total = 50;
        ArrayList set_nos = new ArrayList();

        while (--total > 0)
        {
            int set = 6;
            int loop = 0;
            while (--set > 0)
            {
                int temp = random.Next(low, high);
                loop++;
                if (set_nos.Contains(temp))
                    continue;

                set_nos.Add(temp);
            }

            for (int unused = 1; unused < high-loop; unused++)
                random.Next(low, high);

            //Use set_nos for your purpose!

        }
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜