所以试图让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));
}
}
答案 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;的结果。这就是为什么第一个节点总是从列表中删除的原因。