I want to generate random natural number without any upper bound.
For example I can generate random natural number using random.randint(1, 1000)
but I don't want to specify the upper bound. How can I achieve that?
CodePudding user response:
it is not possible to choose a number from 0 to infinity. However, you can use sys.maxsize
for upper bound which is the maximum number supported. Do not forget to import sys module.
import sys
CodePudding user response:
If we note p(n) the probability of drawing the number n, even if p(n) may not drop to zero, the p(n) serie must still be convergent, with a sum equal to 1. So p(n) must decrease fast enough.
A possibility is to take an exponential distribution. The parameter of the distribution determines the finite average value of the random number.
Naïvely, the distribution returns a floating-point number, so we have to use the int()
conversion function.
Like this, aiming at an average value of 20:
$ python3
Python 3.10.6 (main, Aug 2 2022, 00:00:00) [GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux
...
>>>
>>> import numpy as np
>>>
>>> ys = list(map(int, np.random.exponential(20, 10)))
>>>
>>> ys
[7, 5, 36, 4, 10, 3, 26, 45, 9, 17]
>>>
>>> ys2 = list(map(int, np.random.exponential(20, 100)))
>>>
>>> sum(ys2) / len(ys2)
18.89
>>>
>>> ys4 = list(map(int, np.random.exponential(20, 10000)))
>>>
>>> sum(ys4) / len(ys4)
19.5025
>>>
>>> min(ys4)
0
>>> max(ys4)
207
>>>
>>> quit()
$
CodePudding user response:
The main problem here isn't even the maximum integer the computer can keep (including temporarily while generating such large random numbers). Let's assume PO agrees to sacrifice precision when getting very large numbers and agrees to keep them as float
.
The fundamental problem here is actually the distribution of this natural number. random.randint(1, 1000)
returns a random integer from the uniform distribution. This distribution can't exist without the upper bound, because then the Probability Mass Function (pmf) will return only zeroes. The pmf integral from -∞ to ∞ must equal 1, which is impossible with the uniform distribution without the upper bound, because it doesn't converge on the right.
However, there are other discrete distributions of natural numbers, which although not limited on the right side have a progressively lower probability the larger the integer is. But the packages that generate them in Python usually work with numpy
data types (very limited, like C and unlike regular Python and Wolfram, by the size of the integer), so in Python there is an inherent bound anyway.
from scipy.stats import nbinom
print(nbinom.rvs(1e10, 0.5, size=1) 1)
One could try to write a numerical algorithm in regular Python to generate let's say this negative binomial 1 random variable from the random number generated by the continuous uniform distribution from 0.0 to 1.0, each time calculating the integral of the former's pmf in regular Python (and reversing it into the quantile function), but it will be grossly inefficient.