0

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

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

A numpy translation of the other answer is a definite plus
Thank you Hannes, it works perfectly and the numbers look great! I made x a global inside the function and the printed x outside, after passing the arguments.
No, please don't do that unless you really need to. Which you most likely don't :) Instead call it as times = uniform_min_range(0, 20, 5, 1.0) and then print times.
Done! Thanks so much Hannes!
0

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).

8 Comments

There seems to be a problem with the limits imgur.com/j4iPNph It's probably because no misses can occur for (-1, 0) and (20, 21). Practically may not be important but I wanted to add as a note.
Thank you John! Unfortunately, since I am new to Python, I am still trying to wrap my head around your solution. I am copy pasting your code into my editor. I figured I should define the variables n, a, b, minDist in between the import and the def. But I don't the numbers. I get just a "** Load Time: 0.00 seconds"
@ayhan The numbers themselves are not uniform. The constraints force the numbers to be biased towards the end points. The uniformity I referred to is that the vector is chosen uniformly from among all such vectors.
@JohnColeman You are correct, I mixed up two different concepts.
@Spica. Glad you got it to work, though from a programming point of view, adding a print statement inside a function like that makes it less usable as a function. It is better design to have the calling code print the result.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.