Задача состоит в том, чтобы написать решатель для классической игры в карандаш и бумагу Dots and Boxes . Ваш код должен принимать два целых числа m
и в n
качестве входных данных указывать размер доски.
Начиная с пустой сетки точек, игроки ходят по очереди, добавляя одну горизонтальную или вертикальную линию между двумя смежными соседними точками. Игрок, который заканчивает четвертую сторону поля 1 × 1, зарабатывает одно очко и получает другой ход. (Очки, как правило, записываются путем размещения в поле идентификационной метки игрока, такой как инициал). Игра заканчивается, когда больше не может быть линий. Победителем игры становится игрок с наибольшим количеством очков.
Можно предположить , что либо n = m
или , n = m - 1
и m
, по крайней мере 2.
Задача состоит в solve
том, чтобы максимально развернуть игру Dots and Boxes менее чем за минуту. Размер игры просто n*m
. Вывод вашего кода должен быть win
, draw
или lose
который должен быть результатом для первого игрока, при условии, что оба игрока играют оптимально.
Ваш код должен быть компилируемым / запускаемым в Ubuntu с использованием легко устанавливаемых и бесплатных инструментов. Пожалуйста, сообщайте о вашей оценке как о самой большой области, которую вы можете решить на своем компьютере за 1 минуту вместе со временем. Затем я проверю код на своем компьютере и составлю ранжированную таблицу записей.
В случае тай-брейка победителем будет самый быстрый код на доске самого большого размера, которую он сможет решить менее чем за минуту.
Было бы лучше, если бы выводимый код не просто выиграл или проиграл, но и действительный счет. Это делает для проверки вменяемости правильности.
Ответы:
C99 - доска 3х3 за 0,084 с
Изменить: я реорганизовал мой код и сделал более глубокий анализ результатов.
Дальнейшие правки: добавлена обрезка по симметрии. Это дает 4 конфигурации алгоритма: с симметрией или без X с или без альфа-бета-отсечения
Дальнейшие правки: добавлено запоминание с использованием хеш-таблицы, что в итоге привело к невозможному: решение доски 3х3!
Основные характеристики:
#define HASHTABLE_BITWIDTH
). Когда этот размер больше или равен количеству стен, это гарантирует отсутствие столкновений и O (1) обновлений. Меньшие хеш-таблицы будут иметь больше коллизий и будут немного медленнее.-DDEBUG
распечаткамиПотенциальные улучшения:
исправить небольшую утечку памяти,исправленную в первом редактированииальфа / бета-обрезкадобавлена во втором редактированииобрезать симметрии,добавленные в третьем редакторе (обратите внимание, что симметрии не обрабатываются с помощью памятки, поэтому это остается отдельной оптимизацией)памяткадобавлена в 4-й редакцииКод
Из-за отсутствия организации количество файлов выросло из-под контроля. Весь код был перемещен в этот репозиторий Github . В редакторе заметок я добавил make-файл и скрипт тестирования.
Результаты
Примечания о сложности
Подходы грубой силы к точкам и коробкам очень быстро взрываются .
Рассмотрим доску со
R
строками иC
столбцами. ЕстьR*C
квадраты,R*(C+1)
вертикальные стены иC*(R+1)
горизонтальные стены. Это всегоW = 2*R*C + R + C
.Поскольку Лембик попросил нас решить игру с минимаксом, нам нужно пройти к листьям дерева игры. Давайте пока проигнорируем обрезку, потому что важны порядки.
Есть
W
варианты для первого хода. Для каждого из них следующий игрок может сыграть на любой изW-1
оставшихся стен и т. Д. Это дает нам пространство для поискаSS = W * (W-1) * (W-2) * ... * 1
илиSS = W!
. Факториалы огромны, но это только начало.SS
количество листовых узлов в пространстве поиска. Более важным для нашего анализа является общее количество решений, которые необходимо было принять (т. Е. Количество ветвейB
в дереве). Первый слой веток имеетW
параметры. Для каждого из них есть следующий уровень иW-1
т. Д.Давайте посмотрим на некоторые небольшие размеры таблицы:
Эти цифры становятся смешными. По крайней мере, они объясняют, почему код грубой силы навсегда висит на доске 2х3. Пространство поиска платы 2х3 в 742560 раз больше, чем 2х2 . Если для завершения 2x2 требуется 20 секунд, консервативная экстраполяция прогнозирует более 100 дней времени выполнения для 2x3. Очевидно, что нам нужно обрезать.
Анализ обрезки
Я начал с добавления очень простого сокращения с использованием алгоритма альфа-бета. По сути, он прекращает поиск, если идеальный противник никогда не даст ему свои текущие возможности. «Эй, смотри - я выиграю много, если мой противник позволит мне получить каждый квадрат!», - подумал ни один ИИ.
редактировать Я также добавил обрезку на основе симметричных плат.
Я не использую метод запоминания, просто на случай, если когда-нибудь я добавлю запоминание и хочу оставить этот анализ отдельным. Вместо этогоэто работает так: большинство линий имеют «симметричную пару» где-то еще в сетке. Существует до 7 симметрий (горизонтальная, вертикальная, 180 вращений, 90 вращений, 270 вращений, диагональ и другие диагонали). Все 7 относятся к квадратным доскам, но последние 4 не относятся к неквадратным доскам. Каждая стена имеет указатель на свою «пару» для каждой из этих симметрий. Если при входе в поворот доска является горизонтально симметричной, то необходимо играть только по одной из каждой горизонтальной пары .редактировать редактировать запоминание! Каждая стена получает уникальный идентификатор, который я обычно устанавливаю как индикаторный бит; у n-ой стены есть id
1 << n
. Хэш доски - это просто ИЛИ всех сыгранных стен. Это обновляется в каждой ветви за O (1) раз. Размер хеш-таблицы устанавливается в#define
. Все тесты были выполнены с размером 2 ^ 12, потому что почему бы и нет? Когда имеется больше стенок, чем битов, индексирующих хеш-таблицу (в данном случае 12 битов), наименее значимые 12 маскируются и используются в качестве индекса. Столкновения обрабатываются с помощью связанного списка в каждом индексе хеш-таблицы. Следующая таблица - это мой быстрый анализ того, как размер хеш-таблицы влияет на производительность. На компьютере с бесконечной оперативной памятью мы всегда устанавливаем размер таблицы равным числу стен. Доска 3х4 будет иметь хеш-таблицу длиной 2 ^ 31. Увы, у нас нет такой роскоши.Хорошо, вернемся к обрезке. Остановив поиск высоко в дереве, мы сможем сэкономить много времени, не опускаясь до листьев. «Фактор обрезки» - это часть всех возможных ветвей, которые нам приходилось посещать. У грубой силы фактор обрезки равен 1. Чем он меньше, тем лучше.
источник
rows columns
определяющие размер доскиПитон - 2x2 в 29 с
Кросс-постинг из головоломок . Не особенно оптимизирован, но может стать полезной отправной точкой для других участников.
источник
Javascript - доска 1х2 за 20мс
Онлайн-демонстрация доступна здесь (предупреждение - очень медленное, если размер больше 1x2 с полной глубиной поиска ): https://dl.dropboxusercontent.com/u/141246873/minimax/index.html
Был разработан для оригинальных критериев победы (код гольф), а не для скорости.
Проверено в Google Chrome v35 на Windows 7.
источник