Dijsktra方法不起作用

时间:2016-01-12 10:35:31

标签: java eclipse

所以试图让dijsktra算法工作,显然我根据labb助手(不再提供帮助)删除了错误的节点 这些是他的评论:

  

"您在Dijkstra方法中使用的循环(第158-178行)。为了使其正确,您需要循环遍历minNode的外弧(在您的情况下," n"),然后选择具有最小成本的节点作为您的minNode。在您的情况下,始终从tempNode列表而不是minNode中删除第一个节点。请重新提交修改后的Network.java文件。"

这些是第157-181行:

while (! tempNodes.isEmpty()) { // repeat until all nodes become permanent
        Node n = tempNodes.get(0);
        double min= Double.POSITIVE_INFINITY;

            if(n.value < min){
                min = n.value;
            }


        for(Arc a: n.arcList){
            if(n.value + a.weight < a.head.value){
                a.head.value = n.value + a.weight;  // Update the weight of each node that is adjacent to the minimum-
                n.prev = a;
            }

        tempNodes.remove(n);}//Remove the minimum-weight node n from tempNodes    
    }

    Node k;// Represent a tree by assigning 1 to its arcs and 0 to all other arcs.
    for (String nodeName: nodeMap.keySet()) {
         k = nodeMap.get(nodeName);
         if(k.prev != null) {
              k.prev.alvalue = 1.0;
        }
    }

我是否正确假设唯一的问题是即时删除n而不是min mayby?

我只是添加其余的行:

