简体   繁体   中英

Dijkstra's algorithm in C++

I'm required to implement the Dijkstra's algorithm via ADT graph using the adjacency matrix representation for finding a shortest path by enhancing the pseudo code below using either C/C++ language.

procedure Dijkstra(G, w, r, Parent[0:n-1], Dist)
  for v← 0 to n-1 do
    Dist[v] ← ∞
    InTheTree[v] ← .false.
  endfor
  Parent[r] ←-1
  Dist[r] ←0
  for Stage ←1 to n-1 do 
    Select vertex u that minimises Dist[u] over all u such that InTheTree[u] = .false. 
    InTheTree[u] = .true.                                       // add u to T
    for each vertex v such that uv ∈ E do             // update Dist[v] and 
      if .not. InTheTree[v]  then                // Parent[v] arrays
        if Dist[u] + w(uv) < Dist[v]
          Dist[v] = Dist[u] + w(uv)
          Nearest[v] ←w(uv) 
          Parent[v] ← u
        endif
      endif
    endfor
  endfor
end Dijkstra

Here is my solution of code which is being coded in C++. My lecturer claim that the code does not meet the pseudocode requirements and I'm not sure where it went wrong so can anyone help me to spot what doesn't match between the code and the pseudocode?

#include <stdio.h>
#include <limits.h>
#define N 9

int minDistance(int dist[], bool sptSet[])
{
   int min = INT_MAX, min_index;

   for (int n = 0; n < N; n++)
     if (sptSet[v] == false && dist[n] <= min)
         min = dist[n], min_index = n;

   return min_index;
}
int printSolution(int dist[], int v)
{
   printf("Vertex   Distance from Source\n");
   for (int i = 0; i < N; i++)
      printf("%d \t\t %d\n", i, dist[i]);
}
void dijkstra(int graph[N][N], int src)
{
     int dist[N];     

     bool sptSet[N];                         

     for (int i = 0; i < N; i++) {
        dist[i] = INT_MAX;
        sptSet[i] = false;
     }

     dist[src] = 0;


     for (int count = 0; count < N-1; count++)
     {

       int u = minDistance(dist, sptSet);
            sptSet[u] = true;
       for (int n = 0; n < N; n++)
         if (!sptSet[n] && graph[u][n] && dist[u] != INT_MAX 
                                       && dist[u]+graph[u][n] < dist[n])
            dist[n] = dist[u] + graph[u][n];
     }
     printSolution(dist, N);
}

int main()
{
   int graph[N][N] = {{0, 4, 0, 0, 0, 0, 0, 8, 0},
                      {4, 0, 8, 0, 0, 0, 0, 11, 0},
                      {0, 8, 0, 7, 0, 4, 0, 0, 2},
                      {0, 0, 7, 0, 9, 14, 0, 0, 0},
                      {0, 0, 0, 9, 0, 10, 0, 0, 0},
                      {0, 0, 4, 0, 10, 0, 2, 0, 0},
                      {0, 0, 0, 14, 0, 2, 0, 1, 6},
                      {8, 11, 0, 0, 0, 0, 1, 0, 7},
                      {0, 0, 2, 0, 0, 0, 6, 7, 0}
                     };

    dijkstra(graph, 0);

    return 0;
}

The most obvious mismatch is that your code does not have anything corresponding to to the pseudocode's Parent array. I take that as an output parameter, though it's not explicitly so marked. As you seem to have recognized, it is not needed for computing only the lengths of the minimum paths, but it contains all the information about the actual steps in those paths, and that is often desired information.

You also have no analog of the pseudocode's Nearest ; it would be a bit mean to complain about that, though, as Nearest is not a parameter to the routine, and the pseudocode does not show its elements ever being read. As such, it does not appear to serve any useful purpose.

It appears that this code also does not quite match:

         if (!sptSet[n] && graph[u][n] && dist[u] != INT_MAX 
                                       && dist[u]+graph[u][n] < dist[n])
            dist[n] = dist[u] + graph[u][n];

The condition && dist[u] != INT_MAX does not correspond to anything in the pseudocode. (It's also unnecessary, inasmuch as u was returned by minDistance() , and therefore that condition should always be satisfied).

Conceivably, your instructor may also be dissatisfied that you print the min path lengths instead of returning them. It depends a bit on the pseudocode dialect, but I'd be inclined to take the appearance of Dist in the parameter list as an indication that it is an output parameter, not merely an internal variable.

If your instructor is being extremely picky, then perhaps you can get some slack by pointing out some apparent errors in the pseudocode:

  • As already mentioned, Nearest is not a parameter, and it is written to but never read from.
  • It looks like the conditional if Dist[u] ← w(uv) < Dist[v] then should instead be if Dist[u] + w(uv) < Dist[v] then . (You have implemented the correct version, which could be construed as another difference from the pseudocode.)
  • It looks like Parent[r] ← u should be Parent[v] ← u .

Of course, it could be that your instructor wanted you to implement the pseudocode exactly, errors and all ....

As a matter of strategy, I would have tried to use variable names better matching the pseudocode. I don't think it would be fair for your instructor to reject the code on those grounds, but comparing the C++ code to the pseudocode would have been easier for everyone if you had stuck a bit closer with your names.

While I'm talking about your code, by the way, I observe that although your minDistance() function appears to implement the pseudocode's requirements, it does so in an inefficient way (and Dijkstra isn't particularly efficient to begin with). The usual approach uses a min-heap to track nodes that have been seen but not yet visited, which reduces the cost of selecting the min-distance node from O(n) to O(log n). Not that it matters for so few elements as you are testing on, of course, but for large graphs the difference is enormous.

On problem is i belive your minDistance function, it seems that you only update unvisited nodes ( line 10 if (sptSet[v] == false && dist[n] <= min)). I guess this is wrong. Consider the following graph (nodes V={n1, n2, n3, n4} with the following distances d(n1, n2) = 10; d(n1,n3) = 3; d(n3,n2) = 3 ( all others are infinity).

Starting in n1 you discover n2 with the cost of 10

you discover also n3 with the cost of 3

from n2 you dont discover the shorter path to n2 ( n1-n3-n2), because you marked n2 already as visited.

I'm not sure, if i'm wright. If not dont blame me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM