A causa della natura della domanda, devo includere molte informazioni di base (perché la mia domanda è: come posso restringerla?) Detto questo, può essere sintetizzata (per quanto ne so)
Quali metodi esistono per trovare gli ottimum locali su spazi di ricerca combinatoria estremamente ampi?
sfondo
Nella comunità di superplay assistiti da strumenti cerchiamo di fornire input appositamente realizzati (non generati in tempo reale) a una console o emulatore di videogiochi al fine di ridurre al minimo alcuni costi (di solito il tempo necessario per il completamento). Il modo in cui questo è attualmente fatto è giocando il gioco fotogramma per fotogramma e specificando l'input per ciascun fotogramma, spesso ripetendo più volte parti della corsa (ad esempio, la corsa recentemente pubblicata per The Legend of Zelda: Ocarina of Time ha un totale di 198.590 tentativi).
Fare in modo che queste piste raggiungano il loro obiettivo di solito si riduce a due fattori principali: pianificazione del percorso e traversata. Il primo è molto più "creativo" del secondo.
La pianificazione del percorso sta determinando il modo in cui il giocatore deve navigare nel complesso per completare il gioco ed è spesso la parte più importante della corsa. Ciò è analogo alla scelta del metodo di ordinamento da utilizzare, ad esempio. Il miglior ordinamento di bolle al mondo semplicemente non supererà un ordinamento rapido su 1 milione di elementi.
Nel desiderio di perfezione, tuttavia, anche l'attraversamento (come viene eseguita la rotta) è un fattore enorme. Continuando l'analogia, ecco come viene implementato l'algoritmo di ordinamento. Alcuni percorsi non possono nemmeno essere eseguiti senza frame di input molto specifici. Questo è il processo più noioso di assistenza degli utensili ed è ciò che rende la produzione di una corsa completata richiede mesi o addirittura anni. Non è un processo difficile (per un essere umano) perché si tratta di provare diverse varianti della stessa idea fino a quando una non viene considerata la migliore, ma gli umani possono solo provare così tante variazioni nel loro raggio di attenzione. L'applicazione delle macchine a questo compito sembra corretta qui.
Il mio obiettivo ora è cercare di automatizzare il processo di attraversamento in generale per la console Nintendo 64 . Lo spazio di ricerca per questo problema è di gran lunga troppo grande per attaccare con un approccio a forza bruta. Un segmento n-frame di una corsa N64 ha 2 30n possibili input, il che significa che solo 30 frame di input (un secondo a 30FPS) ha 2 900 possibili input; sarebbe impossibile testare queste potenziali soluzioni, per non parlare di quelle per una corsa completa di due ore.
Tuttavia, non sono interessato a tentare (o meglio, non proverò nemmeno a tentare) l'ottimizzazione globale totale di una corsa completa. Piuttosto, dato un input iniziale , vorrei approssimare l' ottimale locale per un particolare segmento di una corsa (o gli ottimum n locali più vicini, per una sorta di ottimizzazione semi-globale) . Cioè, data una rotta e una traversata iniziale di quella rotta: cerca i vicini di quella traversata per minimizzare i costi, ma non degenerare nel provare tutti i casi che potrebbero risolvere il problema.
Il mio programma dovrebbe quindi assumere uno stato iniziale, un flusso di input, una funzione di valutazione e produrre l'ottimale locale minimizzando il risultato della valutazione.
Stato attuale
Attualmente mi occupo di tutto il quadro. Ciò include la valutazione di un flusso di input tramite la manipolazione dell'emulatore, l'installazione e lo smontaggio, la configurazione, ecc. E come sorta di segnaposto, l'ottimizzatore è un algoritmo genetico di base. Valuta semplicemente una popolazione di flussi di input, memorizza / sostituisce il vincitore e genera una nuova popolazione mutando il flusso del vincitore. Questo processo continua fino a quando non vengono soddisfatti alcuni criteri arbitrari, come il tempo o il numero di generazione.
Si noti che la parte più lenta di questo programma sarà, di gran lunga, la valutazione di un flusso di input . Questo perché si tratta di emulare il gioco per n frame. (Se avessi il tempo, scriverei il mio emulatore che forniva hook in questo tipo di cose, ma per ora sono rimasto con la sintesi dei messaggi e la modifica della memoria per un emulatore esistente da un altro processo.) Sul mio computer principale, che è abbastanza moderno, la valutazione di 200 fotogrammi richiede circa 14 secondi. Come tale, preferirei un algoritmo (data la scelta) che minimizza il numero di valutazioni delle funzioni.
Ho creato un sistema nel framework che gestisce contemporaneamente gli emulatori. In quanto tale, posso valutare più flussi contemporaneamente con una scala lineare delle prestazioni, ma praticamente il numero di emulatori in esecuzione può essere compreso tra 8 e 32 (e 32 lo sta spingendo davvero) prima che le prestazioni del sistema peggiorino. Ciò significa (data la scelta), un algoritmo che può eseguire l'elaborazione mentre è in corso una valutazione sarebbe estremamente vantaggioso, perché l'ottimizzatore può fare un duro lavoro mentre attende una valutazione.
Come test, la mia funzione di valutazione (per il gioco Banjo Kazooie ) era di sommare, per frame, la distanza dal giocatore a un punto obiettivo. Ciò significava che la soluzione ottimale era avvicinarsi a quel punto il più rapidamente possibile. Limitando la mutazione solo allo stick analogico, ci è voluto un giorno per ottenere una soluzione accettabile . (Questo era prima che implementassi la concorrenza.)
Dopo aver aggiunto la concorrenza, ho abilitato la mutazione della pressione del pulsante A e ho svolto la stessa funzione di valutazione in un'area che richiedeva il salto. Con 24 emulatori in esecuzione ci sono voluti circa 1 ora per raggiungere l'obiettivo da un flusso di input inizialmente vuoto, ma probabilmente avrebbe bisogno di funzionare per giorni per arrivare a qualcosa di vicino all'ottimale.
Problema
Il problema che sto affrontando è che non conosco abbastanza bene il campo dell'ottimizzazione matematica per sapere come modellare correttamente il mio problema di ottimizzazione ! Posso seguire approssimativamente l'idea concettuale di molti algoritmi come descritto su Wikipedia, ad esempio, ma non so come classificare il mio problema o selezionare l'algoritmo all'avanguardia per quella categoria.
Da quello che posso dire, ho un problema combinatorio con un quartiere estremamente vasto . Inoltre, la funzione di valutazione è estremamente discontinua, non ha gradiente e ha molti altopiani . Inoltre, non ci sono molti vincoli, anche se aggiungerò volentieri la possibilità di esprimerli se aiuta a risolvere il problema; Vorrei consentire di specificare che il pulsante Start non deve essere utilizzato, ad esempio, ma non è questo il caso generale.
Domanda
Quindi la mia domanda è: come posso modellarlo? Che tipo di problema di ottimizzazione sto cercando di risolvere? Quale algoritmo suppongo di usare? Non ho paura di leggere articoli di ricerca, quindi fatemi sapere cosa dovrei leggere!
Intuitivamente, un algoritmo genetico non potrebbe essere il migliore, perché non sembra davvero imparare. Ad esempio, se premere Start sembra peggiorare sempre la valutazione (perché mette in pausa il gioco), dovrebbe esserci una sorta di designer o cervello che impara: "premere Start in qualsiasi momento è inutile". Ma anche questo obiettivo non è così banale come sembra, perché a volte premere start è ottimale, come nel cosiddetto "pausa back-long-jump" in Super Mario 64 ! Qui il cervello dovrebbe imparare uno schema molto più complesso: "premere Start è inutile tranne quando il giocatore si trova in questo stato molto specifico e continuerà con una combinazione di pressioni di pulsanti ".
Sembra che dovrei (o la macchina potrebbe imparare a) rappresentare l'input in qualche modo più adatto alla modifica. L'input per fotogramma sembra troppo granulare, perché ciò che è veramente necessario sono le "azioni", che possono estendersi su più fotogrammi ... eppure molte scoperte vengono fatte fotogramma per fotogramma, quindi non posso escluderlo del tutto (il la suddetta pausa all'indietro-salto in lungo richiede precisione a livello di frame). Sembra anche che il fatto che l'input venga elaborato in serie dovrebbe essere qualcosa su cui poter capitalizzare, ma non sono sicuro di come.
Attualmente sto leggendo la ricerca (reattiva) di Tabu, la ricerca di vicinato su larga scala, l'ottimizzazione basata sull'insegnamento e l'apprendimento e l'ottimizzazione delle colonie di formiche.
Questo problema è semplicemente troppo difficile da affrontare con qualcosa di diverso dagli algoritmi genetici casuali? O è in realtà un problema banale che è stato risolto molto tempo fa? Grazie per la lettura e grazie in anticipo per eventuali risposte.