Флаг Соединенных Штатов Америки содержит в своем кантоне 50 звезд, представляющих 50 штатов.
В прошлом, когда было меньше штатов, было, конечно, меньше звезд, и они были расположены по-разному. Например, в 1912-1959 гг. (После поступления в Нью-Мексико и Аризону, но до Аляски) было 48 звезд в прямоугольном расположении 6 × 8.
Флаг с 37 звездами, использовавшийся в 1867-1877 годах (после поступления в Небраску, но до Колорадо), имел асимметричный рисунок звезды.
На случай, если в будущем будет добавлен 51-й штат , Армейский институт геральдики уже разработал предварительный проект нового флага.
Но нет общего алгоритма расположения звезд, поэтому давайте создадим его!
Соревнование
Напишите программу, которая при заданном количестве звезд, размещаемом в кантоне (синяя часть) флага США, выдает оптимальные координаты, в которых эти звезды должны быть размещены. Система координат определяется кантоном [а не флагом в целом] с 0≤x≤W и 0≤y≤H.
Для этой задачи «оптимальное» расположение определяется как то, которое минимизирует среднее (евклидово) расстояние между точкой в кантоне и центром ближайшей звезды.
Простой (если возможно неоптимальный) алгоритм для аппроксимации этого значения:
def mean_distance_to_nearest_star(stars, width, height, point_density=100):
"""
Approximate the mean distance between a point in the rectangle
0 < x < width and 0 < y < height, and the nearest point in stars.
stars -- list of (x, y) points
width, height -- dimensions of the canton
"""
total = 0.0
nx = round(width * point_density)
ny = round(height * point_density)
for ix in range(nx):
x = (ix + 0.5) * width / nx
for iy in range(ny):
y = (iy + 0.5) * width / ny
min_dist = float('inf')
for sx, sy in stars:
min_dist = min(min_dist, math.hypot(x - sx, y - sy))
total += min_dist
return total / (nx * ny)
Ваша программа должна принимать три аргумента командной строки (не считая самого имени программы):
- Количество звезд в кантоне.
- Ширина кантона. (Должен принимать значения с плавающей запятой.)
- Высота кантона. (Должен принимать значения с плавающей запятой.)
(Если предпочитаемый вами язык программирования не поддерживает аргументы командной строки, сделайте что-нибудь разумное и запишите это в своем ответе.)
Вывод должен состоять из значений X и Y, разделенных запятыми, по одному в строке. (Порядок точек не имеет значения.)
Например:
~$ flagstar 5 1.4 1.0
0.20,0.20
0.20,0.80
0.70,0.50
1.20,0.20
1.20,0.80
Дополнительные правила и примечания
- Я имею право закрыть лазейки в правилах в любое время.
Крайний срок для ответов - пятница, 4 июля, в 24:00 CDT (UTC-05: 00).Из-за отсутствия ответов срок был продлен. TBA.- Включите в свой ответ:
- Код вашей программы
- Объяснение того, как это работает
- Вывод с аргументами командной строки
50 1.4 1.0
- Ваша программа должна работать в течение разумного промежутка времени: максимум 5 минут на обычном ПК. Я не буду слишком строг к этому, но дисквалифицирую вашу программу, если это займет несколько часов .
- Ваша программа должна быть детерминированной, т. Е. Всегда давать одинаковые выходные данные для одних и тех же аргументов. Таким образом, не зависит от
time()
илиrand()
. Методы Монте-Карло в порядке, если вы используете свой собственный PRNG. - Только центральные точки звезд имеют значение. Не беспокойтесь о попытках избежать дублирования или чего-либо подобного.
счет
- Минимизируйте среднее расстояние от точки в кантоне до ближайшей звезды. (См. Выше.)
- Вы можете быть оценены на основе любых исторических флагов США, от 13 до 50 звезд. Точный алгоритм взвешивания баллов в единый рейтинг будет опубликован позже.
- В случае ничьей победитель будет выбран по количеству чистых голосов.
- Я, вероятно, опубликую свою собственную программу, но исключу себя из числа участников, имеющих право на получение галочки.
источник
Ответы:
Javascript - двигать звезды в направлении наиболее изолированной точки
(с анимацией процесса)
Подход очень прост:
Этот процесс повторяется большое количество раз, постепенно уменьшая количество, на которое перемещаются звезды. Это уменьшает максимальное расстояние от точки до ближайшей звезды, косвенно уменьшая среднее расстояние от точки до ближайшей звезды.
Как того требует вопрос, здесь не используется встроенная случайная функция, вместо этого используется xorshift .
Большая часть кода охватывает настройку и анимацию - часть, которая применяет алгоритм, является функцией
adjustStars
.Код
Вы можете наблюдать за процессом в фрагменте стека ниже.
Выход за 50 звезд
(ширина = 1,4, высота = 1,0)
Среднее расстояние оценивается в 0,0655106697162357.
Координаты:
источник
Вот простой пример. Он всегда размещает звезды в прямоугольную сетку и оптимизирует ее, выбирая факторизацию, при которой ячейки сетки находятся как можно ближе к квадрату. Это прекрасно работает, когда число звезд имеет делитель, близкий к его квадратному корню, и пессимически, когда число звезд простое.
Выход за 50 звезд
(ширина = 1,4, высота = 1,0)
Прямоугольник 10 × 5.
источник
Javascript - случайное перемещение звезды, если среднее расстояние уменьшено
(с анимацией процесса)
Это не дает такой оживленной анимации, как мой первый ответ, с длительными периодами без движения, поскольку потенциальные перестановки проверяются и отклоняются. Однако конечный результат имеет меньшее среднее расстояние, поэтому этот метод является улучшением.
Подход по-прежнему очень прост:
Этот процесс повторяется большое количество раз, постепенно уменьшая количество, на которое перемещаются звезды. Случайный выбор расстояния для перемещения смещен в сторону меньших расстояний, поэтому прогресс в небольших изменениях перемежается со случайным большим прыжком. Каждый шаг занимает больше времени, чем в моем первом ответе, так как измерение среднего расстояния является медленным процессом, требующим выборки всего кантона.
Как того требует вопрос, здесь не используется встроенная случайная функция, вместо этого используется xorshift .
Большая часть кода охватывает настройку и анимацию - часть, которая применяет алгоритм, является функцией
adjustStars
.Код
Вы можете наблюдать за процессом в фрагменте стека ниже.
Выход за 50 звезд
(ширина = 1,4, высота = 1,0)
Среднее расстояние оценивается в 0,06402754713808706.
Координаты:
источник