2

Using the pseudo code found on wikipedia to implement a floyd warshall algorithm on a adjacency list representation the following code was created. The graph is a grid, so if it is a 3 x 3 grid vertex 0 has two edges and vertex 1 has 3 while vertex 2 has two and so on.

self-> V = number of vertex in the graph!!

void floyd(Graph *self, int** dist, int** next)
{
    int i, j, k;
    EdgeNodePtr current;

    current =  malloc(sizeof(current));

    for (i = 0; i < self->V; i++)
    {
        for (j = 0; j < self->V; j++) {
            dist[i][j] = INT_MAX; // Sets all minimun distances to infintiy
            next[i][j] = -1; // Sets all next vertex to a non existant vertex
        }
    }

    for (i = 0; i < self->V; i++)
    {
        for (j = 0; j < self->V; j++)
        {
            current = self->edges[i].head;

            while (current != NULL) // Cycles through all the edges in edgelist
            {
                if (current->edge.to_vertex == j) // If an edge to the correct vertex is found then adds distance
                {
                    dist[i][j] = current->edge.weight;
                    next[i][j] = j; // Updates next node
                }
                current =  current->next;
            }

        }
    }

    PRINT

    // Standard implemnation of floyds algorithm
    for (k = 0; k < self->V; k++)
    {
        for (i = 0; i < self->V; i++)
        {
            for (j = 0; j < self->V; j++)
            {
                if (dist[i][j] > dist[i][k] + dist[k][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    next[i][j] = next[i][k];
                }
            }
        }
    }
 PRINT
}

What happens is the edges are all inserted into the distance array correctly, checked by a simple print. The problem is faced when the algorithm runs it turns all the distances into INT_MINS or similar numbers. While not actually calculating the distances.

I believe the end distance graph of a grid should have every possible distance filled in the array except having the distances from a vertex to itself as infinity.

A picture of the output from printing the list graph where its says PRINT enter image description here

Secernere
  • 63
  • 1
  • 1
  • 9

1 Answers1

2

You need to be careful about int overflow. The Wikipedia pseudocode (at the bottom of this answer) uses "infinity" where "infinity + (anything finite) = infinity". However, this is not the case when you use INT_MAX to represent "infinity" due to overflow. Try changing your if statement condition to:

if (dist[i][k] != INT_MAX &&
         dist[k][j] != INT_MAX &&
         dist[i][j] > dist[i][k] + dist[k][j]) {

This will avoid the int overflow from adding a positive distance to INT_MAX.

Wikipedia pseudocode:

1 let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
2 for each edge (u,v)
3    dist[u][v] ← w(u,v)  // the weight of the edge (u,v)
4 for each vertex v
5    dist[v][v] ← 0
6 for k from 1 to |V|
7    for i from 1 to |V|
8       for j from 1 to |V|
9          if dist[i][j] > dist[i][k] + dist[k][j] 
10             dist[i][j] ← dist[i][k] + dist[k][j]
11         end if
k_ssb
  • 6,024
  • 23
  • 47
  • Surely not, down further in the pseudo code for path reconstruction it doesn't do it. – Secernere Jun 01 '18 at 00:39
  • So if I add in the line "if (i == j) dist[i][j] = 0;" when i set the array values? Doesn't make any difference – Secernere Jun 01 '18 at 00:46
  • @Secernere See my edit, that's probably a better answer for you – k_ssb Jun 01 '18 at 00:48
  • Works now, thanks. So from my understand it was adding to the INT_MAX which cycled around to the lowest INT value? – Secernere Jun 01 '18 at 00:54
  • @Secernere Yep, standard int overflow -- either `dist[i][k]` or `dist[k][j]` was INT_MAX, but INT_MAX + (something small and positive) results in something really close to INT_MIN, which is less than `dist[i][j]` – k_ssb Jun 01 '18 at 00:55