0

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?

Lopez
  • 461
  • 5
  • 19
  • 2
    so you might want a random number which is 20 billion digits long or something like that is that correct? – Crapicus Sep 12 '22 at 10:37
  • yes that is correct. – Lopez Sep 12 '22 at 10:39
  • but if you have no constraints then the program could run for the rest of your lifetime generating the random number is that what you're looking for? -- or you run out of memory cos the number is so humungous! – Crapicus Sep 12 '22 at 10:40
  • 1
    Most integers have a number of digits that is greater than the memory on your PC (or atoms in the universe, etc. -- infinity really is very big), so this seems rather silly... – thebjorn Sep 12 '22 at 10:42
  • No any natural number is acceptable but there shouldn't be a constraint on upper bound. – Lopez Sep 12 '22 at 10:42
  • There is automatically a constraint on the upper bound by the fact that your computer only has so much RAM – Crapicus Sep 12 '22 at 10:43
  • E.g., `29*2**1574753+1` is a "small" number in the context of all natural numbers (it's a prime with 474050 digits). Quick back-of-the-napkin calculation.. Addressable memory on a 64-bit architecture is less than `2**64`, so practically your limit is a number that is less than `10 ** 18446744073709551616` (i.e. `2**64` digits, skipping binary vs. base 10 etc.) This is still a small number compared to infinity. 128 GB of RAM is only `128 * 2 ** 30` (which is waaay smaller). – thebjorn Sep 12 '22 at 11:00
  • 1
    You can't have a "random" number without having a distribution. – President James K. Polk Sep 12 '22 at 11:27
  • This means that the probability of obtaining any integer should approach 0 infinitely. Do you want to always get infinity? – Mechanic Pig Sep 12 '22 at 11:30

3 Answers3

1

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.

Alex
  • 707
  • 1
  • 4
  • 9
0

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

Turan
  • 104
  • 9
  • 1
    Ints are no longer limited in Python 3 which is unbound. e.g. a = sys.maxsize + 10 print(a) you will see you can have bigger ints. – Crapicus Sep 12 '22 at 10:46
  • @Crapicus: sys.maxsize is not the size of the largest integer, it's the size of the largest index i.e. the pointer size, which places an upper bound on the size of the largest integer that python can support. – President James K. Polk Sep 12 '22 at 13:39
  • I never said it was. Ints in Python 3 can expand to the available memory was my point. – Crapicus Sep 12 '22 at 13:45
0

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()
$ 
jpmarinier
  • 4,427
  • 1
  • 10
  • 23