Це Fortnightly Challenge # 3. Тема: Генетичні алгоритми
Цей виклик - трохи експеримент. Ми хотіли подивитися генетичні алгоритми, що ми можемо зробити, з викликом складності. Не все може бути оптимальним, але ми намагалися зробити це доступним. Якщо це вийде, хто знає, що ми можемо побачити в майбутньому. Може, генетичний Король гори?
Специфікація досить довга! Ми намагалися відокремити специфікацію на «Основи» - найголовніший мінімум, який потрібно знати, щоб почати грати з фреймворком та подати відповідь - та «The Gory Details» - повну специфікацію із усіма подробицями про контролер, на основі яких ви міг написати свій.
Якщо у вас є якісь питання, сміливо приєднуйтесь до нас у чаті!
Ви дослідник поведінкової психології. Увечері в п’ятницю, і ви та ваші колеги вирішили повеселитися та використати ваших лабораторних щурів для невеликої гонки з щурами. Насправді, перш ніж ми занадто емоційно прив’яжемось до них, давайте назвемо їх зразками .
Ви встановили невелику гоночну доріжку для екземплярів, і щоб зробити її цікавішою, ви поставили кілька стін, пасток і телепортаторів по всій трасі. Тепер ваші особини - це ще щури ... вони не мають поняття, що таке пастка чи телепорт. Вони бачать лише деякі речі різних кольорів. Вони також не мають жодної пам’яті - все, що вони можуть зробити, - це приймати рішення, виходячи з поточного оточення. Я здогадуюсь, що природний відбір вибере особин, які знають, як уникнути пастки від тих, хто цього не робить (ця гонка забирає деякий час ...). Нехай починаються ігри! †
† 84 465 екземплярів було завдано шкоди при здійсненні цього виклику.
Основи
Це гра з одиночним гравцем (ви та ваші колеги не хотіли змішувати популяцію, тому кожен побудував власну гоночну доріжку). Гоночна доріжка - це прямокутна сітка, 15 комірок заввишки та 50 комірок завширшки. Ви починаєте з 15 зразків на випадкових (не обов'язково виразних) клітинках з лівого краю (де х = 0 ). Ваші екземпляри повинні намагатися досягти мети, яка є будь-якою клітиною при x ≥ 49 та 0 ≤ y ≤ 14 (екземпляри можуть перевернути доріжку праворуч). Щоразу, коли це відбувається, ви отримуєте бал. Ви також починаєте гру з 1 очка. Вам слід спробувати максимізувати свої очки після 10000 оборотів.
Кілька зразків можуть займати одну клітинку і не взаємодіють.
На кожному кроці кожен зразок бачить 5х5 сітку свого оточення (із самим собою в центрі). Кожна комірка цієї сітки буде містити колір -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 . Контролер генерує дошки, запускає гру та забезпечує основу для генетичного алгоритму. Все, що вам потрібно зробити - це забезпечити функцію переміщення.
Зачекайте, так що саме я роблю з геномом?
Завдання - це зрозуміти!
Оскільки зразки не мають пам’яті, все, що ви отримали за певну чергу, є сіткою кольорів 5x5, які для вас нічого не означають. Тож вам доведеться використовувати геном для досягнення мети. Загальна ідея полягає в тому, що ви використовуєте частини геному для зберігання інформації про кольори або компонування сітки, а ваш бот базує свої рішення на додатковій інформації, що зберігається в геномі.
Тепер, звичайно, ви нічого не можете зберігати там вручну. Тож фактична інформація, що зберігається там, спочатку буде повністю випадковою. Але генетичний алгоритм незабаром відбере ті зразки, чий геном містить правильну інформацію, знищуючи ті, які мають неправильну інформацію. Ваша мета - знайти відображення від бітів геному та вашого поля зору до руху, що дозволяє швидко знайти шлях до мети, який послідовно розвивається до виграшної стратегії.
Це має бути достатньо інформації для початку роботи. Якщо ви хочете, ви можете пропустити наступний розділ і виберіть контролера за вибором зі списку контролерів у нижній частині (який також містить інформацію про те, як використовувати саме цей контролер).
Читайте далі, якщо ви хочете все ...
Деталі Горі
Ця специфікація завершена. Усі контролери повинні виконувати ці правила.
У всіх випадкових випадках використовується рівномірний розподіл, якщо не зазначено інше.
Генерація треку:
- Доріжка - це прямокутна сітка, X = 53 комірки в ширину і Y = 15 комірок у висоту. Клітини з x ≥ 49 - це клітини цілі (де x заснований на нулі).
- Кожна клітина має один колір і може бути або не бути летальною - клітини не є летальними, якщо не визначено одним із типів клітин нижче.
- Є 16 різних кольорів клітин, позначених міткою від
0
до15
, значення яких буде змінюватися від гри до гри. Крім того,-1
являє собою клітини, що знаходяться поза межами - це летально . - Виберіть 8 випадкових кольорів . Це будуть порожні клітини (які не мають ефекту).
- Виберіть ще 4 випадкових кольори . Це телепортери. Для двох із цих кольорів виберіть ненульове зміщення в районі 9x9 (від (-4, -4) до (4,4), крім (0,0)). Для двох інших кольорів переверніть ці компенсації. Якщо зразок наступає на телепортатор, він негайно переміщується цим зсувом.
- Виберіть ще 2 випадкових кольори . Це пастки. Для кожного з цих кольорів виберіть зміщення в районі 3x3 (від (-1, -1) до (1,1)). Пастка вказує, що клітина при цьому зміщенні є летальною . Примітка. Сама клітина пастки не обов'язково є летальною.
- Два решти кольору - це стіни, які перешкоджають руху. Спроба перейти на стінну камеру перетворить цей крок у нерухоме. Самі клітини стінки є летальними .
- Для кожної нецільової комірки сітки виберіть випадковий колір. Для кожної цільової комірки виберіть випадковий порожній колір.
- Для кожної комірки з лівого краю колії визначте, чи можна досягти мети протягом 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.
- Досить повільно.
Java
- Не особливо повільно. Не особливо швидко.
Попередня таблиця лідерів
Усі оцінки попередні. Тим не менш, якщо щось не так або застаріло, будь ласка, повідомте мене про це. Наш приклад подано для порівняння, але не заперечує.
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. Концепція виклику з Короля-Хілл перетворилася на щурячу гонку.
- трихоплакс: ігрові тести. Працював на контролері Python.
- feersum: Написав контролер C ++.
- VisualMelon: Написав контролер C #.
- Мартін Бюттнер: Концепція. Написав контролер Ruby. Ігрове тестування. Працював на контролері Python.
- T Авраам: Playtesting. Протестований 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.'