Ai-je raison sur les différences entre les algorithmes de Floyd-Warshall, Dijkstra et Bellman-Ford?

j'ai étudié les trois et je déclare mes déductions d'eux ci-dessous. Est-ce que quelqu'un pourrait me dire si je les ai assez bien compris ou pas? Remercier.

  1. l'algorithme de Dijkstra n'est utilisé que lorsque vous avez une seule source et que vous voulez connaître le plus petit chemin d'un noeud à l'autre, mais qu'il échoue dans les cas comme

  2. l'algorithme de Floyd-Warshall est utilisé lorsque l'un des noeuds peut être une source, donc vous vouloir la distance la plus courte pour atteindre n'importe quel noeud de destination de n'importe quel noeud source. Cela n'échoue que lorsqu'il y a des cycles négatifs

(ce qui est le plus important. Je veux dire, c'est celle que je suis moins sûr:)

3.Bellman-Ford est utilisé comme Dijkstra, quand il n'y a qu'une source. Cela peut gérer les poids négatifs et son fonctionnement est le même que celui de Floyd-Warshall sauf pour une source, non?

Si vous besoin d'avoir un coup d'oeil, les algorithmes correspondants sont (avec l'aimable autorisation de Wikipedia):

Bellman-Ford:

 procedure BellmanFord(list vertices, list edges, vertex source)
   // This implementation takes in a graph, represented as lists of vertices
   // and edges, and modifies the vertices so that their distance and
   // predecessor attributes store the shortest paths.

   // Step 1: initialize graph
   for each vertex v in vertices:
       if v is source then v.distance := 0
       else v.distance := infinity
       v.predecessor := null

   // Step 2: relax edges repeatedly
   for i from 1 to size(vertices)-1:
       for each edge uv in edges: // uv is the edge from u to v
           u := uv.source
           v := uv.destination
           if u.distance + uv.weight < v.distance:
               v.distance := u.distance + uv.weight
               v.predecessor := u

   // Step 3: check for negative-weight cycles
   for each edge uv in edges:
       u := uv.source
       v := uv.destination
       if u.distance + uv.weight < v.distance:
           error "Graph contains a negative-weight cycle"

Dijkstra:

 1  function Dijkstra(Graph, source):
 2      for each vertex v in Graph:                                // Initializations
 3          dist[v] := infinity ;                                  // Unknown distance function from 
 4                                                                 // source to v
 5          previous[v] := undefined ;                             // Previous node in optimal path
 6                                                                 // from source
 7      
 8      dist[source] := 0 ;                                        // Distance from source to source
 9      Q := the set of all nodes in Graph ;                       // All nodes in the graph are
10                                                                 // unoptimized - thus are in Q
11      while Q is not empty:                                      // The main loop
12          u := vertex in Q with smallest distance in dist[] ;    // Start node in first case
13          if dist[u] = infinity:
14              break ;                                            // all remaining vertices are
15                                                                 // inaccessible from source
16          
17          remove u from Q ;
18          for each neighbor v of u:                              // where v has not yet been 
19                                                                                 removed from Q.
20              alt := dist[u] + dist_between(u, v) ;
21              if alt < dist[v]:                                  // Relax (u,v,a)
22                  dist[v] := alt ;
23                  previous[v] := u ;
24                  decrease-key v in Q;                           // Reorder v in the Queue
25      return dist;

Floyd-Warshall:

 1 /* Assume a function edgeCost(i,j) which returns the cost of the edge from i to j
 2    (infinity if there is none).
 3    Also assume that n is the number of vertices and edgeCost(i,i) = 0
 4 */
 5
 6 int path[][];
 7 /* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path
 8    from i to j using intermediate vertices (1..k−1).  Each path[i][j] is initialized to
 9    edgeCost(i,j).
10 */
11
12 procedure FloydWarshall ()
13    for k := 1 to n
14       for i := 1 to n
15          for j := 1 to n
16             path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );
22
demandé sur GrowinMan 2012-07-29 01:03:18

2 réponses

vous avez raison sur les deux premières questions, et sur le but de Floyd-Warshall (trouver les chemins Les plus courts entre toutes les paires), mais pas sur la relation entre Bellman-Ford et Floyd-Warshall: les deux algorithmes utilisent la programmation dynamique pour trouver le chemin le plus court, mais FW n'est pas la même chose qu'exécuter BF de chaque noeud de départ à chaque autre noeud.

en BF, la question Est: Quel est le chemin le plus court entre la source et la cible en utilisant AU PLUS k pas, et le fonctionnement le temps est O (E V). Si nous devions l'exécuter à chaque autre noeud, le temps d'exécution serait O (EV^2).

en FW, la question Est: Quel est le chemin le plus court de i à j à k, pour tous les noeuds i,j,K. Ceci conduit à un temps de fonctionnement O(v^3) - meilleur que BF pour chaque noeud de départ (par un facteur allant jusqu'à |V| pour les graphes denses).

une note de plus sur les cycles / poids négatifs: Dijkstra peut tout simplement ne pas donner les bons résultats. BF et FW ne vont pas échouer - ils le feront correctement précisez qu'il n'y a pas de trajectoire de poids minimum, puisque le poids négatif est illimité.

19
répondu Guy Adini 2017-01-02 23:09:28

source Unique des chemins les plus courts:

algorithme de Dijkstra - aucun poids négatif autorisé-O(E+Vlg (V))

algorithme de Bellman ford-poids négatif autorisé. Mais si un cycle négatif est présent, Bellman ford détectera le cycle-o (VE)

Graphe Dirigé Acyclique - comme le nom l'indique, il fonctionne uniquement pour les DAG - O(V+E)

toutes les paires chemins Les plus courts:

algorithme de Dijkstra - pas de poids négatif autorisé-o (VE + V ^ 2lg (V))--1-->

algorithme de Bellman ford-O (V^2E)

de la Matrice de la chaîne de multiplication de la méthode de la complexité même que Bellman ford algorithme

algorithme de Floyd Warshall-utilise la méthode de programmation dynamique-la complexité est O (V^3)

8
répondu arunmoezhi 2012-07-29 10:05:36