Учитывая список точек, найдите кратчайший путь, который посещает все точки и возвращает к начальной точке.
Задача коммивояжера хорошо известна в области компьютерных наук, как и многие способы ее расчета / аппроксимации. Это было решено для очень больших групп точек, но для некоторых из самых больших требуется много лет процессора.
Не обжечься картошкой.
Hot Potato - игра, в которой 2+ игрока раздают «картошку» по кругу, пока играет музыка. Цель состоит в том, чтобы быстро передать его следующему игроку. Если вы держите картошку, когда музыка останавливается, вы ушли.
Объектом продаж горячего картофеля является:
Учитывая набор из 100 уникальных точек , верните эти точки в лучшем порядке ( более короткое общее расстояние, как определено ниже ). Это «передаст» проблему следующему игроку. Они должны улучшить его и передать следующему, и т. Д. Если игрок не может улучшить его, он уходит и игра продолжается до тех пор, пока не останется один игрок.
Чтобы это не было соревнованием "грубой силы-меня-пути", существуют следующие условия:
Вы не можете занять больше одной минуты, чтобы передать картофель. Если к моменту истечения одной минуты вы не нашли и не приняли более короткое решение, значит, вы вышли.
Вы не можете изменить положение более 25 очков. Точнее,
>= 75
очки должны быть в том же положении, в котором вы их получили. Неважно, какие из них вы решите изменить, а только сумму, которую вы меняете.
Когда остается только один игрок, он становится победителем этой игры и получает одно очко. Турнир состоит из 5*n
игр, где n
указано количество игроков. Каждую игру начальный игрок будет вращать , а оставшийся игрок будет перетасовываться . Игрок с наибольшим количеством очков в конце является победителем турнира. Если турнир заканчивается ничьей за первое место, новый турнир будет сыгран только с этими участниками. Это будет продолжаться, пока не будет галстука.
Начинающий игрок в каждой игре получит набор случайно выбранных очков в произвольном порядке.
Точки определяются как пара целочисленных x,y
координат на декартовой сетке. Расстояние измеряется с помощью Manhattan расстояние , |x1-x2| + |y1-y2|
. Все координаты будут лежать в [0..199]
диапазоне.
вход
Ввод дается с одним строковым аргументом. Он будет состоять из 201 целых чисел, разделенных запятыми, представляющих количество текущих игроков ( m
), и 100 очков:
m,x0,y0,x1,y1,x2,y2,...,x99,y99
Порядок этих точек является текущим путем. Общее расстояние получается путем сложения расстояния от каждой точки до следующей ( dist(0,1) + dist(1,2) + ... + dist(99,0)
). Не забудьте вернуться к началу при расчете общего расстояния!
Обратите внимание, что m
это не количество игроков, которые начали игру, а число, которое все еще в игре.
Выход
Вывод дается так же, как ввод, минус m
; единственная строка, содержащая целые числа через запятую, представляющие точки в их новом порядке.
x0,y0,x1,y1,x2,y2,...,x99,y99
Управляющая программа будет ожидать выхода только в течение одной минуты. Когда получен вывод, он проверит, что:
- выход хорошо сформирован
- вывод состоит из только и все эти 100 точек представить на входе
>=75
точки находятся в исходном положении- длина пути меньше, чем предыдущий путь
Если какая-либо из этих проверок не удалась (или нет выходных данных), вы вышли, и игра перейдет к следующему игроку.
Программа управления
Вы можете найти управляющую программу по этой ссылке . Сама управляющая программа является детерминированной и размещена с фиктивным семенем 1
. Семя, используемое во время подсчета очков, будет другим, поэтому не пытайтесь анализировать списки очередей / точек поворота, которые оно выплевывает.
Основной класс есть Tourney
. Выполнение этого сделает полный турнир с участниками, приведенными в качестве аргументов. Он выплевывает победителя каждой игры и подсчет в конце. Пример турнира с двумя SwapBots выглядит так:
Starting tournament with seed 1
(0) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 3
(0) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 4
(1) SwapBot wins a game! Current score: 5
(1) SwapBot wins a game! Current score: 6
(1) SwapBot wins a game! Current score: 7
(1) SwapBot wins a game! Current score: 8
Final Results:
Wins Contestant
2 (0) SwapBot
8 (1) SwapBot
Если вы хотите протестировать только одну игру за раз, вы можете Game
вместо этого запустить класс. Это запустит одну игру с игроками в порядке, указанном в качестве аргументов. По умолчанию, он также будет печатать игру за игрой, показывая текущий игрок и длину пути.
Также включены несколько тестов игроков: SwapBot
, BlockPermuter
и TwoSwapBot
. Первые два не будут включены в оценки, поэтому не стесняйтесь использовать и злоупотреблять ими во время тестирования. TwoSwapBot
будет включен в судейство, и он не сутулятся, так что возьмите свою A-игру.
альманах
Вы не можете сохранить информацию о состоянии, и каждый ход - это отдельный прогон вашей программы. Единственная информация, которую вы будете получать каждый ход - это набор очков.
Вы не можете использовать внешние ресурсы. Это включает в себя сетевые вызовы и доступ к файлам.
Вы не можете использовать библиотечные функции, предназначенные для решения / помощи с проблемой TSP или ее вариантами.
Вы не можете манипулировать другими игроками или мешать им.
Вы не можете манипулировать или вмешиваться в управляющую программу или любые включенные классы или файлы каким-либо образом.
Многопоточность разрешена.
Одно представление на пользователя. Если вы отправите более одной заявки, я введу только первую отправленную. Если вы хотите изменить свое представление, отредактируйте / удалите оригинал.
Турнир будет проходить на Ubuntu 13.04, на компьютере с процессором i7-3770K и 16 ГБ оперативной памяти. Он не будет работать в ВМ. Все, что я считаю злонамеренным, немедленно дисквалифицирует вашу текущую и будущую заявку.
Все записи должны запускаться из командной строки с бесплатным ( как в пиве ) программным обеспечением. Если у меня возникнут проблемы с компиляцией / запуском вашей записи, я буду просить помощи в комментариях. Если вы не ответите или я не смогу его запустить, он будет дисквалифицирован.
Результаты (22 мая 2014 г.)
Новые результаты в! UntangleBot довольно разумно обошел конкурентов. TwoSwapBot одержал семь побед, и SANNbot также одержал победу. Вот табло и ссылка на необработанный вывод :
Wins Contestant
22 (2) ./UntangleBot
7 (0) TwoSwapBot
1 (5) SANNbot.R
0 (1) BozoBot
0 (3) Threader
0 (4) DivideAndConquer
Как она стоит прямо сейчас , UntangleBot выиграл галочка. Не позволяйте этому отговорить вас от участия, так как я буду проводить турнир по мере появления большего количества участников и соответственно изменяю принятый ответ.
источник
Ответы:
UntangleBot (ранее NiceBot)
Бот C ++ 11, использующий две стратегии.
Сначала он попытается «распутать» путь, если это возможно, путем обнаружения пересечений между путями, которые ближе, чем 25 точек (поскольку распутывание подразумевает изменение всех промежуточных точек).
Если первая стратегия терпит неудачу, она случайным образом меняет точки, чтобы найти лучшие расстояния, пока не будет найден лучший путь.
Этот бот неизменно побеждает TwoSwapBot с приблизительным соотношением пяти побед за один проигрыш в моих тестовых турнирах.
источник
SANNbot
(имитируемый бот отжига в R )
Должен быть вызван с
Rscript SANNbot.R
.Идея относительно проста: каждый ход представляет собой один «этап охлаждения» имитируемого отжига с количеством игроков, все еще находящихся в игре, в виде «температуры» (изменяемой текущим расстоянием более 12000, то есть приблизительно начальным расстоянием). Единственная разница с надлежащим моделируемым отжигом состоит в том, что я проверил, что я не переставляю более 25 элементов, и если я использовал 20 ходов, но результирующая последовательность стоит, чем начальная, то она начинается снова.
источник
java Tourney "java Swapbot" "Rscript SANNbot.R"
и она, кажется, работает.u
границы проверки, этого не произойдет (и это работает намного лучше). Хотя ваш код кажется довольно простым, я не знаю причуд R, поэтому не могу сказать, ошибочна ли логика. (последняя версия контроллера выдаст сообщения о том, почему бот выходит из строя при запускеGame
, так что это может помочь определить проблему)BozoBot
Использует сложную логику, стоящую за Bozosort, чтобы найти лучший путь. Похоже на это.
BozoBot теперь улучшен благодаря многопоточности ! Четыре миньона теперь бесцельно жонглируют точками, пока не наткнулись на улучшение. Первый, кто найдет решение, получит печенье!Видимо я терплю неудачу в многопоточности.
источник
new Thread(new Minion()).start()
TwoSwapBot
Повышение до
SwapBot
, этот парень проверяет каждую пару свопов. Во-первых, он проверяет, сократит ли какой-либо отдельный своп путь. Если это так, он возвращается немедленно. Если нет, он проверяет каждый, чтобы увидеть, если другой , сократит своп. Если нет, он просто умирает.Хотя путь все еще полуслучайный, он обычно возвращается примерно через 100 мс. Если он должен проверять каждый 2-местный обмен (примерно 25М), это займет около 20 секунд.
На момент подачи заявки это превзошло всех других участников в тестовых раундах.
источник
винторезный станок
Этот бот
410 штук2510 балловИдея состоит в том, чтобы найти лучшее улучшение пути, чтобы другие боты потерпели неудачу со своей логикой.
источник
println
на,print
чтобы избавиться от новой строки в конце вашего вывода. Иначе это вылетает.println
наprint
и сделал нить подсчета динамики. Теперь он начинается с 10 потоков ...Разделяй и властвуй + Жадный бот
ПРИМЕЧАНИЕ. Я посмотрел на ваш код, для
Game
которого в Game.parsePath указано следующее:Однако
catch(NumberFormatException)
блока нет , поэтому ваша программа, скорее всего, вылетит, когда программа проигрывателя выведет строку (как показано в конце метода моей программыmain
). Я советую вам это исправить, потому что программы могут выводить исключения, трассировки стека или тому подобное. В противном случае закомментируйте эту строку в моей программе, прежде чем запускать ее.Вернуться к теме
Эта реализация (в Java) разбивает список точек на 25 частей, случайно расположенных в списке. Затем он создает потоки, чтобы сократить путь между точками в каждом фрагменте (следовательно, «Разделяй и властвуй»). Основной поток отслеживает другие и обеспечивает представление кратчайшего решения в установленные сроки. Если поток умирает с решением или без него, он снова запускает другой поток на другом чанке.
Каждый поток использует «жадный» алгоритм, который начинается в произвольной точке, переходит к ближайшей точке и повторяется до тех пор, пока не будут охвачены все точки (следовательно, «жадные»).
Заметки
Просто скомпилируйте и используйте
java DivideAndConquer.class
для запуска.источник
<200
токены, прежде чем попытаться выполнить синтаксический анализ. Все равно лучше проверить это в любом случае.)
строку 19; изменить ,substr
чтобыsubstring
на 38; инициализироватьidx
что-то вrun()
методе.