Як я класифікую проблему оптимізації вводу емулятора та за допомогою якого алгоритму слід підходити до нього?


10

Зважаючи на характер запитання, я повинен включати багато довідкової інформації (оскільки моє запитання: як я звужу це?). Сказане, це може бути узагальнено (наскільки мені відомо) як:

Які існують методи для пошуку локальних оптимумів на надзвичайно великих просторах комбінаторного пошуку?

Фон

У спільноті суперігор за допомогою інструментів ми прагнемо надати спеціально складений (не генерований у режимі реального часу) вхід до консолі відеоігри чи емулятора, щоб мінімізувати деяку вартість (як правило, до завершення). Як це робиться в даний час, це граючи в гру кадр за кадром і вказуючи вхід для кожного кадру, часто повторюючи частини пробігу багато разів (наприклад, нещодавно опублікований запуск для Legend of Zelda: Ocarina of Time has загалом 198 590 спроб).

Здійснення цих пробігів досягає мети, як правило, зводиться до двох основних факторів: планування маршруту та обхід. Перший набагато «креативніший», ніж другий.

Планування маршруту визначає, яким саме гравцем слід орієнтуватися в цілому, щоб завершити гру, і часто це найважливіша частина бігу. Це аналогічно вибору, наприклад, який спосіб сортування використовувати, наприклад. Найкращий сорт бульбашок у світі просто не збирається перевершити швидке сортування на 1 мільйон елементів.

Однак у прагненні до досконалості величезний фактор - також обхід (як здійснюється маршрут). Продовжуючи аналогію, саме так реалізований алгоритм сортування. Деякі маршрути навіть неможливо виконати без введення дуже конкретних кадрів. Це самий виснажливий процес інструментальної допомоги, і це змушує виготовлення завершеного циклу займати місяці чи навіть роки. Це не складний процес (для людини), оскільки він зводиться до спроб різних варіантів однієї ідеї, поки одна людина не буде визнана найкращою, але люди можуть спробувати лише стільки варіацій у своєму діапазоні уваги. Застосування машин до цього завдання тут здається правильним.

Моя мета зараз - спробувати автоматизувати процес обходу взагалі для системи Nintendo 64 . Простір пошуку для цієї проблеми поки занадто велике , щоб атакувати з перебором підходом. Сегмент n-кадру запуску N64 має 2 30n можливих входів, тобто лише 30 кадрів вводу (секунда при 30FPS) має 2 900 можливих входів; неможливо було б протестувати ці потенційні рішення, не кажучи вже про ці, протягом повного двогодинного пробігу.

Однак мені не цікаво намагатися (а точніше, я навіть не збираюся намагатися) повної глобальної оптимізації повного циклу. Швидше, я хотів би, з огляду на початковий внесок, наблизити локальний оптимум для певного сегменту пробігу (або найближчого n локальних оптимумів, для свого роду напів глобальної оптимізації) . Тобто, враховуючи маршрут та початкову траверсію цього маршруту: шукайте сусідів цього траверсу, щоб мінімізувати витрати, але не вироджуйтеся в спробах усіх випадків, які могли б вирішити проблему.

Тому моя програма повинна приймати початковий стан, потік введення, функцію оцінювання та виводити локальний оптимум, зводячи до мінімуму результат оцінки.

Поточний стан

В даний час я подбав про всі рамки. Це включає в себе оцінку вхідного потоку за допомогою маніпуляції емулятором, налаштуванням та вилученням, конфігурацією тощо. Оптимізатор - це основний генетичний алгоритм. Він просто оцінює сукупність вхідних потоків, зберігає / замінює переможця та генерує нову сукупність, мутуючи потік переможця. Цей процес триває до тих пір, поки не будуть виконані якісь довільні критерії, наприклад, час чи кількість покоління.