public class Network {
// Attributes
public String name;
public HashMap<String, Node> nodeMap;

// Constructor
public Network(String name, String inputFileName) {
// Initialize the attributes
this.name = name;
this.nodeMap = new HashMap<String, Node>();

// You MAY need these local variables to store values or objects
// temporarily while constructing a new Network object
String line, arcID, tailName, headName;
Node tail, head;
double weight;
Arc forwardArc, backwardArc;

try {
// Get access to the contents of an ASCII file
File file = new File(inputFileName);
FileReader fReader = new FileReader(file);
BufferedReader bReader = new BufferedReader(fReader);

// Read the first line, and do nothing to skip it
line = bReader.readLine();
// Read the second line, which represents the first
// (undirected) arc stored in the file
line = bReader.readLine();
// Store each element of the network in forward star.
while (line != null) {
// Split each line into an array of 4 Strings
// using ; as separator.
String[] tokens = line.split(";");
arcID = tokens[0];
tailName = tokens[1];
headName = tokens[2];
weight = Double.parseDouble(tokens[3]);


// Check if nodeMap contains a Node whose name is tailName or headName.
if(nodeMap.containsKey(tailName)){
    tail = nodeMap.get(tailName);
}
else{
    tail = new Node(tailName, Double.POSITIVE_INFINITY, new LinkedList());
    nodeMap.put(tailName, tail);
}

if(nodeMap.containsKey(headName)){
    head = nodeMap.get(headName);
}
else{
    head = new Node(headName, Double.POSITIVE_INFINITY, new LinkedList());
    nodeMap.put(headName, tail);
}
// If not, create it, assign it to tail or head, and add it to nodeMap.
// Otherwise, retrieve it from nodeMap.

// Then, create two Arcs:
// one from tail to head, to be added to outArc of tail
// one from head to tail, to be added to outArc of head.
forwardArc = new Arc(arcID+"a",tail,head,weight);
backwardArc = new Arc(arcID+"b",head,tail,weight);
tail.arcList.add(forwardArc);
head.arcList.add(backwardArc);

// Read the next line
line = bReader.readLine(); }
} catch (Exception e) {
e.printStackTrace();
}
}


// Save
public void save(String outputFileName) {
    // This object represents an output file, out.txt, located at ./data/.
                File file = new File(outputFileName);
                // This object represents ASCII data (to be) stored in the file
                FileWriter fWriter;
                try {
                    //writing to the output-file
                    fWriter = new FileWriter(file);
                    fWriter.write("TLID "+"\t");
                    fWriter.write("NAME "+"\t");
                    fWriter.write("ALVALUE"+"\n");

                    for (Map.Entry<String, Node> entry : nodeMap.entrySet()) {
                        String key = entry.getKey();
                        Object value = entry.getValue();
                        Node values = (Node) value;
                      for (Arc A: values.arcList) {
                          String TLID = A.name.substring(0,A.name.length()-1);

                            fWriter.write(TLID+"\t");
                            fWriter.write(A.name+"\t");
                            fWriter.write(A.alvalue+"\n");
                        }
                    }


                    fWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
}

public void printNodes(){
System.out.println("\tNODE NAME\tWEIGHT");
Node node;
for (String nodeName: nodeMap.keySet()) { // loop thru nodeMap
node = nodeMap.get(nodeName);
System.out.print("\t" + node.name); // \t represents tab space
System.out.print("\t\t" + node.value);
System.out.println();
}

}

public void printArcs(){
    System.out.print("TLID "+"\t");
    System.out.print("NAME "+"\t");
    System.out.print("ALVALUE "+"\n");

    for (Map.Entry<String, Node> entry : nodeMap.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        Node values = (Node) value;
      for (Arc A: values.arcList) {
          String TLID = A.name.substring(0,A.name.length()-1);
          System.out.print(TLID+"\t");
          System.out.print(A.name+"\t");
          System.out.print(A.alvalue+"\n");

        }
    }
}
public void dijkstra(Node origin) {

    // Set the value (representing shortest path distance) of origin to 0
     origin.value = 0;

    // Create a set of nodes, called tempNodes, whose shortest path distances are not permanently determined. Initially, this set contains all nodes.
     List<Node> tempNodes = new ArrayList<Node>();
    for (String nodeName: nodeMap.keySet()) {
     tempNodes.add(nodeMap.get(nodeName));
     }

    // Perform Dijkstra
    while (! tempNodes.isEmpty()) { // repeat until all nodes become permanent
        Node n = tempNodes.get(0);
        double min= Double.POSITIVE_INFINITY;

            if(n.value < min){
                min = n.value;
            }


        for(Arc a: n.arcList){
            if(n.value + a.weight < a.head.value){
                a.head.value = n.value + a.weight;  // Update the weight of each node that is adjacent to the minimum-
                n.prev = a;
            }

        tempNodes.remove(n);}//Remove the minimum-weight node n from tempNodes    
    }

    Node k;// Represent a tree by assigning 1 to its arcs and 0 to all other arcs.
    for (String nodeName: nodeMap.keySet()) {
         k = nodeMap.get(nodeName);
         if(k.prev != null) {
              k.prev.alvalue = 1.0;
        }
    }

}

private void clearArcWeight() {
     Node n;
    for (String nodeName: nodeMap.keySet()) {
     n = nodeMap.get(nodeName);
     for(Arc a: n.arcList){
     a.weight = 0.0;
     }
     }
    }

public void dijkstra(Node origin, Node destination) {
 dijkstra(origin); // or this.dijkstra(origin);
 clearArcWeight();
 trace(destination);
}

// Represent a tree by assigning 1 to its arcs and 0 to all other arcs.

private void trace(Node n){
    Arc a = n.prev;
    while (a != null) {
     a.weight = 1.0;
     a = a.tail.prev;
     }
}

public HashMap<String, Node> getNodeMap(){
    return nodeMap;
}

public void dijkstraByName(String string) {

    dijkstra(nodeMap.get(string));
}

}

1 个答案:

答案 0 :(得分:1)

我或许可以在这里给出一些提示......如果你看一下这些话:

Node n = tempNodes.get(0);
// [...n is not changed here...]
tempNodes.remove(n);

你会意识到传入remove()的n永远不会是&temp;来自于#temp; 2012()和#39; tempNodes.get(0)&#39;的结果。这就是为什么第一个节点总是从列表中删除的原因。