-1

I am trying to implement Dijkstras algorithm in c and I almost have the right output. Something is happening it the dist array. It is giving extremely large and small numbers.

Link to site I'm basing most of my algorithm code on: https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/ this also explains the algorithm if you're not familiar.

Here is the code:

#include <limits.h>
#include <stdio.h>
#include<stdbool.h>
#define N 10 /* max matrix size is 10 x 10 */
#define INF INT_MAX /* infinity? */
int src; /* global */

void getdata(int amtrx[3][N], int *n, int *src) {
  int i, j, nsz, nedg, fr, to, vtx, wt;
  scanf("%d %d %d", &nsz, &nedg, &vtx);

  for (i = 0; i < nsz; i++)
    for (j = 0; j < nsz; j++)
      amtrx[i][j] = INF;

  for(i=0; i < nedg; i++) {
    scanf("%d %d %d", &fr, &to, &wt);
    amtrx[fr][to] = wt;
  }
  *n = nsz;
  *src = vtx;
}

void printpaths(int dist[], int n) {
  int i;
  for (i = 0; i < n; i++)
    if(i == src);
    else if (dist[i] < INF) {
      printf("%d  %d  %d\n", src, i, amtrx[i]);
    } else {
      printf("%d  %d  INF (no path)\n", src, i);
    }
}

void dijkstras(int amtrx[][N], int n) {
  int dist[n], v;
  bool spt[n];
  int min = INF, u;

  for (v = 0; v < n; v++)
    if (spt[v] == false && dist[v] <= min) {
      min = dist[v], u = v;
      spt[u] = true;
    }

  for (v = 0; v < n; v++)
    if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
      dist[v] = dist[u] + amtrx[u][v];

  printpaths(dist, n);
}

int main()  {
  int amtrx[N][N];
  int n;

  getdata(amtrx, &n, &src);
  dijkstras(amtrx, n);
  return 0;
}

Here is the input:

6 11 0
0 1 50
0 2 10
0 4 45
1 2 15
1 4 10
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 4 03

Output:

0  1  32701
0  2  -1996178040
0  3  -1996178014
0  4  -1996178044
0  5  32765

Expected output:

0 1 45
0 2 10
0 3 25
0 4 45
0 5 INF (no path)

Thanks for the help in advance! I'm hoping it's just a simple fix that I can't seem to see :)

update

I think the algorithm was wrong and I worked on it a little, the output is still wrong but i think this is more right than before:

void dijkstras(int amtrx[][N], int n) {
  int dist[n], v, q;
  bool spt[n];
  int min = INF, u;

  for (v = 0; v < n; v++) {
    dist[v] = INF;
    spt[v] = false;
  }

  dist[n] = 0;

  for (v = 0; v < n - 1; v++) {
    for (q = 0; q < n; q++) {
      if (spt[v] == false && dist[v] <= min) {
        min = dist[v], u = v;
      }
      spt[u] = true;
    }

    for (v = 0; v < n; v++)
      if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
        dist[v] = dist[u] + amtrx[u][v];
  }

  printpaths(dist, n);
}

Output now:

0  1  INF (no path)
0  2  INF (no path)
0  3  INF (no path)
0  4  INF (no path)
0  5  INF (no path)

update 2

void dijkstras(int amtrx[][N], int n) {
    int min = INF, dist[N], count, v, u;
    bool spt[N];

    for (v = 0; v < N; v++) {
        dist[v] = INF;
    spt[v] = false;
  }

    dist[src] = 0;

    for (count = 0; count < N - 1; count++) {
      for (v = 0; v < N; v++)
        if (spt[v] == false && dist[v] <= min)
            min = dist[v], u = v;

      spt[u] = true;

      for (v = 0; v < N; v++)
        if (!spt[v] && amtrx[u][v] && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
            dist[v] = dist[u] + amtrx[u][v];
    }

  printpaths(dist, n);
}

output:

0  1  50
0  2  10
0  3  INF (no path)
0  4  45
0  5  INF (no path)

I'm so close I can taste it! Any help is appreciated!

Helana Brock
  • 45
  • 15
  • To make your code more readable and easier to follow I would recommend using more meaningful names/ `spt` or `amtrx` for example do not mean much to me. Also please hard code the test data. – c0der Apr 22 '20 at 04:05
  • In my understanding, the `min` value should be set to INF at each iteration, i.e. for each `count` – Damien Apr 22 '20 at 08:18
  • `printf("%d %d %d\n", src, i, amtrx[i]);` This is probably not the code you are running. – n. m. could be an AI Apr 22 '20 at 11:58
  • @N. 'pronouns' m. I supposed `amtrx[i]` must be changed by `dist[i]` – Stef1611 Apr 23 '20 at 10:27

1 Answers1

0
void dijkstras(int amtrx[][N], int n) {
    int min = INF, dist[n], count, v, u;
    bool spt[n];

    for (v = 0; v < n; v++) {
        dist[v] = INF;
    spt[v] = false;
  }

    dist[src] = 0;

    for (count = 0; count < n - 1; count++) {
            min=INF;
      for (v = 0; v < n; v++)
        if (spt[v] == false && dist[v] <= min)
            min = dist[v], u = v;

      spt[u] = true;

      for (v = 0; v < n; v++)
        if (!spt[v] && amtrx[u][v] != INF && dist[u] != INF && dist[u] + amtrx[u][v] < dist[v])
            dist[v] = dist[u] + amtrx[u][v];
    }

  printpaths(dist, n);
}
Stef1611
  • 1,978
  • 2
  • 11
  • 30