Ainda usando a mesma representação de grafos vista na aula anterior, vamos implementar no lab de hoje o algoritmo de busca de caminhos mais curtos de Dijkstra, visto em sala. Estão disponíveis os arquivos de entrada grafo5.dat e grafo9.dat e um teste em testecaminho.c.
A função menorescaminhos retorna um novo array contendo, para cada nó j do grafo, qual o último nó visitado no caminho mais curto encontrado de no_inicial até j. Repare que este último nó é o nó anterior ao nó j no caminho do no_inicial ao nó j. (A informação sobre o último visitado é suficiente para descobrir todo o caminho da origem até o nó!). O array retornado deve conter uma posição a mais do que o número de nós do grafo, com essa posição contendo o valor -1 (para marcar o final do array).
Para implementar menorescaminhos, utilize um array
auxiliar, visitados,
que indique que nós já foram visitados, e um outro array auxiliar,
caminhos, contendo o valor do menor caminho (distância)
encontrado até agora para cada nó do grafo. O array caminhos
também deve conter uma posição a mais (com o valor -1) para indicar o final do
array.
Inicialize as posições de caminhos com o valor INT_MAX
para todos os nós diferentes do nó inicial (que terá o valor 0).
Vamos fazer duas implementações:
O custo de encontrar o nó não visitado com menor distância à origem é linear e faz o algoritmo ficar O(n2). Uma forma de diminuir este custo é usar um heap de prioridades para determinar o nó com menor distância a cada passo.
Note que ainda serão necessários os arrays visitados e caminhos para as visitas aos vizinhos do nó corrente!
Sua implementação de heap pode ser bem baseada na que foi vista no
laboratório 9 (implementação para o lab 9 aqui),
mas teremos que fazer algumas modificações.
Em grafo_heap.c temos uma declaração da estrutura de heap e algumas funções já modificadas. Você pode consultar o código do
laboratório 9 e adaptá-lo para implementar/completar as funções que estão
faltando em grafo_heap.c
. Note que os parâmetros podem estar
um pouco diferentes da implementação usada no laboratório 9!
Para esta operação não ficar muito custosa, o heap agora contém um array chamado posnos, indexado pelo identificador do nó, que indica em que posição do heap o nó se encontra. (Se o nó não estiver mais no heap, coloque -1 nesta posição, por exemplo.) Todas as operações de inserção e correção do heap devem acertar posnos.
grafo.c
e grafo_heap.c
.