我正在尝试使用numpy在Python中创建一个循环,它将为我提供一个变量" times"在0到20之间随机生成5个数字。但是,我希望有一个条件:该列表中两个相邻元素之间的差异都不小于1.实现此目的的最佳方法是什么?我尝试了最后两行代码,但这很可能是错误的。
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
例如,对于一次迭代,这不会很好:
4.25230915 4.36463992 10.35915732 12.39446368 18.46893283
但是这样的事情会很完美:
1.47166904 6.85610453 10.81431629 12.10176092 15.53569052
答案 0 :(得分:3)
由于你正在使用numpy,你也可以使用内置函数来获得统一的随机数。
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
它使用与上一个答案相同的试错法,因此根据参数,查找解决方案的时间可能很长。
答案 1 :(得分:1)
使用命中和未命中方法来保证均匀分布。这是一个直接的Python实现,应该可以调整为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
例如,
>>> randSpacedPoints(5,0,20,1)
[0.6681336968970486, 6.882374558960349, 9.73325447748434, 11.774594560239493, 16.009157676493903]
如果没有可行的解决方案,这将在无限循环中挂起(因此您可能需要添加一个控制试验次数的安全参数)。