Algoritmo Dijkstra vs amplitude primeira pesquisa pelo caminho mais curto no gráfico

11

Eu fiz essa pergunta no StackOverflow. Me pediram para morar aqui. Então aqui está:

Preciso de alguns esclarecimentos e informações sobre o algoritmo de Dijkstra versus a primeira pesquisa de largura em gráficos direcionados, se estiverem corretos.

O algoritmo de Dijkstra encontra o caminho mais curto de Nó Apara Nó Fem um gráfico ponderado, independentemente de haver ou não um ciclo (desde que não haja pesos negativos)

mas para isso, todos os caminhos de Apara todos os outros nós no gráfico são calculados e pegamos o caminho de Apara Finvertendo as seqüências de nós em prev.

BFS: localiza o caminho mais curto de nó Apara nó Fem um gráfico não ponderado, mas se falhar se um ciclo for detectado.

no entanto, o BFS apenas calcula o caminho do nó A para o nó F e não necessariamente todo o caminho do nó A. Se o nó F for alcançado mais cedo, ele retornará o caminho.

gráfico de exemplo

user1988876
fonte

Respostas:

17
  1. O BFS não falha se um ciclo for detectado. http://en.wikipedia.org/wiki/Breadth-first_search

  2. O Dijkstra's também não calcula todos os caminhos de A a F. Para quando encontra o caminho mais curto de A a F.

  3. Em um gráfico não ponderado, você pode usar o BFS para procurar também o caminho mais curto de A para todos os outros nós na mesma execução! (apenas não faça isso parar assim que encontrar F)

  4. Você pode usar um algoritmo do tipo BFS para encontrar o caminho mais curto se souber que todos os comprimentos são números inteiros menores que um número 'pequeno' k no tempo O (k (v + e)) substituindo todas as arestas (u, w) de comprimento n com um caminho de n-1 nós entre u e w, o comprimento de cada aresta no caminho é 1.

Espero que isto ajude.

Aditya
fonte
você pode elaborar o ponto 4
user1988876
@ User1988876: Como um comentário geral, se você estiver interessado na resposta de Aditya, eu recomendo fortemente que você vote novamente na resposta dele (como eu realmente fiz). Geralmente, é uma boa ideia em um site como esse.
Carlos Linares López
11
Desculpe pelo atraso na resposta. Pegue qualquer extremidade de um gráfico cujos pesos sejam pequenos inteiros positivos (menos de k) (u, v) de peso, por exemplo, 5. Substitua a borda uv por um caminho da seguinte maneira u-uv1-uv2-uv3-uv4-v ( uv1 a uv5 são novos nós) com o peso de cada aresta no meio como 1. Faça isso para cada aresta. Agora que todos os pesos do gráfico resultante são 1, você pode pensar nele como um gráfico não direcionado com <= k | v | vértices e <= k | e | Use o BFS para encontrar o caminho mais curto. Em geral, isso não é melhor que o Dijkstra, pois os pesos podem ser arbitrariamente grandes e não integrais em um gráfico.
Aditya
6

Embora a resposta de Aditya seja boa, gostaria de esclarecer alguns pontos.

Primeira pesquisa de largura

A Pesquisa por Largura (BFS) apenas usa uma fila para enviar e enviar nós de / para. Isso significa que ele visita os nós na ordem de sua profundidade.

Se acontecer que o custo de todos os operadores é o mesmo (para que sejam considerados iguais a 1), é garantido que você encontrará uma solução ideal.

Como conseqüência, observe o seguinte:

  1. Apenas enumera caminhos até que a solução seja encontrada. Não se pode dizer que esse algoritmo calcula o caminho mais curto entre o nó de origem e o nó de objetivo (ponto final!). Ele apenas calcula a distância de todos os caminhos que encontra no caminho em direção à meta. Em outras palavras, o que for dito sobre o caminho que ele encontra para o nó de objetivo pode ser igualmente dito sobre qualquer outro caminho descoberto por ele.

  2. Nada impede que o BFS seja aplicado a gráficos com custos arbitrários. O único ponto a ser lembrado é que o algoritmo preserva a integridade (para que seja garantido encontrar uma solução), embora a admissibilidade seja perdida (ou seja, não garante que a solução seja ótima).

  3. Originalmente, o BFS não considerava uma lista FECHADA para armazenar todos os nós expandidos, de modo que você está certo quando diz que pode cair em um ciclo. No entanto, como ele armazena explicitamente todos os nós na memória e a camada com maior demanda de memória é sempre a mais recente, o BFS geralmente é estendido com uma lista FECHADA que armazena todos os nós expandidos anteriormente. Se uma transposição for encontrada antes da expansão de um nó, ela poderá ser ignorada com segurança.

Algoritmo de Dijkstra

De fato, se você adicionar uma lista CLOSED ao BFS, conforme sugerido no ponto 3 acima, e também classificar os nós na pilha (a chamada lista OPEN) em ordem crescente de (ou seja, o custo do caminho a partir do start state para ), então você tem o algoritmo de Dijkstra (bem, há também outra diferença muito importante, enquanto o BFS para ao gerar o nó de objetivo, o Dijkstra para ao expandi- lo).g(n)n

Assim:

  1. Novamente, esse algoritmo apenas enumera caminhos até que a solução seja encontrada. Não é verdade que ele visite todos os nós no espaço de estados e, de fato, o algoritmo de Dijkstra é conhecido por estar completo (isto é, garante que uma solução seja encontrada, se houver), mesmo que o gráfico subjacente seja infinito.

  2. Você pode aplicar com segurança o algoritmo de Dijkstra quando as operações tiverem custos arbitrários. De fato, essa é a razão pela qual você substituiu a fila por um heap em que os nós são inseridos em ordem crescente de custo.

  3. Edgar Dijkstra originalmente considerou usar uma lista FECHADA (você pode conferir o artigo dele, é apenas algumas páginas e é muito fácil de ler) para que os ciclos sejam considerados adequadamente.

Espero que isso ajude, talvez seja necessária uma explicação mais detalhada desses algoritmos. Se sim, não hesite em pedir por eles

Felicidades,

Carlos Linares López
fonte
11
O BFS usa uma fila, não uma pilha.
Nbro 22/07
@ nbro: Verdade! Obrigado por apontar isso! Eu editei e modifiquei minha resposta de acordo!
Carlos Linares López