2015-06-01 2 views
5

Мне интересно, как я мог генерировать случайные числа, которые появляются в круговом распределении.Как создать случайные точки в круговом распределении

Я способен генерировать случайные точки в прямоугольном распределении, что точки генерируются внутри квадрата (0 < = х < 1000, 0 < = у < 1000):

Как бы я пойти на для создания точек в пределах окружности таким образом, чтобы:

(x-500)^2 + (y-500)^2 < 250000?

+2

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

+0

http://mathworld.wolfram.com/DiskPointPicking.html – Veedrac

+2

Прочтите [это] (http://stats.stackexchange.com/questions/120527/how-to-generate-random-points-uniformly-distributed-in- круг). – vsoftco

ответ

5

ПЕРВЫЙ ОТВЕТ: Простым решением было бы сделать проверку, чтобы убедиться, что результат удовлетворяет вашему уравнению перед продолжением.

Сформировать х, у (есть способы Рандомайза в отборную диапазоне)

Проверьте, ((х-500)^2 + (у-500)^2 < 250000) истинно , если нет, регенерировать.

Единственным недостатком будет неэффективность.

ВТОРОЙ ОТВЕТ:

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

+3

Первый ответ имеет двойное достоинство простого и правильного обеспечения равномерного распределения значений (x, y). Неэффективность относительно невелика, потому что будет отброшена только часть 1- (0,25 * PI) пар. – Simon

+1

Вполне вероятно, что это будет * быстрее *, чем делать это «правильно», если использовать быстрый генератор случайных чисел, поскольку он избегает тригонометрии, корней, больших чисел и использует только один вызов «случайный» в среднем. – Veedrac

4
import random 
import math 

# radius of the circle 
circle_r = 10 
# center of the circle (x, y) 
circle_x = 5 
circle_y = 7 

# random angle 
alpha = 2 * math.pi * random.random() 
# random radius 
r = circle_r * random.random() 
# calculating coordinates 
x = r * math.cos(alpha) + circle_x 
y = r * math.sin(alpha) + circle_y 

print("Random point", (x, y)) 

В вашем примере circle_x 500, как circle_y есть. circle_r 500.

Другой вариант расчета радиуса, чтобы получить равномерно распределенных точек, на основе this answer

u = random.random() + random.random() 
r = circle_r * (2 - u if u > 1 else u) 
+5

Я не знаю, нуждается ли OP, но это будет * не * равномерным распределением. – andars

+2

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

+0

Это прекрасная возможность связать одну из самых больших проблем теории вероятностей: парадокс Бертранда (https://en.wikipedia.org/wiki/Bertrand_paradox_ (вероятность)). – naught101

0

Я хотел бы использовать полярные координаты:

r_squared, theta = [random.randint(0,250000), 2*math.pi*random.random()]

Тогда г всегда меньше или равны радиусу, а theta всегда между 0 и 2 * pi радианами.

Поскольку г не в начале координат, вы всегда будете конвертировать его в вектор с центром в 500, 500, если я правильно понимаю

x = 500 + math.sqrt(r_squared)*math.cos(theta) y = 500 + math.sqrt(r_squared)*math.sin(theta)

Выберите r_squared случайным образом из this

+3

Распределение (x, y), созданное этим подходом, не будет равномерным. – Simon

+0

'x = 500 + r * math.cos (theta)' 'y = 500 + r * math.sin (theta)' Да? – fiacre

+0

@simon, я вижу проблему: Изменить код выше: 'r_sqared, theta = [random.randint (0,250000), 2 * math.pi * random.random()]' Затем примените преобразование 'x = 500 + math.sqrt (r_squared) * math.cos (theta)' 'y = 500 + math.sqrt (r_squared) * math.sin (theta)' – fiacre

4

Что вам необходимо отбирать образец (полярная форма):

r, theta = [math.sqrt(random.randint(0,500))*math.sqrt(500), 2*math.pi*random.random()] 

Затем вы можете преобразоватьи theta обратно в декартовых координатах x и y через

x = 500 + r * math.cos(theta) 
y = 500 + r * math.sin(theta) 

Related (хотя и не Python), но дает представление.

+0

Как отмечалось в других ответах, t приводит к равномерному распределению точек. – naught101

+0

@ naught101 Нет, он генерирует равномерно распределенные точки на диске, обратите внимание, что я генерирую форму квадратного корня радиуса, а не самого радиуса (что действительно не приведет к равномерному распределению по диску) , – vsoftco

+0

А, правда, я понимаю, что вы делаете. Я думаю, что было бы лучше, если бы вы просто взяли выборку из единичного круга, а затем умножили и добавили впоследствии, а не выборку из круга r = 500. – naught101

0

Вы можете использовать rejection sampling, создать случайную точку в пределах квадрата (2r)×(2r), который охватывает круг, повторяя, пока не получите одну точку в круге.

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