Je ne sais pas si je peux continuer ici …
Mon code avait effectivement des bugs:
- Je ne transmettais pas la valeur cumulée au sommet suivant.
- je faisait le parcours à partir du début pour trouver le chemin le plus court. Il faut le faire à partir de la fin vers le début.
Ensuite, il était inutile de retourner les longueurs minimales, puisqu’on retrouve dans acess
cette valeur pour le sommet de sortie.
Pour des graphes orientés, je suppose qu’il ne faut pas enregistrer la distance dans les deux directions. Mais je devrais accumuler dans acces
le sommet associé à la dernière valeur qu’on y a placée.
J’appelle toujours ma fonction dijkstra même si ce n’en est pas un. Voici mon nouveau code:
def dijkstra(graphe, acces, cumulatif, sommet, sortie):
if sommet == sortie: return
for noeud, distance in graphe[sommet].items():
if cumulatif + distance < acces[noeud]:
acces[noeud] = cumulatif + distance
dijkstra(graphe, acces, cumulatif+distance, noeud, sortie)
graphe = {}
acces = {}
while True:
sommet1, sommet2, distance = input("> ").split()
distance = int(distance)
if distance <= 0: break
acces[sommet1] =float('inf')
acces[sommet2] = float('inf')
if sommet1 not in graphe.keys():
graphe[sommet1] = {}
graphe[sommet1][sommet2] = distance
if sommet2 not in graphe.keys():
graphe[sommet2] = {}
graphe[sommet2][sommet1] = distance
acces[sommet1] = 0
dijkstra(graphe, acces, 0, sommet1, sommet2)
chemin = [sommet2]
minimum = acces[sommet2]
if minimum < float('inf'):
print("La longueur du chemin minimum est", minimum)
while sommet1 != sommet2:
for sommet, distance in graphe[sommet2].items():
if minimum - distance == acces[sommet]:
chemin.append(sommet)
sommet2 = sommet
minimum -= distance
break
chemin.reverse()
print(chemin)
else:
print(f"Pas de chemin entre {sommet1} et {sommet2}")
Il semble que je ne comprenne pas bien l’algo de Dijkstra. Pour le petit graphe suivant:
a b 4
a c 5
b c 2
b d 9
c d 5
a d 0
La dernière ligne démarre l’algo et indique que 'a' est le début et 'd' est la fin.
Selon ma compréhension de l’algo, il ne devrait pas regarder les suivants de 'c' car c’est la branche 'a’->’b' qui est minimale.
Et pourtant, il faut passer par 'c' pour un chemin minimal.