49 votes

La génération d'un tower defense labyrinthe (le plus long labyrinthe avec peu de murs) - quasi-optimale heuristique?

Dans un jeu de tower defense, vous avez une NxM grille avec un début, une fin, et un certain nombre de murs.

Image1

Les ennemis de prendre le chemin le plus court du début à la fin sans passer par les murs (ils ne sont généralement pas limités à la grille, mais pour simplifier, disons qu'ils sont. Dans les deux cas, ils ne peuvent pas se déplacer à travers la diagonale des "trous")

Image2

Le problème (pour cette question, au moins) est de placer jusqu'à K des murs supplémentaires afin de maximiser le chemin les ennemis ont à prendre. Par exemple, pour K=14

Image3

Mon intuition me dit que ce problème est NP-difficile si (comme je suis l'espoir de le faire) - on généraliser ce afin d'inclure les points de cheminement qui doit être visité avant de passer à la finition, et aussi, éventuellement, sans points de cheminement.

Mais, sont-il décent de l'heuristique là pour la quasi-optimale des solutions?


[Edit] j'ai posté une question connexe ici.

5voto

Saeed Amiri Points 16317

J'ai une approche gourmande et je pense que c'est quasi optimal (mais je ne pouvais pas trouver facteur de rapprochement). L'idée est simple, vous devez bloquer les cellules qui sont critiques à l'endroit de votre Labyrinthe, ces lieux sont, normalement, mesure de la connectivité de votre labyrinthe. Cette connectivité peut être considéré comme le sommet de la connectivité et de la motivation est de trouver le minimum vertex couper dans tout le chemin du début et de la finale (s,f). Après cela, vous pouvez supprimer certaines cellules critiques.

Avant de commencer l'algorithme, prendre le double de votre labyrinthe de la grille, pour trouver le correspondant de graphique. Maintenant, trouver le minimum (s,f) vertex couper sur votre graphique, après cela, examiner chaque sommet de ce couper, retirer le sommet de telle sorte que son retrait entraîne sur le chemin de longueur maximale entre les s,f ou c'est dans le minimum de chemin de s à f. de nouveau trouver le minimum (s,f) vertex couper, ... et ceci pour éliminer k des nœuds.

Le problème se produit lorsque vous souhaitez supprimer un nœud qui provoque à couper entre les s,f, pour empêcher cela, vous pouvez le poids de coupe nœud le plus haut possible, signifie d'abord calculer le minimum (s,f) couper, si on coupe le résultat est juste un nœud, faire pondérée et définir son poids à n^3, maintenant de nouveau calculer le minimum de sf couper sûr de coupe simple nœud dans le calcul précédent n'appartient pas à une nouvelle coupe. Mais s'il y a un chemin entre s,f (après quelques itérations) vous ne pouvez pas l'améliorer. Dans ce cas, vous pouvez utiliser des algorithmes cupides, comme le retrait de nœud à partir d'une partie d'un plus court chemin de s à f qui n'appartient à aucune coupe. après que vous avez de nouveau de transaction avec un minimum de vertex coupe.

L'algorithme temps d'exécution de chaque étape est:

min-cut + path finding for all nodes in min-cut
O(min cut) + O(n^2)*O(number of nodes in min-cut)

Et parce que le nombre de nœuds dans min de coupe ne peut pas être supérieure à O(n^2) très très mauvaise situation pour cet algorithme est O(k*n^4), mais normalement, il ne prend pas plus de O(k*n^3), parce que normalement min-cut algorithme domine la découverte de parcours, aussi normalement découverte de parcours ne prend O(n^2).

Je pense également que cette gourmande choix peut être une bonne motivation pour le recuit simulé, les algorithmes.


P. S: minimum vertex coupe est semblable à minimum de bord de coupe, et approche similaire comme max-flow/min-cut peut être appliqué sur un minimum sommet de coupe, il suffit de supposer chaque sommet comme deux vertex, une Vi, on Vo, moyens d'entrée et de sortie, convertir graphe non-dirigé à réalisé l'un n'est pas difficile.

5voto

Antti Huima Points 15465

il peut être facilement illustré (la preuve laissé comme exercice au lecteur) que c'est assez à la recherche de la solution de manière à ce que chacune des K blocus est mis sur le minimum de longueur de l'itinéraire. Notez que s'il y a plusieurs minimale de la longueur des routes, alors tous d'entre eux doivent être considérés. La raison en est que si vous ne mettez pas des autres barrages sur le minimum de longueur de la route alors qu'il ne change pas; par conséquent, vous pouvez mettre le premier disponible blocus sur elle immédiatement au cours de la recherche. Cela accélère même une recherche par force brute.

Mais il y a plus d'optimisations. Vous pouvez également décider que vous mettez la prochaine blocus de sorte qu'il devient le PREMIER blocus sur le minimum de longueur de l'itinéraire, c'est à dire vous de travail, de sorte que si vous placez le blocus de la 10e place sur la route, puis vous cochez les cases 1..9 "ouvert en permanence" jusqu'à ce que vous revenir. Cela permet d'économiser encore un nombre exponentiel de carrés à la recherche de cours de mandature de recherche.

Vous pouvez ensuite appliquer des heuristiques pour réduire l'espace de recherche ou de réorganiser, par exemple, essayez d'abord de ceux blocus de stages que l'augmentation de la longueur de l'actuel minimum de longueur de l'itinéraire le plus. Vous pouvez ensuite exécuter l'algorithme de backtracking pour une quantité limitée de temps réel et de choisir la meilleure solution trouvée jusqu'à présent.

4voto

MrGomez Points 20526

Je crois que nous pouvons réduire le contenu de l'maximale problème collecteur de booléenne satisifiability et de montrer la NP-complétude à travers toute dépendance sur ce subproblem. De ce fait, les algorithmes spinning_plate fournis sont raisonnables, comme des heuristiques, precomputing et d'apprentissage de la machine est raisonnable, et l'astuce consiste à trouver la meilleure solution heuristique si nous voulons gaffe en avant ici.

Considérons un conseil comme suit:

..S........
#.#..#..###
...........
...........
..........F

Cela a de nombreux problèmes qui, à cause gourmand et porte-lié solutions à l'échec. Si nous regardons cette deuxième ligne:

#.#..#..###

Nos portes logiques sont, en base 0 tableau 2D commandés [row][column]:

[1][4], [1][5], [1][6], [1][7], [1][8]

Nous pouvons nous rendre à nouveau présent comme une équation à satisfaire le bloc:

if ([1][9] AND ([1][10] AND [1][11]) AND ([1][12] AND [1][13]):
    traversal_cost = INFINITY; longest = False # Infinity does not qualify

À l'exception de l'infini en un unsatisfiable cas, nous revenir en arrière et rerender ce que:

if ([1][14] AND ([1][15] AND [1][16]) AND [1][17]:
    traversal_cost = 6; longest = True

Et notre caché boolean relation qui se situe parmi l'ensemble de ces portes. Vous pouvez également montrer que géométrique épreuves peuvent pas fractalize de manière récursive, parce que nous pouvons toujours créer un mur qui est exactement N-1 de la largeur ou de la hauteur de long, ce qui représente une partie essentielle de la solution dans tous les cas (donc, de division et de conquête ne sera pas vous aider).

En outre, en raison des perturbations à travers les différentes lignes sont importantes:

..S........
#.#........
...#..#....
.......#..#
..........F

On peut montrer que, sans un ensemble complet de formalisation géométrique des identités, la recherche de l'espace se réduit à N-SAT.

Par extension, on peut également montrer que c'est trivial de vérifier et de non-polynomial pour résoudre le nombre de portes d'approche de l'infini. Sans surprise, c'est pourquoi les jeux de tower defense restent tellement amusant pour les humains à jouer. De toute évidence, une preuve rigoureuse est souhaitable, mais c'est un squelette de départ.

Notez que vous pouvez réduire considérablement le n stage de n-choisissez-k relation. Parce que nous pouvons de manière récursive montrent que chaque perturbation doit se trouver sur le chemin critique, et parce que le chemin critique est toujours calculable en O(V+E) temps (avec quelques optimisations pour accélérer les choses pour chaque perturbation), vous pouvez réduire considérablement votre espace de recherche à un coût d'une largeur de recherche pour chaque tour supplémentaire ajouté à la carte.


Parce que nous pouvons raisonnablement supposer O(n^k) pour une solution déterministe, un heuristical approche est raisonnable. Mon conseil donc se situe quelque part entre spinning_plate réponse et Soravux de l', avec un oeil vers les techniques d'apprentissage automatique applicable au problème.

Le 0e solution: Utiliser un tolérable, mais sous-optimale de l'IA, dans lequel spinning_plate fourni deux algorithmes utilisables. En effet, ces approximative de combien de naïfs, les joueurs de l'approche du jeu, et cela devrait être suffisant pour un simple jeu, mais avec un degré élevé d'exploitabilité.

Le 1er ordre de la solution: Utiliser une base de données. Compte tenu de la formulation du problème, vous n'avez pas assez démontré la nécessité de calculer la solution optimale à la volée. Par conséquent, si nous relaxer la contrainte de se rapprocher d'un plateau aléatoire en l'absence d'informations, il suffit de précalculer l'optimum pour tous K tolérable pour chaque conseil. Évidemment, cela ne fonctionne que pour un petit nombre de planches: avec V! potentiel du conseil des états pour chaque configuration, nous ne pouvons pas raisonnablement à précalculer tous les optimums comme V devient très grand.

La 2e ordre solution: Utiliser une machine-étape d'apprentissage. La promotion de chaque étape que vous fermez un écart qui en résulte est très élevé coût de traversée, l'exécution jusqu'à ce que votre algorithme converge ou pas plus de solution optimale peut être trouvée que gourmand. Une pléthore d'algorithmes sont applicables ici, donc je vous recommande de chasser les classiques et la littérature pour choisir le bon celui qui fonctionne dans les limites de votre programme.

La meilleure heuristique peut être une simple carte de la chaleur générée par un localement l'état courant, profondeur de récursivité-première traversée, le tri des résultats par la plus à la moins fréquemment parcourus après l'O(V^2) de la traversée. Procédure par le biais de cette sortie goulûment permet d'identifier tous les goulots d'étranglement, et le faire sans faire le cheminement de l'impossible c'est tout à fait possible (la vérification est O(V+E)).

Mettre tous ensemble, j'essaierais d'un croisement de ces approches, en combinant la carte de la chaleur et du chemin critique des identités. Je suppose que il y a assez de place ici pour arriver à une bonne, fonctionnelle géométrique la preuve, qui satisfait toutes les contraintes du problème.

3voto

dfb Points 8807

Au risque d'énoncer une évidence, voici un algorithme

1) Find the shortest path
2) Test blocking everything node on that path and see which one results in the longest path
3) Repeat K times

Naïvement, cela va prendre O(K*(V+ E log E)^2) mais vous pouvez avec un peu de travail à améliorer 2 que de recalculer des chemins partiels.

Comme vous le mentionnez, simplement en essayant de briser le chemin est difficile, car si la plupart des sauts de simplement ajouter une longueur de 1 (ou 2), il est difficile de trouver les points d'étranglement que conduire à de gros gains.

Si vous prenez le minimum vertex couper entre le début et la fin, vous trouverez les points d'étranglement pour l'ensemble du graphique. Un algorithme est ce

1) Find the shortest path 
2) Find the min-cut of the whole graph
3) Find the maximal contiguous node set that intersects one point on the path, block those.
4) Wash, rinse, repeat

3) c'est la grosse partie et pourquoi cet algorithme peut mal fonctionner, trop. Vous pouvez également essayer

  • le plus petit ensemble de nœuds qui se connecte avec d'autres blocs existants.
  • trouver tous les groupements de contiguë verticies dans le sommet de coupe, de tester chacune d'elles pour le plus long chemin a la le premier algorithme

La dernière, ce qui pourrait être le plus prometteur

Si vous trouvez un min sommet de coupe sur l'ensemble du graphique, vous allez trouver les points d'étranglement pour l'ensemble du graphique.

1voto

Vladimir Sinenko Points 2046

Voici une pensée. Dans votre grille, groupe des murs adjacents dans les îles et traiter chaque île comme un graphe nœud. La Distance entre les nœuds est le nombre minimal de murs qui est nécessaire pour se connecter (pour bloquer l'ennemi).

Dans ce cas, vous pouvez commencez à maximiser la longueur de chemin d'accès en bloquant les plus bas prix des arcs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X