0

I am trying to code dijkstra's algorithm, starting at any vertex I need to show the distance and print the path of nodes. It works for vertex 2,4, and 5, but for 1 and 3 it gets messed up. It's probably something stupidly small, but I can't see it.

public static void main(String[] args)
{
    int INF = Integer.MAX_VALUE;
    int verticies = 5;
    int W[][] = {{INF,7,4,6,1},
    {0,INF,0,0,0},
    {0,2,INF,4,0},
    {0,0,0,INF,0},
    {0,0,0,1,INF}};

    int startNode = 1;
    dijkstra(W,verticies,startNode-1);

}

public static void dijkstra(int G[][],int n,int startnode)
{
    int INF = Integer.MAX_VALUE, nINF = Integer.MIN_VALUE;
    //int cost[MAX][MAX],distance[MAX],pred[MAX];
    //int visited[MAX],count,mindistance,nextnode,i,j;
    int cost[][] = new int[n][n];
    int distance[] = new int[n];
    int pred[] = new int[n];
    boolean visited[] = new boolean[n];
    int count=0, mindistance=0, nextnode=0,i,j;

    //pred[] stores the predecessor of each node
    //count gives the number of nodes seen so far
    //create the cost matrix
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if(G[i][j]==0)
                cost[i][j]=INF;
            else
                cost[i][j]=G[i][j];

    //initialize pred[],distance[] and visited[]
    for(i=0;i<n;i++)
    {
        distance[i]=cost[startnode][i];
        pred[i]=startnode;
        visited[i]=false;
    }

    distance[startnode]=0;
    visited[startnode]=true;
    count=1;

    while(count<n-1)
    {
        mindistance=INF;

        //nextnode gives the node at minimum distance
        for(i=0;i<n;i++)
            if(distance[i]<mindistance&&!visited[i])
            {
                mindistance=distance[i];
                nextnode=i;
            }

        //check if a better path exists through nextnode
        visited[nextnode]=true;
        for(i=0;i<n;i++)
            if(!visited[i])
                if(mindistance+cost[nextnode][i]<distance[i])
                {
                    distance[i]=mindistance+cost[nextnode][i];
                    pred[i]=nextnode;
                }
        count++;
    }

    //print the path and distance of each node
    for(i=0;i<n;i++)
        if(i!=startnode)
        {
            if(distance[i] == INF || distance[i] < 0){
                System.out.print("\nNo edge exists between node "+(startnode+1)+" and node "+(i+1));
            } else {
                System.out.format("\nDistance of node %d = %d", (i + 1), distance[i]);
                System.out.format("\nPath = %d", (i + 1));

                j = i;
                do {
                    j = pred[j];
                    System.out.format("<-%d", (j + 1));
                } while (j != startnode);
            }
        }
}
Felicia
  • 33
  • 1
  • 1
  • 8
  • Hint: you put quite lot of code there. **Hard** to read code that is. Dont be surprised when there aren't too many answers. Instead, I recommend A) learn how to use a debugger B) read about "Clean Code". I would start with **not** putting all that stuff into one method. Instead: slice things into as many small methods as possible. – GhostCat Oct 18 '16 at 18:52
  • 1
    Plus: I suggest to always always always put { around blocks }. It is **soooo** easy to get something wrong when not doing that! – GhostCat Oct 18 '16 at 18:53
  • @Felicia I don't know what the problem is but one thing looks strange : With the line "visited[nextnode]=true;", you are marking the node (obtained from the set of connected nodes) with minimum weight as visited. I think according to algorithm a node is marked visited when all its adjacent nodes are visited. – 10101010 Oct 18 '16 at 19:02
  • @Felicia I think this class that I wrote https://github.com/rajatIIT/graph_algo_practice/commit/82a6dc964d5ac8d58040eaedb37395c2ab565d94 might help you . Like GhostCat said, clearer code is nice. – 10101010 Oct 18 '16 at 19:03
  • I posted the whole thing as is because last time I got yelled at by a user for not posting enough of the code... Sorry still trying to find the happy medium I guess. – Felicia Oct 18 '16 at 23:37

1 Answers1

1

I don’t know exactly how, but you are somehow getting INF into your calculations. My suspicion goes to the line distance[i]=mindistance+cost[nextnode][i];, but it may not be the only culprit, I have not checked. When mindistance is 1 (or greater) and cost is Integer.MAX_VALUE, you get an arithmetic overflow and the result gets negative. Further behaviour, I have not predicted, but it’s not as expected.

When in the two places you define INF I change the value to 1,000,000, I get the following output from your program:

Distance of node 2 = 6
Path = 2<-3<-1
Distance of node 3 = 4
Path = 3<-1
Distance of node 4 = 2
Path = 4<-5<-1
Distance of node 5 = 1
Path = 5<-1

I believe this is correct.

The way I found out? I stuck this statement into the middle of your outer while loop:

        System.out.println("count " + count + " nextnode " + nextnode + " mindistance " + mindistance);

When it printed a large negative number, I started suspecting an arithmetic overflow. Until you learn to use a debugger, System.out.println() is your friend for debugging.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Do you recommend a debugger? – Felicia Oct 18 '16 at 23:30
  • A debugger is indispensable for a professional programmer. It hasn’t got any steep learning curve, so you may get started in a pace that suits you. – Ole V.V. Oct 18 '16 at 23:39
  • Also, thank you.. That worked. The debugger that is included in my program only tells you what's wrong if there's an error, it's not very good. – Felicia Oct 18 '16 at 23:39
  • Good IDEs like IntelliJ IDEA and Eclipse have good built-in debuggers. If you’re keen, you may download Eclipse for free and start trying it out. – Ole V.V. Oct 18 '16 at 23:42