EDIT 2:Il semble que ce n'est pas de CLRS (je suppose que c'était parce qu'il a suivi le même format de code CLRS qui nous a été donné dans ce Algos et DS cours). Néanmoins, dans ce cours, nous avons donné ce code comme étant "Algorithme de Dijkstra".Dijkstra avec des bords négatifs. Je ne comprends pas les exemples, ils fonctionnent selon le pseudocode CLRS
J'ai lu Why doesn't Dijkstra's algorithm work for negative weight edges? et Negative weights using Dijkstra's Algorithm (la seconde est spécifique à l'algorithme de l'OP je pense). En regardant le pseudo-code de CLRS ("Introduction aux algorithmes"), je ne comprends pas pourquoi Dijkstra ne fonctionnerait pas sur ces exemples de graphes avec des bords négatifs.
Dans le pseudo-code (ci-dessous), Insert
nœuds de retour sur le tas si la nouvelle distance à eux est plus courte que la distance précédente à eux, donc il me semble que les distances seraient finalement mises à jour.
Par exemple:
La revendication est que (A, C) est mis à 1 et jamais mis à jour à la distance correcte -2. Mais le pseudocode de CLRS dit que nous plaçons d'abord C et B sur le tas avec les distances 1 et 2 respectivement; alors nous sautons C, ne voyons pas d'arêtes sortantes; alors nous sautons B, regardons le bord (B, C), voyons que Dist[C] > Dist[B] + w(B,C)
, mettez Dist[C]
à -2, remettez C sur le tas, ne voyez pas de bords sortants et nous avons terminé. Alors ça a bien marché.
Même chose pour l'exemple dans la première réponse à cette question: Negative weights using Dijkstra's Algorithm
L'auteur de la réponse affirme que la distance C ne sera pas mis à jour -200, mais selon ce pseudo-code qui est pas vrai, puisque nous mettrions B revenir sur le tas, puis calculer la distance la plus courte correcte à C.
(pseudocode de CLRS)
Dijkstra(G(V, E, ω), s ∈ V)
for v in V do
dist[v] ← ∞
prev[v] ← nil
end for
dist[s] = 0
H←{(s,0)}
while H̸=∅ do
v ← DeleteMin(H)
for (v, w) ∈ E do
if dist[w] > dist[v] + ω(v, w) then
dist[w] ← dist[v] + ω(v, w)
prev[w] ← v
Insert((w, dist[w]), H)
end if
end for
end while
EDIT: Je comprends que nous supposons qu'une fois qu'un noeud est sorti du tas, la distance la plus courte a été trouvée; mais encore, il semble (d'après le CLRS) que nous replaçons les nœuds sur le heap si la distance est plus courte que précédemment calculée, donc à la fin quand l'algorithme est fini, nous devrions avoir la bonne distance la plus courte.
Le pseudo-code que vous avez présenté ici ne semble pas correspondre à la deuxième édition de CLRS ou à la troisième édition de CLRS que je viens de retirer de mon étagère. Êtes-vous sûr que c'est le bon pseudocode? L'implémentation Dijkstra "traditionnelle" ne réinsère rien dans sa file d'attente prioritaire, utilisant plutôt une opération de réduction de clé pour réduire les priorités existantes. (Aussi, je suis l'auteur de la réponse à cette question liée que vous avez mentionnée, et je serais heureux d'en discuter!) – templatetypedef
@templatetypedef, Ce serait génial merci! Comment initiez-vous le chat? –
Cela ressemble plus à Bellman-Ford avec une file d'attente (prioritaire), qui peut réinsérer des nœuds, et fonctionne avec des bords négatifs. – IVlad