How to generate highly uniform random number in python?
Question
In somehow I need an random function that can generate highly uniform numbers, such as, when I say [5,5], and I run this function for 10 times, I would like to have 5 number that are less than 0.5 and other 5 numbers are greater than 0.5.
Every run should be separated, like:
for i in range(0,10):
rnd=random_function([6,3,1])
print rnd
After having run this function for ten times, then I have 6 numbers are less than 0.6, 3 numbers are between 0.6 and 0.9, and 1 number are between 0.9 to 1.
Does anyone know how can I do that? Because the random function inside python is not that uniform.... Thanks!!
Solution
What you are asking for is not random; indeed, it is fairly structured. The point of random data is that it isn't structured: you can't say anything about what the values will be, only what they will be on average.
You can still do what you want, though: just specify the ranges you want your numbers to fall into.
>>> def random_function(*args):
... n = sum(args)
... bottom = 0
... for m in args:
... for _ in range(m):
... yield random.uniform(bottom, bottom + m/n)
... bottom += m/n
...
>>> list(random_function(6,3,1))
[0.1849778317803791, 0.2779140519434712, 0.08380168147928498, 0.5477412922676888
, 0.5158697440011519, 0.5535466918038039, 0.8046993690361345, 0.714614514522802,
0.7102988180048052, 0.9608096335125095]
>>> list(random_function(6,3,1))
[0.29313403848522546, 0.5543469551407342, 0.14208842652528347, 0.344464024804118
7, 0.3168266508239002, 0.5956620829410604, 0.673021479097414, 0.7141779120687652
, 0.7783099010964684, 0.9103924993423906]
Explanation:
Given (6,3,1)
, work out their sum (10
). We want six numbers between 0 and 6/10, three numbers between 6/10 and 6/10 + 3/10, and one number between 6/10 + 3/10 and 6/10 + 3/10 + 1/10. We can generate these by calling
random.uniform(0, 6/10) six times,
random.uniform(6/10, 9/10) three times, and
random.uniform(9/10, 1) once.
OTHER TIPS
Isn't it the essense of random that it's not uniform? If you want to generate 6 random numbers and you want half of them to be under 0.5 and the other half to be over 0.5, you should generate 3 numbers between 0 and 0.5 and generate 3 between 0.5 and 1.
Well, that's kind of defeating the purpose of "random" numbers, but Python does support this.
As part of the random
module (import random
), you can use random.uniform(a,b)
instead of random.random()
where a
to b
is the range in floating point.
More info in Python's documentation.
It would help to know the context of your question, but it appears that what you may be looking for are low-discrepancy sequences rather than the usual pseudo-random numbers.
More specifically, check if Halton sequence gives you desired results. Python implementation is available.