Outre A *, BFS, DFS, etc., quels sont les autres bons algorithmes de recherche de chemin/heuristiques couramment utilisés dans Pacman? Je ne pense pas que ceux que j'ai mentionnés fonctionneront s'il y a plus d'un fruit à rechercher pour Pacman.
J'ai besoin de bons algorithmes de recherche de chemin que PacMan peut utiliser pour finir le labyrinthe avec le moins de comptes possible. J'ai essayé de chercher une ligne directrice, mais jusqu'à présent, pas de chance. Une distance * avec Manhattan est mentionnée partout, mais elle ne fonctionnera qu'avec des labyrinthes avec seulement un (ou deux? Ou peut-être même quelques fruits) à obtenir.
BTW, pour garder les choses simples, en supposant qu'il n'y a pas de fantômes autour.
Quelques exemples tirés des problèmes originaux de PacMan: First , Second et Third
Votre commentaire indique que vous recherchez chemin le plus court} _. Ce problème est une variation de TSP sur un graphe planaire, et est donc NP-Hard .
Fonction heuristique possible pour A*
qui peut résoudre le problème mais n'est pas admissible [le chemin trouvé n'est donc pas optimal]:
Somme des distances de manhattan de tous les fruits à l'agent.
Vous pouvez également utiliser une heuristique éditable, de #fruits
- mais cela prendra beaucoup de temps.
Si vous recherchez l'optimum, eh bien, c'est difficile. Vous pouvez essayez toutes les permutations de fruits et vérifiez la distance totale que vous devez parcourir. Cette solution est factorielle dans le nombre de fruits , et si elle est supérieure à 20 - avec la force brute naïve - cela prendra trop de temps. Vous pouvez en quelque sorte améliorer la situation en en réduisant le problème à TSP , et en utilisant une solution de programmation dynamique, également exponentielle, ou des solutions heuristiques à TSP.
On peut également améliorer la solution heuristique non admissible en fournissant un algorithme à tout moment :
exécute de manière itérative A*
avec une fonction heuristique décroissante : h(v) = h'(v) / m
, où h'
est la fonction heuristique à la dernière itération de A *, et m > 1
. Cela garantit qu’à un moment donné, votre fonction heuristique h
sera admissible - et que la solution trouvée sera optimale. Cependant, chaque itération devrait durer beaucoup plus longtemps que la précédente [de façon exponentielle plus longue ..]
Heuristique qui a fonctionné pour moi si vous connaissez le regard du labyrinthe:
x
name__.y
name__.Ensuite, la réponse est juste: x + y
.
Notez que les distances réelles ne sont pas des distances de Manhattan, mais plutôt real
dans le labyrinthe - vous pouvez calculer cela (même si vous le souhaitez), car vous connaissez l'aspect du labyrinthe (vous connaissez tous les murs, ...). Cette information (distance réelle entre quelques points du labyrinthe) est statique car les murs ne changent pas.
L'interprétation de cette formule x + y
pourrait ressembler à ceci:
x
- dans tous les cas, vous devrez parcourir cette distance, au moins à la fin.y
- pendant que vous êtes parmi les deux fruits les plus éloignés, il est préférable de collecter la nourriture qui se trouve à proximité pour ne pas avoir à revenir en arrièreSi vous résolvez ce problème dans le cadre du projet de classe Berkeley AI, vous pouvez utiliser la fonction mazeDistance(pos1, pos2, gameState)
qui est déjà implémentée et qui utilise votre implémentation de bfs pour calculer la distance réelle. En outre, cette heuristique est admissible et cohérente , du moins pour leurs cas de test. À propos, avec cette heuristique, j'ai réussi à ne développer que 376 nœuds dans le labyrinthe trickySearch
name__.
J'ai trouvé la nourriture la plus proche (en utilisant manhattan) mais pour mon heuristique, j'ai utilisé la distance réelle entre ma position et la nourriture la plus proche. J'ai ajouté 1 à tous les points de nourriture ne partageant pas la ligne ou la colonne avec ma position ou point alimentaire le plus proche.
Parce que les points alimentaires qui partagent la position ou le rang de ma position ou de la position la plus proche de la nourriture seraient consommés lorsque je passerais de ma position à la nourriture la plus proche et que j'avais déjà compté le coût de ceci dans la distance réelle que j'ai mentionnée à la deuxième ligne.
Donc, en bref: heuristique = mazeDistance (ma position, la nourriture estimée la plus proche) + points laissés de côté
Cela était admissible et cohérent. Avec cela, je développais 5500 nœuds et obtenais un 5/4 sur FoodHeuristic. https://github.com/sukritiverma1996/Intro-to-AI -course
Je sais que c'est vieux, mais il y a probablement beaucoup d'autres personnes qui cherchent à résoudre ce problème (cela fait partie de la classe d'IA libre de Berkeley). Il y a beaucoup de suggestions de force brute, donc je vais contribuer un assez simple qui devient assez proche et EST ADMISSIBLE:
edit: L'affirmation précédente qu'il s'agit d'une heuristique admissible est fausse. Pardon!
Vous pouvez le forcer brutalement pour un petit nombre de fruits dans un labyrinthe de taille raisonnable.
O(n^2)
exécutions de A * pour obtenir toutes les distances par paire entre les noms n
fruits.)si vous souhaitez réduire le nombre de nœuds étendus et que le temps d'exécution vous importe peu, je vous recommande d'utiliser Minimum Spanning Tree, le coût d'Edge devrait être mazeDistance et utiliser une priorityQueue, chaque fois que vous ajoutez un nœud au nœud visité, recherchez le nœud le plus proche à celui qui vient d'être ajouté, puis l'ajoutant au nœud visité, jusqu'à ce que tout le nœud de la nourriture ait été ajouté au nœud visité. Si vous faites avec un problème de parcours IA, le nœud développé devrait être très faible.
En supposant que cela concerne le projet IA de Berkeley:
Dans le cas général, trouver le chemin le plus court qui visite chaque point est NP-difficile. Cependant, cela ne signifie pas que c'est difficile en pratique. Cela s'explique par le fait qu'il existe des algorithmes traitables à paramètres fixes et que les labyrinthes de Pacman fournis entrent dans le cas de graphes faciles à résoudre.
En particulier, pour toute largeur de branche donnée, le chemin le plus court peut être trouvé en polynôme temporel dans la taille du graphe (mais exponentiel dans la largeur de la branche du graphe) par une simple application de programmation dynamique. Cela ne viole pas la dureté NP car les graphes arbitraires peuvent avoir une grande largeur de branche, mais cela signifie que le problème peut être résolu efficacement si vous ne vous souciez que des graphes qui ont une faible largeur de branche. Les labyrinthes Pacman fournis ont une connectivité médiocre et une faible largeur de branche.
Pour plus de détails, voir cet article .
dans un état de jeu donné, disons que md(x)
est la distance entre manman et pacman au noeud x
, considérons minmd(X)
comme une fonction qui renvoie xmin
s.t md(xmin)<=md(x)
pour tout x
dans X
. Soit X
l'ensemble des aliments qu'il reste à pacman.
Que penser à ce sujet - si vous envisagez un assouplissement de votre monde pacman dans lequel il n'y a pas de murs, pacman ne peut pas marcher moins de md(xmin)
où xmin=minmd(X)
pour manger un fruit, puis s'il veut manger un autre fruit, il ne doit pas moins que md(xmin1)
où xmin1=minmd(X-{xmin})
et ainsi de suite. renvoyer la somme des mds pacman parcourus de xmin à xmin1 à xmin2 et ainsi de suite et comme il s’agit d’une solution optimale pour la relaxation, vous disposez d’une fonction admissible et cohérente heureuse!
Un autre point à considérer, c'est que vous pouvez même obtenir une meilleure heuristique si vous considérez les murs, c'est un problème beaucoup plus difficile, donc je n'y suis pas beaucoup entré, mais j'ai remarqué que si vous avez lié pacman dans un rectangle avec le prochain fruit optimal, il devra payer au moins 2 actions supplémentaires s'il y a une ligne de mur PLEIN verticale ou horizontale entre eux car il devra sortir du rectangle de délimitation et y entrer de nouveau en payant au moins 2 actions en le faisant pour chacun de ces murs. Cela peut être examiné plus avant et vous pouvez également trouver plus de fonctionnalités spéciales dans ce rectangle.