Это Fortnightly Challenge # 3. Тема: Генетические алгоритмы
Этот вызов - эксперимент. Мы хотели посмотреть, что мы можем сделать, с помощью генетических алгоритмов. Не все может быть оптимальным, но мы старались сделать его доступным. Если это сработает, кто знает, что мы можем увидеть в будущем. Может быть, генетический король горы?
Спецификация довольно длинная! Мы попытались разделить спецификацию на Основы - необходимый минимум, чтобы начать играть с фреймворком и представить ответ - и подробности The Gory - полную спецификацию со всеми подробностями о контроллере, на основе которых вы мог написать свой.
Если у вас есть какие-либо вопросы, присоединяйтесь к нам в чате!
Вы исследователь в поведенческой психологии. Это вечер пятницы, и вы и ваши коллеги решили повеселиться и использовать своих лабораторных крыс для небольшой крысиных гонок. На самом деле, прежде чем мы будем слишком эмоционально привязаны к ним, давайте назовем их образцами .
Вы создали небольшую гоночную трассу для образцов, и чтобы сделать ее более интересной, вы разместили несколько дорожек, ловушек и телепортеров по всей трассе. Теперь ваши образцы все еще крысы ... они понятия не имеют, что такое ловушка или телепорт. Все, что они видят, это вещи разных цветов. У них также нет никакой памяти - все, что они могут сделать, - это принимать решения, основываясь на их текущем окружении. Я предполагаю, что естественный отбор выберет образцы, которые знают, как избежать ловушки из тех, которые этого не делают (эта гонка займет некоторое время ...). Да начнется игра! †
† 84 465 особей были повреждены при постановке этой задачи.
Основы
Это однопользовательская игра (вы и ваши коллеги не хотели смешивать население, поэтому каждый из них создал свой собственный гоночный трек). Ипподром представляет собой прямоугольную сетку высотой 15 ячеек и шириной 50 ячеек. Вы начинаете с 15 образцов на случайных (не обязательно отличных) ячейках на левом краю (где x = 0 ). Ваши образцы должны попытаться достичь цели, которой является любая ячейка при x ≥ 49 и 0 ≤ y ≤ 14 (образцы могут отклониться от пути вправо). Каждый раз, когда это происходит, вы получаете очко. Вы также начинаете игру с 1 очком. Вы должны попытаться максимизировать свои очки после 10 000 ходов.
Несколько образцов могут занимать одну и ту же ячейку и не будут взаимодействовать.
На каждом ходу каждый образец видит сетку 5x5 своего окружения (с самим собой в центре). Каждая ячейка этой сетки будет содержать цвет -1
к 15
. -1
представляет клетки, которые находятся за пределами. Ваш образец умирает, если он выходит за пределы. Что касается других цветов, они представляют собой пустые клетки, ловушки, стены и телепорты. Но ваш образец не знает, какой цвет представляет, и вы тоже. Однако есть некоторые ограничения:
- 8 цветов будут представлять пустые ячейки.
- 4 цвета будут представлять телепорт. Телепортер отправит образец в определенную ячейку в своем районе 9x9. Это смещение будет одинаковым для всех телепортеров одного цвета.
- 2 цвета будут представлять стены. Двигаться в стену - все равно, что стоять на месте.
- 2 цвета будут представлять ловушку. Ловушка указывает, что одна из 9 клеток в ее непосредственной близости является летальной (не обязательно сама клетка ловушки). Это смещение будет одинаковым для всех ловушек одного цвета.
Теперь об этом естественном отборе ... у каждого экземпляра есть геном, представляющий собой число из 100 битов. Новые образцы будут созданы путем скрещивания двух существующих образцов, а затем с незначительным изменением генома. Чем успешнее образец, тем больше у него шансов на воспроизведение.
Итак, вот ваша задача: вы напишите одну функцию, которая получает в качестве входных данных сетку цветов 5x5, которую видит образец, а также его геном. Ваша функция вернет ход (Δx, Δy) для образца, где Δx и Δy будут каждый из {-1, 0, 1}
. Вы не должны сохранять какие-либо данные между вызовами функций. Это включает в себя использование ваших собственных генераторов случайных чисел. Ваша функция будет обеспечена засеянным ГСЧ, который вы можете использовать по своему усмотрению.
Оценка вашего представления будет средним геометрическим числом баллов по 50 случайным трекам. Мы обнаружили, что эта оценка подвержена значительным отклонениям. Поэтому эти оценки будут предварительными . Как только этот вызов исчезнет, будет объявлен крайний срок. По истечении крайнего срока, 100 досок будут выбраны случайным образом, и все заявки будут перенесены на эти 100 досок. Не стесняйтесь ставить оценку в вашем ответе, но мы будем оценивать каждую подачу самостоятельно, чтобы никто не обманывал.
Мы предоставили программы контроллеров на нескольких языках. В настоящее время вы можете написать свою заявку на Python (2 или 3), Ruby , C ++ , C # или Java . Контроллер генерирует доски, запускает игру и обеспечивает основу для генетического алгоритма. Все, что вам нужно сделать, это обеспечить функцию перемещения.
Подождите, так что же мне делать с геномом?
Задача состоит в том, чтобы понять это!
Поскольку у образцов нет памяти, все, что у вас есть в данном ходу, - это сетка цветов 5х5, которая ничего для вас не значит. Таким образом, вам придется использовать геном, чтобы достичь цели. Общая идея заключается в том, что вы используете части генома для хранения информации о цветах или компоновке сетки, а ваш бот основывает свои решения на дополнительной информации, хранящейся в геноме.
Теперь, конечно, вы не можете хранить там что-либо вручную. Таким образом, фактическая информация, хранящаяся там, изначально будет полностью случайной. Но генетический алгоритм скоро выберет те образцы, чей геном содержит правильную информацию, и убьет те, у которых неправильная информация. Ваша цель - найти соответствие между битами генома и вашим полем зрения движением, которое позволяет быстро найти путь к цели и которое последовательно развивается в выигрышной стратегии.
Этого должно быть достаточно, чтобы вы начали. Если вы хотите, вы можете пропустить следующий раздел и выбрать нужный контроллер из списка контроллеров внизу (который также содержит информацию о том, как использовать этот конкретный контроллер).
Читайте дальше, если хотите все ...
Гори Детали
Эта спецификация завершена. Все контроллеры должны выполнять эти правила.
Вся случайность использует равномерное распределение, если не указано иное.
Генерация треков:
- Дорожка представляет собой прямоугольную сетку, шириной X = 53 ячейки и высотой Y = 15 ячеек. Ячейки с x ≥ 49 являются целевыми ячейками (где x основано на нуле).
- Каждая клетка имеет один цвет и может быть или не быть летальной - клетки не являются летальными, если это не указано одним из типов клеток ниже.
- Существует 16 различных цветов ячеек, помеченных от
0
до15
, значение которых будет меняться от игры к игре. Кроме того,-1
представляет клетки, которые находятся за пределами - это смертельно . - Выберите 8 случайных цветов . Это будут пустые ячейки (которые не имеют никакого эффекта).
- Выберите еще 4 случайных цвета . Это телепорты. Для двух из этих цветов выберите ненулевое смещение в окрестности 9x9 (от (-4, -4) до (4,4) за исключением (0,0)). Для других двух цветов инвертируйте эти смещения. Если образец наступает на телепорт, он немедленно перемещается на это смещение.
- Выберите еще 2 случайных цвета . Это ловушки. Для каждого из этих цветов выберите смещение в окрестности 3х3 (от (-1, -1) до (1,1)). Ловушка указывает на то, что ячейка с таким смещением смертельна . Примечание. Сама ловушка не обязательно смертельна.
- В 2 остальных цветами являются стенами, которые препятствуют движению. Попытка перейти на клетку стены превратит движение в неподвижность. Сами клеточные стенки смертельны .
- Для каждой нецелевой ячейки сетки выберите случайный цвет. Для каждой клетки цели выберите случайный пустой цвет.
- Для каждой ячейки на левом краю дорожки определите, можно ли достичь цели в течение 100 ходов (в соответствии с приведенными ниже правилами порядка хода ). Если это так, эта ячейка является допустимой стартовой ячейкой . Если начальных ячеек меньше 10, откажитесь от дорожки и создайте новую.
- Создайте 15 экземпляров, каждый со случайным геном и возрастом 0 . Поместите каждый образец в случайную начальную ячейку.
Порядок поворота:
- Следующие шаги будут выполнены, по порядку, для каждого образца. Образцы не взаимодействуют и не видят друг друга и могут занимать одну и ту же клетку.
- Если возраст образца составляет 100 лет , он умирает. В противном случае увеличьте его возраст на 1.
- Образцу предоставляется его поле зрения - сетка цветов 5x5, центрированная на образце, и он возвращает движение в своей окрестности 3x3. Выход за пределы этого диапазона приведет к прекращению работы контроллера.
- Если целевой ячейкой является стена, то ход изменяется на (0,0).
- Если целевая ячейка является телепортом, образец перемещается по смещению телепорта. Примечание. Этот шаг выполняется один раз , а не итеративно.
- Если ячейка, занятая в настоящее время образцом (возможно, после использования одного телепорта), смертельна, образец погибает. Это единственный раз, когда образцы умирают (кроме шага 1.1. Выше). В частности, новый образец, который появляется на смертельной клетке, не погибнет немедленно, но имеет шанс сначала покинуть опасную клетку.
- Если образец занимает целевую ячейку, наберите одно очко, переместите образец в случайную начальную ячейку и установите его возраст равным 0.
- Если на доске осталось менее двух экземпляров, игра заканчивается.
- Создайте 10 новых экземпляров с возрастом 0 . Каждый геном определяется (индивидуально) по правилам разведения ниже. Поместите каждый образец в случайную начальную ячейку.
Разведение:
Когда создается новый образец, выбирайте двух разных родителей наугад, с уклоном в сторону образцов, которые продвинулись дальше вправо. Вероятность того, что образец будет выбран, пропорциональна его текущей оценке пригодности . Оценка пригодности образца
1 + x + 50 * сколько раз он достиг цели
где x - горизонтальный индекс на основе 0. Образцы, созданные в том же порядке, не могут быть выбраны в качестве родителей.
Из двух родителей выберите случайного, чтобы взять первый бит генома.
- Теперь, когда вы идете по геному, поменяйте родителей с вероятностью 0,05 и продолжайте брать биты у получающегося родителя.
- Мутируйте полностью собранный геном: для каждого бита переверните его с вероятностью 0,01 .
Подсчет очков:
- Одна игра длится 10000 ходов.
- Игроки начинают игру с 1 очком (чтобы разрешить использование среднего геометрического).
- Каждый раз, когда образец достигает цели, игрок получает очко.
- На данный момент каждый игрок подаст заявку на 50 игр, каждая из которых имеет свой случайный трек.
- Вышеуказанный подход приводит к большей дисперсии, чем желательно. Как только этот вызов исчезнет, будет объявлен крайний срок. По истечении крайнего срока, 100 досок будут выбраны случайным образом, и все заявки будут перенесены на эти 100 досок.
- Общий счет игрока является средним геометрическим значением очков этих отдельных игр.
Контроллеры
Вы можете выбрать любой из следующих контроллеров (так как они функционально эквивалентны). Мы протестировали все из них, но если вы обнаружили ошибку, хотите улучшить код или производительность, или добавили такую функцию, как графический вывод, отправьте сообщение об ошибке или отправьте запрос на GitHub! Также вы можете добавить новый контроллер на другом языке!
Нажмите на название языка для каждого контроллера, чтобы перейти к нужному каталогу на GitHub, который содержит README.md
точные инструкции по использованию.
Если вы не знакомы с git и / или GitHub, вы можете загрузить весь репозиторий в виде ZIP-файла с первой страницы (см. Кнопку на боковой панели).
питон
- Наиболее тщательно проверено. Это наша эталонная реализация.
- Работает как с Python 2.6+, так и с Python 3.2+!
- Это очень медленно. Мы рекомендуем запустить его с PyPy для существенного ускорения.
- Поддержка графического вывода с использованием либо
pygame
илиtkinter
.
Рубин
- Протестировано с Ruby 2.0.0. Должен работать с более новыми версиями.
- Это также довольно медленно, но Ruby может быть удобен для прототипирования идеи для представления.
C ++
- Требуется C ++ 11.
- Опционально поддерживает многопоточность.
- Безусловно, самый быстрый контроллер в связке.
C #
- Использует LINQ, поэтому он требует .NET 3.5.
- Скорее медленно.
Ява
- Не особенно медленно. Не особенно быстро.
Предварительная таблица лидеров
Все оценки являются предварительными. Тем не менее, если что-то не так или устарело, пожалуйста, дайте мне знать. Наш пример представления приведен для сравнения, но не для утверждения.
Score | # Games | User | Language | Bot
===================================================================================
2914.13 | 2000 | kuroi neko | C++ | Hard Believers
1817.05097| 1000 | TheBestOne | Java | Running Star
1009.72 | 2000 | kuroi neko | C++ | Blind faith
782.18 | 2000 | MT0 | C++ | Cautious Specimens
428.38 | | user2487951 | Python | NeighborsOfNeighbors
145.35 | 2000 | Wouter ibens | C++ | Triple Score
133.2 | | Anton | C++ | StarPlayer
122.92 | | Dominik Müller | Python | SkyWalker
89.90 | | aschmack | C++ | LookAheadPlayer
74.7 | | bitpwner | C++ | ColorFarSeeker
70.98 | 2000 | Ceribia | C++ | WallGuesser
50.35 | | feersum | C++ | Run-Bonus Player
35.85 | | Zgarb | C++ | Pathfinder
(34.45) | 5000 | Martin Büttner | <all> | ColorScorePlayer
9.77 | | DenDenDo | C++ | SlowAndSteady
3.7 | | flawr | Java | IAmARobotPlayer
1.9 | | trichoplax | Python | Bishop
1.04 | 2000 | fluffy | C++ | Gray-Color Lookahead
кредиты
Эта задача была огромным совместным усилием:
- Натан Меррил: Написал контроллеры Python и Java. Превратила концепцию испытаний из King-of-the-Hill в крысиные бега.
- Трихоплакс: тестирование. Работал на контроллере Python.
- feersum: Написал C ++ контроллер.
- VisualMelon: написал C # контроллер.
- Мартин Бюттнер: Концепция. Написал Ruby контроллер. Тестируем. Работал на контроллере Python.
- Т Авраам: тестирование. Протестировал Python и рассмотрел C # и C ++ контроллер.
Все вышеперечисленные пользователи (и, возможно, еще пара, о которых я забыл) внесли свой вклад в общий дизайн задачи.
Обновление контроллера C ++
Если вы используете C ++ с Visual Studio и многопоточностью, вы должны получить последнее обновление из-за ошибки с заполнением генератора случайных чисел, которая позволяет создавать дубликаты плат.
'In particular, a new specimen which spawns on a lethal cell will not die immediately, but has a chance to move off the dangerous cell first.'