-2

If I use python random's randint function, I seem to be getting a uniform distribution as below.

How do I make this a non-uniform randint?

EDIT: I have realised that what I am asking for is not possible. I either have a fixed bias, or my function ends up in a uniform distribution. Thank you for your time.

I do not care about specifying a specific range like this: Generate random numbers with a given (numerical) distribution (numpy.random.choice/ random.choice), the answer can have any distribution over the range.

Thank you for your time.

Eg:

#Counter({2: 10760, 6: 190364, 4: 40092, 0: 160068, 7: 99936, 3: 99885, 8: 99845, 9: 99725, 5: 99675, 1: 99650})

Current Example Code:

from collections import Counter
from random import randint
list_size=1000000
random_list=list(sorted([randint(0,9) for x in range(list_size)]))
Counter(random_list)
#Counter({2: 100760, 6: 100364, 4: 100092, 0: 100068, 7: 99936, 3: 99885, 8: 99845, 9: 99725, 5: 99675, 1: 99650})

Things I have tried:

def really_random(start,stop):
    random_array_size=random.randint(3,10)
    random_array_choice=random.randint(0,random_array_size-1)
    random_value=[random.randint(start,stop) for x in range(random_array_size)][random_array_choice]
    return random_value

def really_random_test(start,stop):
    list_size = 100000
    random_list = list(sorted([really_random(start, stop) for x in range(list_size)]))
    print(Counter(random_list))

still pretty uniform

#Counter({7: 10094, 9: 10066, 3: 10044, 1: 10027, 5: 10012, 8: 10012, 0: 10009, 6: 9985, 2: 9878, 4: 9873})
azazelspeaks
  • 5,727
  • 2
  • 22
  • 39
  • 1
    "How do I make this a non-uniform randint, or is this as random as it gets?" - wait, what? Are you under the impression that a non-uniform distribution would be somehow *more random*? What's your underlying reason for wanting a non-uniform distribution? – user2357112 Aug 26 '20 at 04:22
  • It's seems pretty predictable that out of x entries, each entry occurs nearly 1/x times. I would like the chance of each to be further away from 1/x – azazelspeaks Aug 26 '20 at 04:25
  • That comment is unrelated to this issue. I have removed it from the question. – azazelspeaks Aug 26 '20 at 04:27
  • 2
    "It's seems pretty predictable that out of x entries, each entry occurs nearly 1/x times." - That sounds like you just need to get a better understanding of the statistics involved. Otherwise, if you get what you're asking for, you'll probably end up coming back in a few weeks saying "My random numbers have a huge bias towards [whatever]! That doesn't seem very random. How do I get rid of that?" – user2357112 Aug 26 '20 at 04:33
  • you were right. I am in a rabbit hole of trying to figure out why and how to rebias it. Can you suggest some resources to get out of it? – azazelspeaks Aug 26 '20 at 05:20
  • I was trying to multiply functions by functions, in the end, either I got a uniform distribution because the functions cancelled each other out, or I got a fixed bias somewhere. I guess what I'm asking for is a random bias, but that in itself is not random. – azazelspeaks Aug 26 '20 at 05:23

3 Answers3

2

You seem to be under the impression that if the distribution of the random numbers is uniform, that makes them "not random". This isn't true - the real requirement for the randomness of a generated number is that you can't predict it. Note this helpful sentence from the Wikipedia article on randomness:

Individual random events are by definition unpredictable, but since they often follow a probability distribution, the frequency of different outcomes over numerous events (or "trials") is predictable.

Knowing that "out of x entries, each entry occurs nearly 1/x times" does not help you predict what the next random number will be. Imagine rolling a fair die many, many times. The more times you roll it, the more uniform the distribution of results will look. But this doesn't mean the die is somehow less random.

