Eu estava olhando o que os caras da competição Mario AI estavam fazendo e alguns deles criaram alguns bots Mario muito legais, utilizando o algoritmo de localização A * (A-Star).
( Vídeo de Mario A * Bot Em Ação )
Minha pergunta é: como o A-Star se compara ao Dijkstra? Olhando por cima deles, eles parecem semelhantes.
Por que alguém usaria um sobre o outro? Especialmente no contexto de participar de jogos?
Respostas:
Dijkstra é um caso especial para A * (quando a heurística é zero).
fonte
Dijkstra:
Tem uma função de custo, que é o valor custo real da origem para cada nó:
f(x)=g(x)
.Ele encontra o caminho mais curto da origem para todos os outros nós, considerando apenas o custo real.
Uma pesquisa:
Tem duas funções de custo.
g(x)
: o mesmo que Dijkstra. O custo real para alcançar um nóx
.h(x)
: custo aproximado do nóx
ao nó da meta. É uma função heurística. Essa função heurística nunca deve superestimar o custo. Isso significa que o custo real para alcançar o nó da meta a partir do nóx
deve ser maior ou igualh(x)
. É chamado de heurística admissível.O custo total de cada nó é calculado por
f(x)=g(x)+h(x)
Uma pesquisa * expande apenas um nó se parecer promissor. Ele se concentra apenas em alcançar o nó do objetivo a partir do nó atual, e não em todos os outros nós. É ideal se a função heurística for admissível.
Portanto, se sua função heurística for boa para aproximar o custo futuro, será necessário explorar muito menos nós que o Dijkstra.
fonte
O que o pôster anterior disse, mais porque o Dijkstra não tem heurística e a cada passo escolhe arestas com o menor custo, ele tende a "cobrir" mais do seu gráfico. Por isso, o Dijkstra poderia ser mais útil que o A *. Um bom exemplo é quando você tem vários nós de destino candidatos, mas não sabe qual deles é o mais próximo (no caso A *, você teria que executá-lo várias vezes: uma vez para cada nó candidato).
fonte
O algoritmo de Dijkstra nunca seria usado para encontrar caminhos. Usar A * é um acéfalo se você conseguir uma heurística decente (geralmente fácil para jogos, especialmente em mundos 2D). Dependendo do espaço de pesquisa, o Aprofundamento Iterativo A * às vezes é preferível porque utiliza menos memória.
fonte
Dijkstra é um caso especial para A *.
Dijkstra encontra os custos mínimos do nó inicial para todos os outros. A * encontra o custo mínimo do nó inicial ao nó do objetivo.
O algoritmo de Dijkstra nunca seria usado para encontrar caminhos. O uso de A * pode gerar uma heurística decente. Dependendo do espaço de pesquisa, é preferível o iterativo A *, pois utiliza menos memória.
O código para o algoritmo de Dijkstra é:
O código para o algoritmo A * é:
fonte
Dijkstra encontra os custos mínimos do nó inicial para todos os outros. A * encontra o custo mínimo do nó inicial ao nó do objetivo.
Portanto, parece que o Dijkstra seria menos eficiente quando tudo o que você precisa é a distância mínima de um nó para outro.
fonte
Você pode considerar A * uma versão guiada do Dijkstra. Significado, em vez de explorar todos os nós, você usará uma heurística para escolher uma direção.
Em termos mais concretos, se você estiver implementando os algoritmos com uma fila de prioridade, a prioridade do nó que você está visitando será uma função do custo (nós anteriores custa + custo para chegar aqui) e a estimativa heurística daqui para o objetivo. Enquanto estiver em Dijkstra, a prioridade é influenciada apenas pelo custo real dos nós. Em ambos os casos, o critério de parada está atingindo a meta.
fonte
O algoritmo de Dijkstra encontra definitivamente o caminho mais curto. Por outro lado, A * depende da heurística. Por esse motivo, A * é mais rápido que o algoritmo de Dijkstra e fornecerá bons resultados se você tiver uma boa heurística.
fonte
Se você olhar para o psuedocode para Astar:
Visto que, se você olhar o mesmo para Dijkstra :
Portanto, o ponto é que o Astar não avaliará um nó mais de uma vez,
pois acredita que olhar um nó uma vez é suficiente, devido
às suas heurísticas.
OTOH, o algoritmo de Dijkstra não tem vergonha de se corrigir, caso
um nó apareça novamente.
O que deve tornar o Astar mais rápido e mais adequado para encontrar o caminho.
fonte
Em A *, para cada nó, você verifica as conexões de saída.
Para cada novo nó, você calcula o menor custo até agora (csf), dependendo dos pesos das conexões com esse nó e dos custos que você tinha para alcançar o nó anterior.
Além disso, você estima o custo do novo nó para o nó de destino e o adiciona ao csf. Agora você tem o custo total estimado (etc). (etc = csf + distância estimada para o destino) Em seguida, escolha entre os novos nós aquele com o menor, etc.
Faça o mesmo que antes, até que um dos novos nós seja o destino.
Dijkstra funciona quase da mesma forma. Exceto que a distância estimada para o destino é sempre 0 e o algoritmo para primeiro quando o destino não é apenas um dos novos nós , mas também aquele com o csf mais baixo.
A * é geralmente mais rápido que dijstra, embora nem sempre seja esse o caso. Nos videogames, você costuma usar a abordagem "perto o suficiente para um jogo". Portanto, o caminho ótimo "próximo o suficiente" de A * geralmente é suficiente.
fonte
O algoritmo de Dijkstra é definitivamente completo e ideal para você sempre encontrar o caminho mais curto. No entanto, costuma demorar mais, pois é usado principalmente para detectar vários nós de meta.
A* search
por outro lado, importa com valores heurísticos, que você pode definir para atingir seu objetivo mais próximo, como a distância de manhattan em direção ao objetivo. Pode ser ideal ou completo, dependendo de fatores heurísticos. é definitivamente mais rápido se você tiver um único nó de objetivo.fonte