简体   繁体   中英

Shortest Path Implementation in Java

I'm working with an Adjacency matrix and trying to create a function that finds a shortest path within a graph. I'm trying to modify Prim's algorithm which I used to write a minimal spanning tree function.

public static int shortest(int first, int last)  throws Exception{
              int weight[] = new int[Nodes.length]; //keeps track of the weights of the added edges
              int path[] = new int[Nodes.length];   //keeps track of the nodes in the path
              boolean visited[] = new boolean[Nodes.length];    //keeps track of nodes visited
              int current;
              int total;
              int minWeight;
              int nodes = Nodes.length;
              int i;

              for (i=0;i<nodes;i++){    //initialization
                    path[i]=0;
                    visited[i]=false;
                    weight[i]=32767;    //largest short int
              }

              current=first;
              weight[current]=0;
              total=1;
              visited[current]=true;
              path[0]=current;

              while(total!=nodes){
                    for(i=1;i<nodes;i++){
                        if(AMatrix[current][i] != 0 && visited[i]==false && weight[i]>AMatrix[current][i]){     
                                weight[i]=AMatrix[current][i]; 
                                    path[i]=current;
                        }
                    }
                    minWeight=32767;
                    for(i=1;i<nodes;i++){
                        if(visited[i]==false && weight[i]<minWeight){
                            minWeight=weight[i];
                            current=i;
                        }
                    }
                    write("current = "+ current);
                    visited[current]=true;
                    total++;

                    if(current == last){
                        path[total-1]=current;
                        for(i=1;i<total;i++){
                            write("includes the node "+Nodes[path[i]]); 
                        }

                        minWeight=0;
                        int j=1;
                        for(i=2;i<total;i++){
                            write("The weight from "+Nodes[path[j]]+" to "+Nodes[path[i]]+" is "+AMatrix[path[j]][path[i]]);
                            minWeight = minWeight+AMatrix[path[j]][path[i]];
                            write("min weight= "+minWeight);
                            j++;
                        }
                        return minWeight;
                    }
                }

                return -1;
        }

It works with one of the inputs I gave it where I started with the first node, but if I try starting with a different node, it creates a path that connects two nodes that aren't actually connected. I've stared at this for so long, and I can't see why it's doing that. The minimal spanning tree works great, and I thought that this was going to be a simple modification but it's just not working.

I actually think that there's a lot of things wrong with this, such as if I try to print out the elements starting the path array from 0, it will print out the first one twice, so I'm sure I've made lots of mistakes, but that's the one that's being blatantly obvious to me right now.

AMatrix is my adjacency matrix and Nodes is the matrix of each of my nodes. Write is I function I wrote that writes to an output file.

The arrays have zero based indexes. But your first two loops start from 1:

for(i=1; i < nodes;i++)

So this will likely cause that fact that it works when you start first=0 , because in your adjacency matrix AMatrix[current][i] != 0 the diagonal (current == i) is probably 0. But if you start the algorithm with an other value that 0, you are missing a node : 0.

Also, just a few hints:

  • You say : "weight[i]=32767; //largest short int" , but this is the largest short, 2^15 - 1, which is better initialized like this : weight[i] = Short.MAX_VALUE; . If you want the largest int, it's similar : weight[i] = Integer.MAX_VALUE;
  • Better not to use static for everything. It isn't easy to test and it isn't OO. You maybe can write unit test using JUnit. Or like Domi said in the comment, try to debug your code (with for example the eclipse debugger).
  • The code is a little hard to follow/understand if you didn't write it yourself. So add comments, for example above each for loop explaining what it does. Readability of code is more important than writing it fast, because you will read the code several times, but you write it only once.

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