Spica
Spica

Reputation: 127

Constraining random number generation in Python

I am trying to create a loop in Python with numpy that will give me a variable "times" with 5 numbers generated randomly between 0 and 20. However, I want there to be one condition: that none of the differences between two adjacent elements in that list are less than 1. What is the best way to achieve this? I tried with the last two lines of code, but this is most likely wrong.

for j in range(1,6):

    times = np.random.rand(1, 5) * 20
    times.sort()
    print times

    da = np.diff(times) 

    if da.sum < 1: break

For instance, for one iteration, this would not be good:

4.25230915 4.36463992 10.35915732 12.39446368 18.46893283

But something like this would be perfect:

1.47166904 6.85610453 10.81431629 12.10176092 15.53569052

Upvotes: 0

Views: 565

Answers (2)

Hannes Ovr&#233;n
Hannes Ovr&#233;n

Reputation: 21831

Since you are using numpy, you might as well use the built-in functions for uniform random numbers.

def uniform_min_range(a, b, n, min_dist):
    while True:
        x = np.random.uniform(a, b, size=n)
        np.sort(x)
        if np.all(np.diff(x) >= min_dist):
            return x

It uses the same trial-and-error approach as the previous answer, so depending on the parameters the time to find a solution can be large.

Upvotes: 2

John Coleman
John Coleman

Reputation: 51998

Use a hit and miss approach to guarantee uniform distribution. Here is a straight-Python implementation which should be tweakable for numpy:

import random

def randSpacedPoints(n,a,b,minDist):
    #draws n random numbers in [a,b]
    # with property that their distance apart is >= minDist
    #uses a hit-miss approach

    while True:
        nums = [a + (b-a)*random.random() for i in range(n)]
        nums.sort()
        if all(nums[i] + minDist < nums[i+1] for i in range(n-1)):
            return nums

For example,

>>> randSpacedPoints(5,0,20,1)
[0.6681336968970486, 6.882374558960349, 9.73325447748434, 11.774594560239493, 16.009157676493903]

If there is no feasible solution this will hang in an infinite loop (so you might want to add a safety parameter which controls the number of trials).

Upvotes: 0

Related Questions