我应该为我的学校作业实施Dijkstra。我理解算法本身并基于维基百科和其他一些来源的代码,但我似乎有一些错误,因为它基本上没有在我的JUnit测试中终止。
代码:
@Override
public void populateDijkstraFrom(Node startNode) {
this.resetState();
// TODO: Your populateDijkstraFrom implementation here
// You can use this implementation of a priority queue.
// Nodes that are added to the queue are automatically sorted by distance
// because we overwrote Node.compareTo()
if(startNode == null){
throw new RuntimeException();
}
for (Node n : nodes.values()){
if(n != startNode){
n.predecessor=null;
n.distance=Integer.MAX_VALUE; //set distance of each node to maxvalue
}
}
PriorityQueue<Node> distanceQueue = new PriorityQueue<Node>();
startNode.predecessor=null;
startNode.distance=0; //set distance of startnode to 0
distanceQueue.add(startNode); //add startnode to the PQ
while (!distanceQueue.isEmpty()){
Node current = distanceQueue.poll(); // get headelement of PQ
current.status=2;
for(Node i : current.getAdjacentNodes()){
int weight = current.getWeight(i);
int distancethroughcurrent = current.distance + weight;
if(distancethroughcurrent < i.distance){
i.distance = distancethroughcurrent;
i.predecessor = current;
distanceQueue.add(i);
i.status=1;
}
}
}
// clean up
this.clearMarks();
}
另外计算最短路径,我们也应该编写一个方法,通过使用上面的方法找到这个路径并将其返回到列表中:
@Override
public List<Node> getShortestPathDijkstra(int startNodeID, int targetNodeID) {
return getShortestPathDijkstra(nodes.get(startNodeID), nodes.get(targetNodeID));
}
/**
* Calculates a List of Node indices that describe the shortet path from
* start node to target node. The Dijkstra-Algorithmn is used for
* calculation.
*
* @param targetNodeIndex
* the index of the target node, as returned by addNode()
* @return the list of nodes, or null if no path exists
*/
@Override
public List<Node> getShortestPathDijkstra(Node startNode, Node targetNode) {
// NOTE: you have to run populateDijkstraFrom first before you can read
// out the shortest path
LinkedList<Node> DijkstraList = new LinkedList<Node>();
if(startNode == null || targetNode == null){
throw new RuntimeException(); //check if either node is null
}
populateDijkstraFrom(startNode);
Stack <Node> stack = new Stack<Node>();
while(targetNode.predecessor != null){
stack.push(targetNode);
targetNode = targetNode.predecessor;
}
stack.push(startNode);
while (!stack.isEmpty()){
Node item = stack.pop();
DijkstraList.add(item);
}
//This line stops program execution until a key is pressed
//stopExecutionUntilSignal();
//Return an empty list. Replace this line by the shortest path!
return DijkstraList;
}
编辑:这是一个没有经过的测试用例:
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;
import org.junit.Test;
import org.junit.Before;
import static org.junit.Assert.assertEquals;
public class DijkstraTest {
private DiGraph g1;
@Before
public void setUp() throws Exception {
// read graph from file
try {
g1 = GraphIO.loadGraph("tests/testgraphen/graphDijkstra.txt");
g1.setShowSteps(true);
VisualGraph v = new VisualGraph(g1);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testDijkstraShortestPath() {
// fill distance and predecessor values
g1.populateDijkstraFrom(0);
// expected list
LinkedList<Integer> expect = new LinkedList<Integer>();
expect.addFirst(3);
expect.addFirst(2);
expect.addFirst(1);
expect.addFirst(0);
// test actual getShortestPath from 0 to 3
List<Node> actualNodes = g1.getShortestPathDijkstra(0, 3);
assertEquals(
"getShortestPath didn't find the path with the right number of nodes",
actualNodes.size(), expect.size());
LinkedList<Integer> actual = new LinkedList<Integer>();
for (Node n : actualNodes) {
actual.addLast(n.getID());
}
assertEquals("getShortestPath didn't return the shortest path",
actual.toString(), expect.toString());
}
}