Учитывая, что n окружностей с радиусами r1 ... rn, расположите их так, чтобы никакие круги не перекрывались, а ограничивающая окружность имела «маленький» радиус.Позиция N окружностей разных радиусов внутри большего круга без перекрытия
Программа принимает список [r1, r2, ... rn] как входной сигнал и выводит центры окружностей.
- Я прошу «маленький», потому что «минимальный» радиус преобразует его в гораздо более сложной проблемой (минимальная версия уже оказалась NP трудно/полная - см сноску ближе к концу вопроса). Нам не нужен минимум. Если форма, сделанная кругами, кажется довольно круговой, это достаточно хорошо.
- Вы можете предположить, что Rmax/Rmin < 20, если это помогает.
- Низкий приоритет - программа должна иметь возможность обрабатывать более 2000 кругов. В начале, даже 100-200 кругов должно быть хорошо.
- Возможно, вы догадались, что круги не должны быть упакованы плотно или даже касаться друг друга.
Цель состоит в том, чтобы придумать визуально приятное расположение заданных кругов, которое может вписаться в большой круг и не оставлять слишком много пустого пространства. (например, круги в color blindness test picture).
Вы можете использовать код Python ниже в качестве отправной точки (вам нужно будет NumPy и Matplotlib для этого кода - "Суда APT-получить установку Numpy Matplotlib" на Linux) ...
import pylab
from matplotlib.patches import Circle
from random import gauss, randint
from colorsys import hsv_to_rgb
def plotCircles(circles):
# input is list of circles
# each circle is a tuple of the form (x, y, r)
ax = pylab.figure()
bx = pylab.gca()
rs = [x[2] for x in circles]
maxr = max(rs)
minr = min(rs)
hue = lambda inc: pow(float(inc - minr)/(1.02*(maxr - minr)), 3)
for circle in circles:
circ = Circle((circle[0], circle[1]), circle[2])
color = hsv_to_rgb(hue(circle[2]), 1, 1)
circ.set_color(color)
circ.set_edgecolor(color)
bx.add_patch(circ)
pylab.axis('scaled')
pylab.show()
def positionCircles(rn):
# You need rewrite this function
# As of now, this is a dummy function
# which positions the circles randomly
maxr = int(max(rn)/2)
numc = len(rn)
scale = int(pow(numc, 0.5))
maxr = scale*maxr
circles = [(randint(-maxr, maxr), randint(-maxr, maxr), r)
for r in rn]
return circles
if __name__ == '__main__':
minrad, maxrad = (3, 5)
numCircles = 400
rn = [((maxrad-minrad)*gauss(0,1) + minrad) for x in range(numCircles)]
circles = positionCircles(rn)
plotCircles(circles)
Дополнительная информация: Алгоритм упаковки окружности, обычно упоминаемый в результатах поиска Google, не применим к этой проблеме.
Заявление о проблеме другого «алгоритма упаковки окружности»: Таким образом, для комплекса K (графики в этом контексте называются симплициальными комплексами или сложными краткими) и соответствующими граничными условиями, вычисляют радиусы соответствующего круга упаковка для K ....
В основном он начинается с графика, указывающего, какие круги касаются друг друга (вершины графа обозначают круги, а ребра обозначают касание/касательную связь между кругами). Нужно найти радиусы и положения круга, чтобы удовлетворить трогательные отношения, обозначенные графиком.
Другая проблема действительно есть интересное наблюдение (независимо от этой проблемы):
круг упаковки Теорема - Каждый круг упаковки имеет соответствующий плоский граф (это легко/очевидная часть), и каждый плоский график имеет соответствующую упаковку круга (не столь очевидная часть). Графики и упаковки являются дуальными друг от друга и уникальны.
У нас нет планарного графика или тангенциального отношения, чтобы начать с нашей проблемы.
Эта статья - Роберт Дж Фаулер, Майк Патерсон, Стивен Л. Танимото: Оптимальная упаковка и Покрытие на плоскости является NP-Complete - доказывает, что минимальная версия этой проблемы является NP-полной. Однако документ недоступен в Интернете (по крайней мере, нелегко).
Не головоломка ... это проблема, с которой я боролся на работе.У меня есть базовое решение, но я ищу лучшего. – Rajan
Я снова просмотрел свою проблему после вашего комментария, но не смог увидеть часть головоломки. Пожалуйста, дайте мне знать, если проблема будет задана способом, который предполагает его несерьезный вопрос типа головоломки. я бы перефразировал его. Или, вы имеете в виду, что это слишком сложная проблема для переполнения стека? – Rajan
@ Грег: Я думаю, что это очень субъективно. То, что вы называете головоломкой, некоторые люди называют ее программированием, в то время как другие называют ее математической. Я прошел через такие аргументы по одному из моих вопросов. – Pupil