将询问用户路径和距离。然后它将使用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);
}
}
答案 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数据结构(例如使用的List
和Map
对象)使执行更加连贯,并且,因此,更容易使用。希望这会有所帮助。