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.
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!
}
精彩评论