Зважаючи на характер запитання, я повинен включати багато довідкової інформації (оскільки моє запитання: як я звужу це?). Сказане, це може бути узагальнено (наскільки мені відомо) як:
Які існують методи для пошуку локальних оптимумів на надзвичайно великих просторах комбінаторного пошуку?
Фон
У спільноті суперігор за допомогою інструментів ми прагнемо надати спеціально складений (не генерований у режимі реального часу) вхід до консолі відеоігри чи емулятора, щоб мінімізувати деяку вартість (як правило, до завершення). Як це робиться в даний час, це граючи в гру кадр за кадром і вказуючи вхід для кожного кадру, часто повторюючи частини пробігу багато разів (наприклад, нещодавно опублікований запуск для 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, дуже масштабний пошук сусідства, оптимізацію на основі навчання та навчання та оптимізацію колоній мурашок.
Чи просто з цією проблемою важко впоратися з чим-небудь, крім випадкових генетичних алгоритмів? Або це насправді тривіальна проблема, яка була вирішена давно? Дякуємо за прочитане та заздалегідь дякую за будь-які відповіді.