Weighted Graphs and Shortest Path Algorithms

(Dijkstra’s Algorithm)

 

 

Objectives of this lecture

q       Learn how to compute the shortest path between vertices in a weighted graph

 

What is Weighted graph?

q       For many applications, the edges in a graph are associated with a weight.

q       For example, we could have a graph representing possible routes between cities, where the weight might be the distance or time taken along a given route. Such a graph is referred to as a weighted graph.

q       A weighted graph is generally implemented using adjacency table where the matrix is not an NxN array of booleans, but of integers or reals, where the number indicates the weight of an edge

q       Where there is no edge between two vertices this corresponds in principle with a weight of infinity, but some convention can be adopted for what to put in the matrix for such cases.

 

Finding the shortest path

q       Given a weighted graph, we want to find the shortest path between two vertices, where the 'length' of the path is just defined as the sum of the weights on the relevant edges.

q       However, It turns out that finding shortest path from one vertex to another involves the same algorithm as finding a shortest path between that vertex and every other vertex.  The only difference is that in the former, we stop as soon as the target is reached.

q       Thus, we shall develop an algorithm that find the shortest path from a given vertex called the source to every other vertex.

q       It is necessary to keep track, as we search, of the shortest distance we have found so far connecting the source vertex to each other vertex. This information can be kept in an array (say, d).

q       As we search, given a number of possible vertices to explore, the one that is the shortest distance from the start vertex is explored first. 

q       We shall go through how this works with an example.

q       Suppose we are searching the graph in the following figure; starting from vertex 0

q       We shall use a set S to denote the vertices so far examined.

 

 

We proceed as follows:

 
 

q       The shortest distance from the souce, vertex 0 to itself is 0 so is added to the array S. 

q       We then look at the vertices connected to 0, and record the shortest distance from vertex 0 to these vertices, ie:

index

0

1

2

3

4

d

0

5

3

¥

2

 

q       The vertex with the shortest distance, 4, is added to S.

q       At this point, the shortest distance from 0 to itself and 4 has been determined.

 

q       Next, we examine what additional vertices we can reach from vertex 4.  Also, could passing though vertex 4 improve the shortest distance of the vertices we already estimated?

 

 

q       We can now reach vertex 3 with a distance of 2+4=6.  We can also reach vertex 2 through 4 but the previous estimate is better.  Simlarly, the previous estimate for vertex 1 is better.  Thus, our shortest array is as follows:

index

0

1

2

3

4

d

0

5

3

6

2

 

 

q       The minimum distance among those vertices not already in S is vertex 2, so we add it to S and re-examine the estimate distances if we pass through it.

 

 

q       We can now reach vertex 1 with a shorter distance of 3+1=4.  Also we can reach vertex 3 with a shorter distance of 3+2=5.  We update these distances in the array d and obtain the following:

index

0

1

2

3

4

d

0

4

3

5

2

 

q       The nearest among those vertices not already visted is vertex 1.  we add this to S and examine the estimates again.  This addition however does not improve any of the distances in d.

 

 

index

0

1

2

3

4

d

0

4

3

5

2

 

q       Finally, we add vertex 3, but this again does not change any of the shortest distances.

 

 

index

0

1

2

3

4

d

0

4

3

5

2

 

 

Implementation.

q       We represent the graph using adjacency table as explained earlier.  Thus, the calling program should include the following declarations.

 
#include <limits.h>
#define INFINITY INT_MAX     /* value for infty   */
#define MAXVERTEX ...
typedef int AdjacencyTable[MAXVERTEX][MAXVERTEX];
typedef int DistanceTable[MAXVERTEX];
int n;  /* number of vertices in the graph  */
AdjacencyTable cost; /* describes the graph        */
DistanceTable D;   /* shortest distances from vertex 0 */
 
/* Distance: calculates the cost of the shortest path.
Pre:  A directed graph is given which has n vertices by the weights
        given in the table cost.
Post: The function finds the shortest path from vertex 0 to each vertex
         of the graph and returns the path that it finds in the array D.
 */
 
void Distance(int n, AdjacencyTable cost, DistanceTable D)
{
   Boolean final[MAXVERTEX];   /* Has the distance from 0 to v been 
                                        found? final[v] is true iff v is in the set S.*/
    int i;        /* repetition count for the main loop               */
    int w;          /* a vertex not yet added to the set S              */
    int v;          /* vertex with minimum tentative distance in D[]*/
    int min;        /* distance of v, equals D[v]                 */
 
    final[0] = TRUE;        /* Initialize with vertex 0 alone in the set S. */
    D[0] = 0;
 
    for (v = 1; v < n; v++) {
        final[v] = FALSE;
        D[v] = cost[0][v];
    }
 
    /* Start the main loop; add one vertex v to S on each pass.   */
    for (i = 1; i < n; i++) {
        min = INFINITY;     /* Find the closest vertex v to vertex 0. */
        for (w = 1; w < n; w++)
            if (!final[w])
                if (D[w] < min) {
                    v = w;
                    min = D[w];
                }
        final[v] = TRUE;            /* Add v to the set S.    */
        for (w = 1; w < n; w++)  //Update the remaining distances in D.
            if (!final[w])
                if (min + cost[v][w] < D[w])
                    D[w] = min + cost[v][w];
    }
}

 

Analysis

The main loop is executed n-1 times, and within the main loop, each executes n-1 times, thus the running time of the algorithm is O(n2).