2016-05-03 3 views
0

Я пытаюсь создать цикл в Python с numpy, который даст мне переменную «times» с 5 номерами, генерируемыми случайным образом между 0 и 20. Однако я хочу, чтобы было одно условие: ни одно из различий между двумя соседними элементами в этом списке меньше 1. Каков наилучший способ достичь этого? Я попытался использовать последние две строки кода, но это, скорее всего, неверно.Ограничение генерации случайных чисел в Python

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

ответ

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 

Он использует тот же метод проб и ошибок, как и предыдущий ответ, так что в зависимости от параметров времени, чтобы найти решение может быть большим.

+0

Нулевой перевод другого ответа - это определенный плюс –

+0

Спасибо, Ханнес, он отлично работает, и цифры отлично смотрятся! Я сделал x глобальным внутри функции и напечатал x снаружи, после передачи аргументов. – Spica

+0

Нет, пожалуйста, не делайте этого, если вам действительно не нужно.Скорее всего, вы этого не сделаете :) Вместо этого назовите его как 'times = uniform_min_range (0, 20, 5, 1.0)', а затем 'print times'. –

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] 

Если нет целесообразного решения это будет висеть в бесконечном цикле (так что вы можете захотеть добавьте параметр безопасности, который контролирует количество испытаний).

+0

Возможно, существует проблема с ограничениями http://imgur.com/j4iPNph Вероятно, это связано с тем, что для (-1, 0) и (20, 21) не могут отсутствовать промахи. Практически может быть неважно, но я хотел добавить в качестве примечания. – ayhan

+0

Спасибо, Джон! К сожалению, поскольку я новичок в Python, я все еще пытаюсь обвести голову вокруг вашего решения. Я копирую код в свой редактор. Я решил, что я должен определить переменные n, a, b, minDist между импортом и def. Но я не цифры. Я получаю только «** Время загрузки: 0.00 секунд» – Spica

+1

@ayhan. Номера сами по себе не являются однородными. Ограничения заставляют числа смещаться в сторону конечных точек. Единообразие, о котором я говорил, состоит в том, что вектор выбирается равномерно из всех таких векторов. –

Смежные вопросы