Зауважте, що найбільш повільною частиною цієї програми буде, безумовно, оцінка вхідного потоку . Це тому, що це включає емуляцію гри для n кадрів. (Якби у мене був час, я б написав власний емулятор, який забезпечував гачки подібних матеріалів, але поки що мені залишається синтезувати повідомлення та змінювати пам'ять для існуючого емулятора з іншого процесу.) На моєму головному комп'ютері, який досить сучасна, оцінка 200 кадрів займає приблизно 14 секунд. Тому я вважаю за краще алгоритм (з урахуванням вибору), який мінімізує кількість оцінок функції.

Я створив систему в рамках, який одночасно управляє емуляторами. Як такий, я можу оцінити відразу декілька потоків за лінійною шкалою продуктивності, але практично кажучи, кількість працюючих емуляторів може становити лише 8 до 32 (а 32 насправді штовхає його) до погіршення продуктивності системи. Це означає (з урахуванням вибору), алгоритм, який може виконувати обробку під час оцінки, був би дуже корисним, оскільки оптимізатор може робити важкі підйоми, поки він чекає на оцінку.

Як тест, моя функція оцінки (для гри Банджо Казуої ) полягала в тому, щоб підсумовувати, за кадром, відстань від гравця до точки воріт. Це означало, що оптимальним рішенням було якомога швидше наблизитися до цієї точки. Обмежуючи мутацію лише аналоговою паличкою, потрібен день, щоб отримати нормальне рішення. (Це було до того, як я застосував паралельність.)

Після додавання одночасності я ввімкнув мутацію натискань на кнопку A і зробив ту саму функцію оцінювання в області, яка вимагала стрибків. При запуску 24 емуляторів знадобилося приблизно 1 годину, щоб досягти мети з початково пустого вхідного потоку, але, ймовірно, потрібно буде працювати цілими днями, щоб дійти до чогось, близького до оптимального.

Проблема

Проблема, з якою я стикаюсь, полягає в тому, що я недостатньо знаю поле математичної оптимізації, щоб знати, як правильно моделювати мою проблему оптимізації ! Я, наприклад, можу приблизно дотримуватися концептуальної ідеї багатьох алгоритмів, як описано у Вікіпедії, але я не знаю, як класифікувати свою проблему або вибрати найсучасніший алгоритм для цієї категорії.

З того, що я можу сказати, у мене є комбінаторна проблема з надзвичайно великим сусідством . Крім того, функція оцінювання надзвичайно перервана, не має градієнта та має багато плато . Крім того, не так багато обмежень, хоча я з радістю додаю можливість висловити їх, якщо це допоможе вирішити проблему; Я хотів би дозволити вказати, що, наприклад, не слід використовувати кнопку "Пуск", але це не загальний випадок.

Питання

Отже, моє запитання: як я моделюю це? Яку проблему оптимізації я намагаюся вирішити? Який алгоритм я думаю використовувати? Я не боюся читати науково-дослідні роботи, тому дайте мені знати, що я повинен читати!

Інтуїтивно зрозумілий, генетичний алгоритм не міг бути найкращим, тому що він насправді не вчився. Наприклад, якщо натискання кнопки «Пуск», здається, завжди погіршує оцінку (оскільки це призупиняє гру), то має бути якийсь конструктор чи мозок, який вчиться: «натискання кнопки« Пуск »у будь-якій точці марно». Але навіть ця мета не настільки тривіальна, як це звучить, тому що іноді натискання на старт є оптимальним, як, наприклад, у так званій "паузі назад-довго стрибки" в Super Mario 64 ! Тут мозку доведеться навчитися набагато складнішій схемі: "натискання кнопки" Старт "марно, за винятком випадків, коли гравець перебуває в такому дуже специфічному стані і продовжить деяку комбінацію натискань кнопок ".

Здається, я повинен (або машина могла б навчитися) представляти вклад в інший спосіб, більш придатний для модифікації. Введення за кадром здається занадто детальним, тому що дійсно потрібні "дії", які можуть охоплювати кілька кадрів ... але багато відкриттів робиться на основі кадрів, тому я не можу повністю виключити це ( згадана пауза, стрибок назад у довжину вимагає точності на рівні кадру). Також здається, що те, що вхід обробляється серійно, має бути чимось, на якому можна використовувати великі літери, але я не знаю як.

В даний час я читаю про (Реактивний) пошук Tabu, дуже масштабний пошук сусідства, оптимізацію на основі навчання та навчання та оптимізацію колоній мурашок.

Чи просто з цією проблемою важко впоратися з чим-небудь, крім випадкових генетичних алгоритмів? Або це насправді тривіальна проблема, яка була вирішена давно? Дякуємо за прочитане та заздалегідь дякую за будь-які відповіді.


Ваше повідомлення досить довге, воно допоможе читачам, якщо у вас буде короткий розділ на тему, в якому чітко викладене питання, без додаткової довідкової інформації.
Каве

@Kaveh: Я розумію, що це довговічність, але через характер питання досить важко звузити, оскільки я досить багато запитую, як звузити його. :(

Відповіді:


6

З інформації, яку ви надаєте у своєму запитанні, я не бачу, як застосовувати стандартні методи оптимізації (про які я знаю). Ваші об'єкти не такі складні (докладніше про це пізніше), але ваша цільова функція противна: її значення визначаються зовнішньою системою поза вашим контролем, вона навряд чи матиме приємні властивості тощо. Тому я думаю, що використання генетичних алгоритмів тут не є нездійсненним і, можливо, навіть хорошим підходом; вони часто працюють краще, ніж інші методи, якщо у вас немає поняття про структуру вашої проблеми. Є про що слід розглянути

  • об'єктний простір,
  • цільова функція і
  • параметри вашого генетичного алгоритму,

тому дозвольте мені детальніше.

Які ваші об’єкти?

Ви вже відповіли на це: ви переглядаєте послідовність дій, кожна з яких займає один кадр. Я думаю, це може бути занадто дрібнозернистим; можливо спробуйте послідовність дій, кожна з тривалістю (у кількості кадрів). Це дозволило б мутаціям типу "ходити трохи довше", щоб мати інші ймовірності, ніж "вставити прес A" природним чином. Спробуйте, що найкраще працює; можливо, вам доведеться переглянути цей предмет, подумавши про інші інгредієнти.

Яка ваша цільова функція?

Цей дійсно є вирішальним. Що ви хочете оптимізувати? Час до мети? Кількість різних дій? Кількість зібраних зірок? Поєднання кількох факторів? Як тільки ви отримуєте кілька цілей, речі стають волохатими - там (як правило) вже немає оптими!

Ви згадали час до мети. Це, мабуть, зовсім не хороша цільова функція. Чому? Тому що більшість послідовностей навіть не досягнуть мети, тому вони будуть підводити деяку константу, створюючи подібний фітнес-пейзаж (концептуальний ескіз в одному вимірі):

введіть тут опис зображення
[ джерело ]

00

11+final distance to goal+11+time to goal

011

То як вимірювати відстань? Лінійна відстань може виглядати спокусливо, але має свої проблеми; знову ж, неправильні сигнали можуть надсилатися. Розглянемо цей простий сценарій:

введіть тут опис зображення
[ джерело ]

Кожна послідовність, яка починається зі стрибка до верхнього коридору, вдосконалюється, поки не досягне місця трохи вище мети, але насправді вона не може дійсно дістатися мети! Ще гірше, що серед послідовностей, які не досягають мети, ті, що піднімаються вгору, такі ж хороші, як і ті, що йдуть вниз, тому GA не може відкинути послідовності, які явно приречені. Іншими словами, лінійна відстань створює особливо погані локальні оптими, які можуть захопити GA, якщо на рівні є тупики.

Тому я пропоную вам накласти сітку над своїм рівнем і з'єднати сусідні точки, якщо ігровий персонаж може дістатися від одного до іншого. Потім ви обчислюєте відстань від мети за довжиною найкоротшого шляху від точки, найближчої до тієї, де послідовність висаджує символ до точки, найближчої до мети. Це легко обчислити, і ходіння в десятиліття (місцеві оптими) негайно карається¹. Звичайно, вам потрібен доступ до даних рівня, але я припускаю, що у вас є такі.

Як працює ваш GA?

Тепер ми можемо перейти до власне генетичного алгоритму. Основні міркування - критерій популяції, відбору, відтворення / мутації та зупинки.

Населення

Наскільки чисельним буде ваше населення? Якщо він занадто малий, він може не забезпечити різноманіття, необхідного для досягнення хорошого рішення. Якщо вона занадто велика, ви, швидше за все, несете непотрібні сміття, сповільнюючи процес.

Як ви ініціалізуєте своє населення? Ви вибираєте випадкові послідовності дій? Якщо так, то якої довжини? Чи є у вас (невелика) кількість вироблених вручну розумних рішень для насіння, можливо таких, які досягають мети?

Вибір

k

Основна концепція тут - тиск на вибір : наскільки важко вижити? Зробіть це занадто маленьким, і ви не відмивайте лайно рішення. Зробіть це занадто високим і ви зробите важкі зміни (зокрема, переміщення між місцевими оптимами).

Розмноження та мутація

Після того, як ви вибрали тих, хто вижив в одному раунді, ви повинні створити з них наступне покоління (чи виживають батьки і є частиною наступного покоління?). Є дві основні стратегії: мутація та рекомбінація.

Мутація цілком зрозуміла, хоча специфіка може відрізнятися. Для кожної позиції в послідовності людини мутуйте її з певною вірогідністю. Ви можете зробити це незалежно для кожної позиції, або вибрати кількість мутацій випадковим чином, або ви можете виконати різні мутації з різною ймовірністю (наприклад, вставлення нового елемента, видалення одного, зміна однієї, ...). Мутація зазвичай стосується невеликих змін.

Рекомбінація, що поєднує аспекти двох або більше рішень нового, є більш хитрою, але може дозволити великі кроки, тобто залишити одну «гору фітнесу» і перейти безпосередньо на схил іншої (яка може бути і вище). Класична ідея - кросовер ; Я не знаю, чи має це сенс тут (мені здається, що заміна префікса заданої послідовності на щось інше швидше за все знецінить суфікс). Можливо, ви можете використовувати знання про рівень та положення ігрового персонажа в різних точках послідовності, щоб керувати цим, тобто створювати кросовер-точки лише тоді, коли персонаж знаходиться в одній і тій же позиції в обох послідовностях.

Припинення

Nk1n


Як бачите, всі ці речі переплітаються, щоб впливати на фактичну ефективність. Якщо ви використовуєте декілька популяцій паралельно, можна навіть думати про реалізацію генетичного дрейфу через міграцію та / або катастрофи. Теорія мало для того, щоб орієнтуватися на вашому шляху, тож вам доведеться випробувати різні налаштування і подивитися, куди це потрапить. Сподіваємось, те, що працює для одного рівня, буде працювати і для інших. Щасливого майстерності!

Nota bene: Погляньте на BoxCar 2D у світлі вищезазначеного. Вони роблять деякі речі досить добре (інші - не так), і ви можете зрозуміти, як параметри GA можуть впливати на його ефективність.


  1. Насправді, побудова послідовності з жадібністю з використанням цього фітнесу, тобто вибір дії, що мінімізує відстань до мети з усіх можливих наступних дій, може працювати досить добре. Спробуйте, перш ніж використовувати GA!
  2. Звичайно, ви як спостерігач завжди пам’ятаєте найкраще рішення, яке коли-небудь стикалося.

1
Приємно! Два питання. Що змушує вас сказати, що в MOO (як правило) немає оптими? Бали оптимальні для Парето, тобто ви не можете покращити щось, не жертвуючи чимось іншим. Дати їм значення залежить від модельєра. Також, чи не є мутація щодо невеликих змін з малою ймовірністю? З великою ймовірністю мутації пошук має тенденцію робити випадкові, некеровані рухи, які зазвичай шкодять продуктивності. Я думаю, що було помічено, що невеликі ймовірності мутації працюють найкраще.
Juho

1/nn1

Гаразд, бачу. Щодо третього пункту так, я мав на увазі щось саме таке. Дякую!
Juho

Дякую за всю інформацію! Дійсно гарно викладена відповідь, яка прояснює моє розуміння.
GManNickG

1

Більш детально про метод оптимізації на основі навчального навчання (TLBO) та його код див. У наступній роботі:

Елітарний алгоритм оптимізації, заснований на навчанні та навчанні, для вирішення складних задач з обмеженою оптимізацією Р. Венката Рао та В. Пателя; Міжнародний журнал обчислень промислового машинобудування 3 (4): 535–560 (2012)

Для додаткового читання:


1
Ласкаво просимо до cs.SE, і дякую за вашу відповідь! Зауважте, що ви можете використовувати Markdown для форматування своїх публікацій; Я пропоную вам ознайомитися з моєю редакцією. Щодо змісту, я не думаю, що це допомагає ОП, який, схоже, хоче знати, як моделювати свою проблему, а не деталі щодо конкретної методики. Крім того, чи є лише один хлопець, що працює над TLBO?
Рафаель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.