输出2147483647作为Dijkstra中最终答案的距离

时间:2016-05-19 15:19:09

标签: java dijkstra

将询问用户路径和距离。然后它将使用Dijkstra算法计算最短距离。问题是一些距离和路径是错误的。有距离2147483647,其路径为空。算法完美地以零为起点。我如何解决它?
如果用户输入

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);
    }

}

1 个答案:

答案 0 :(得分:2)

我不知道你的代码有什么问题,老实说。我不打算通过尝试调试它; Eclipse可以为您做到这一点(正如我在评论中链接的那样)。

我将提供的是一种更好的方法来接近这一点,IMO。将数据存储在整数数组中是一种复杂的方法,这会导致混淆(这里很明显)。使用像Java这样的面向对象语言的一个主要好处是,您可以以与上下文相关的连贯方式形成数据。

考虑创建两个类:

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;
    }
}

每当您在节点之间创建双向链接时:

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

然后评估Dijkstra变得更加简单:

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.
}

这不是一个完整的实现。我不想为你做功课。但是,我确实希望包含足够的示例,说明如何利用面向对象设计和内部Java数据结构(例如使用的ListMap对象)使执行更加连贯,并且,因此,更容易使用。希望这会有所帮助。