Python's random number generator could have used any distribution, and still have been just as "random". But usually, for programming purposes, it's very helpful to know that each result is equally likely (i.e. that you're rolling a fair die and not a weighted one). So what I'm trying to say is - the randint function is almost definitely the right tool for your purposes.

Blue Star
  • 1,932
  • 1
  • 10
  • 11
  • I am not concerned about the randomness, I merely want a non-uniform distribution. – azazelspeaks Aug 26 '20 at 04:40
  • You yourself linked to a question which discusses how to achieve that. Perhaps your issue is that you don't know what distribution you want? What are the requirements that make it need to be non-uniform? – Blue Star Aug 26 '20 at 04:43
  • I will do more research I guess. I have voted to close the question. – azazelspeaks Aug 26 '20 at 04:45
  • If you're not concerned about randomness, what type of distribution do you want? Many of ditributions have already implemented in most of computer softwares. – Dimitri Sifoua Aug 26 '20 at 05:00
1

If you generate uniform random numbers and then, say, square them, the results will be random yet not uniform. So, what is it you want?

Igor Rivin
  • 4,632
  • 2
  • 23
  • 35
  • I have tried this out, and it seems to skew all the numbers towards 0. Instead of a flat distribution that random.randint gives me, this gives a reducing exponential curve. I'm starting to think that what I need is something like a varying amplitude and phase sine wave as the distribution somehow. – azazelspeaks Aug 26 '20 at 04:40
  • @azazelspeaks: A non-uniform distribution will necessarily be biased towards some result. If you don't want such a bias, you don't want a non-uniform distribution. – user2357112 Aug 26 '20 at 04:44
  • I dont want it biased to 0, I want the bias to be random. – azazelspeaks Aug 26 '20 at 04:45
  • I have voted to close the question, what I'm effectively looking for is some sort of function that contains multiple gaussian distributions. Think sine wave. – azazelspeaks Aug 26 '20 at 04:51
-1

I suppose, you want to generate numbers that are really random (actually pseudo-random). If so, to my knowledge there is three types of generators to do that:

  • Algorithmic generators (Stochastic simulation - Monte Carlo).
  • Algorithmic generators + physical mechanisms (lotteries, casino machines, etc.).
  • Non-linear algorithmic generators with random parameters (cryptology).

I have already implemented algorithmic generators (the easiest to implemented) with linear congruence (More on this link) in a system simulation project.

class PseudoRandomNumberGenerator:
    """Pseudo random number generator with linear congruence"""
    
    def __init__(self, seed: int, multiplier: int, shift: int, modulus: int):
        self.seed = seed
        self.multiplier = multiplier
        self.shift = shift
        self.modulus = modulus
        
    def next(self, a: int, b: int):
        """Get the next random number within range [a, b["""
        self.seed = (self.multiplier * self.seed + self.shift) % self.modulus
        
        # Make projection of generated number on the interval [a, b[
        slope = (b - a) / (self.modulus - 1)
        
        return int(self.seed * slope + a)

The choice of the seed, multiplier, shift and modulus have to be well since these parameters determine the size of one cycle. The longer the cycle, the more robust the generator.

You can try these parameters: seed=53123027, multiplier=1664525, shift=1013904223, modulus=2**32. Or you can simply search in the litterature.

Dimitri Sifoua
  • 490
  • 5
  • 17
  • 2
    This doesn't offer any advantages over Python's built-in random number generation facilities - it's slower, and has far worse statistical properties. It also demonstrates misunderstandings of random number generation. For example, the classification of random number generators doesn't make sense, and the period is one of the **least** important properties of a random number generator - past a fairly low threshold, longer periods are utterly irrelevant. (The example parameters give a low enough period to actually cause problems, though.) – user2357112 Aug 26 '20 at 05:09
  • 1
    There's also stuff like the unnecessarily circuitous computation of `intercept`, which could just be replaced with `a`. – user2357112 Aug 26 '20 at 05:19
  • Why do you my classification doesn't make sense? With the generator that I've implemented, the period is not the least important properties. – Dimitri Sifoua Aug 26 '20 at 05:36