0

The user will be asked what path and what distance. Then it'll compute the shortest distance using Dijkstra's algorithm. The problem is some distance and paths are wrong. There are distances that has 2147483647 and its path is null. The algo works perfectly with zero as a starting point. How do i fix it?
If the user inputs

Enter first path: 0
Enter second path: 1
Enter distance: 1
Do you want to add path again? y
Enter first path: 1
Enter second path: 3
Enter distance: 2
Do you want to add path again? y
Enter first path: 3
Enter second path: 5
Enter distance: 4
Do you want to add path again? y
Enter first path: 1
Enter second path: 2
Enter distance: 3
Do you want to add path again? y
Enter first path: 0
Enter second path: 2
Enter distance: 8
Do you want to add path again? y
Enter first path: 0
Enter second path: 4
Enter distance: 9
Do you want to add path again? n
V   D   P
0   2147483647null //this part should be 1 and the path is 1-0
1   0null
2   31 -    2
3   21 -    3
4   2147483647null // this part should be 10 and the path is 0-4
5   63 -    5

=========================================================================

import java.util.*;

public class DijkstraAlgo {
    final static int VERTICES = 6;

    public static int minDistance(int distance[], Boolean shortestPath[]){
        int minDist = Integer.MAX_VALUE;
        int minIndex = -1;

        for(int i = 0;i < VERTICES;i++){
            if(shortestPath[i] == false && distance[i] <= minDist){
                minDist = distance[i];
                minIndex = i;
            }
        }

        return minIndex;
    }

    public static void dijkstra(int path[][], int startingPoint){
        int shortestDist[] = new int[VERTICES];
        Boolean shortestPath[] = new Boolean[VERTICES];
        String paths[] = new String[VERTICES];

        for(int i = 0;i < VERTICES;i++){
            shortestDist[i] = Integer.MAX_VALUE;
            shortestPath[i] = false;
        }

        shortestDist[startingPoint] = 0;

        for(int ctr = 0;ctr < VERTICES - 1;ctr++){
            int index = minDistance(shortestDist, shortestPath);

            shortestPath[index] = true;

            for(int j = 0;j < VERTICES;j++){
                if(!shortestPath[j] && path[index][j] != 0 && shortestDist[index] != Integer.MAX_VALUE && shortestDist[index] + path[index][j] < shortestDist[j]){
                    shortestDist[j] = shortestDist[index] + path[index][j];
                    paths[j] = Integer.toString(index) + " - " + "   " + Integer.toString(j);
                    System.out.println(shortestDist[j]);
                }
            }
        }
        printAnswer(shortestDist, VERTICES, paths);
    }

    public static void printAnswer(int distance[], int vertices, String paths[]){
        System.out.println("V   D   P");
        for(int i = 0; i < VERTICES; i++)
            System.out.println(i + "   " + distance[i] + paths[i]);
    }

    public static void main(String args[]){
        int start;
        int end;
        int path[][] = new int[6][6];
        int distance;

        Scanner input = new Scanner(System.in);
        String choose;
        boolean ans = true;

        while(ans == true){
            System.out.print("Enter first path: ");
            start = input.nextInt();
            System.out.print("Enter second path: ");
            end = input.nextInt();
            System.out.print("Enter distance: ");
            distance = input.nextInt();

            path[start][end] = distance;

            System.out.print("Do you want to add path again? ");
            choose = input.next();
            if(choose.equals("y") || choose.equals("Y"))
                ans = true;
            else if(choose.equals("n") || choose.equals("N"))
                ans = false;
            else
                System.out.println("Invalid input!");
        }

        dijkstra(path, 1);
    }

}
Temmie
  • 127
  • 2
  • 14
  • This is a job for the debugger. Here's instructions for Eclipse. If you use something other than Eclipse, Google has the answer. http://www.vogella.com/tutorials/EclipseDebugging/article.html – Ironcache May 19 '16 at 15:51

1 Answers1

2

I don't know what's wrong with your code, being honest. I don't plan to go through and try to debug it either; Eclipse can do that for you (as I linked in the comment).

What I will provide is a better means of approaching this, IMO. Storing your data in arrays of integers is a convoluted approach that's going to lead to confusion (as is evident here). One of the main benefits of using an object-oriented language like Java is that you can form your data in a coherent manner relevant to the context.

Consider creating two classes:

public class DijkstraNode {
    private int label;
    private List<DijkstraLink> links;

    public DijkstraNode(int label) {
        this.label = label;
        links = new ArrayList<DijkstraLink>();
    }

    public int getLabel() {
        return label;
    }

    public void addLink(DijkstraLink link) {
        links.add(link);
    }

    public List<DijkstraLink> getLinks() {
        return links;
    }
}

...

public class DijkstraLink {
    private DijkstraNode node;
    private int distance;

    public DijkstraLink(DijkstraNode node, int distance) {
        this.node = node;
        this.distance = distance;
    }

    public DijkstraNode getLinkedNode() {
        return node;
    }

    public int getDistance() {
        return distance;
    }
}

Whenever you create a bi-directional link between nodes:

public void createTwoWayLink(DijkstraNode first, DijkstraNode second, int distance) {
    first.addLink(new DijkstraLink(second, distance));
    second.addLink(new DijkstraLink(first, distance));
}

Then evaluating Dijkstra's becomes a much simplier task:

public void computeDijkstras(DijkstraNode startNode, List<DijkstraNode> nodes) {
    Map<DijkstraNode, Integer> distances = new HashMap<DijkstraNode, Integer>();
    for (DijkstraNode node : nodes) {
        if (node != startNode) {
            distances.put(node, Integer.MAX_VALUE);
        }
        else {
            distances.put(node, 0);
        }
    }

    List<DijkstraNode> computedNodes = new ArrayList<DijkstraNode>();

    DijkstraNode toEval = computeSmallestUncomputedNode(distances, computedNodes); // TODO

    while (toEval != null) {
        for (DijkstraLink link : toEval.getLinks()) {
            if (computedNodes.contains(link.getLinkedNode()) {
                continue;
            }
            int evalDist = link.getDistance() + distances.get(toEval);
            if (evalDist < distances.get(link.getLinkedNode())) {
                distances.put(link.getLinkedNode(), evalDist);
            }
        }

        computedNodes.add(toEval);

        toEval = computeSmallestUncomputedNode(distances, computedNodes);
    }

    // distances computed; do whatever.
}

This isn't a complete implementation. I didn't want to do your homework for you. However, I did want to include enough of an example of how capitalizing on object-oriented design and internal Java data structures (such as the List and Map objects used) make execution much more coherent, and, thus, easier to work with. Hope this helps.

Ironcache
  • 1,719
  • 21
  • 33