Java 使用Dijkstra'的最短路径;s算法
我现在正在恢复一个旧的家庭作业,我正在编写一个程序,其中包括使用Dijkstra算法在图中找到最短路径 我想我在大多数情况下都是正确的,但在执行Java 使用Dijkstra'的最短路径;s算法,java,algorithm,dijkstra,Java,Algorithm,Dijkstra,我现在正在恢复一个旧的家庭作业,我正在编写一个程序,其中包括使用Dijkstra算法在图中找到最短路径 我想我在大多数情况下都是正确的,但在执行if(currentNode.getAktuell())时,我在第58行一直得到NullPointerException 我一直在反复尝试几种解决方案,但似乎无法找出问题所在,但prioQueue.poll()返回null。我试图处理最后一个currentNode,它最终变为null,但没有找到有效的解决方案,所以我开始认为我错过了一些东西 如果熟悉di
if(currentNode.getAktuell())
时,我在第58行一直得到NullPointerException
我一直在反复尝试几种解决方案,但似乎无法找出问题所在,但prioQueue.poll()当队列为空时,code>返回null
。我试图处理最后一个currentNode
,它最终变为null,但没有找到有效的解决方案,所以我开始认为我错过了一些东西
如果熟悉dijkstras算法的人能在这里帮助我,我将不胜感激。这个算法可能有更好的解决方案,但我只想得到帮助,找出我写的算法的错误,而不是使用其他人的算法来“回答”
public static List<String> shortestPath(Graph<String> graph, String från, String till){
//if(!pathExists(graph, från, till))
//return null;
PriorityQueue<DjikstraObjekt<String>> prioQueue = new PriorityQueue<DjikstraObjekt<String>>();
LinkedHashMap<String, DjikstraObjekt<String>> samling = new LinkedHashMap<String, DjikstraObjekt<String>>();
for(String bla : graph.getNodes())
samling.put(bla, new DjikstraObjekt<String>(bla, Integer.MAX_VALUE, null, false));
samling.get(från).updateVikt(0);
prioQueue.add(samling.get(från));
while(!samling.get(till).getAktuell())
{
DjikstraObjekt<String> currentNode = prioQueue.poll();
if(currentNode==null)
break;
if(currentNode.getAktuell())
continue;
currentNode.aktuellNod();
for(ListEdge<String> edge : graph.getEdgesFrom(currentNode.getNode()))
{
System.out.println("get edges from");
int nyVikt = edge.getVikt() + currentNode.getVikt();
DjikstraObjekt<String> toNode = samling.get(edge.getDest());
if(!toNode.getAktuell() && nyVikt < toNode.getVikt()) {
toNode.updateVikt(nyVikt);
toNode.setFrån(currentNode.getNode());
prioQueue.add(toNode);
}
}
}
List<String> djikstaList = new ArrayList<String>();
for(int i=0;i<samling.size();i++){
if(samling.get(i).getNode()!=från){
System.out.println(samling.get(i).getNode());
djikstaList.add(samling.get(i).getNode());
}
}
return djikstaList;
}
public class DjikstraObjekt<E> implements Comparable<DjikstraObjekt<E>> {
private E nod;
private int vikt;
private E frånNod;
private boolean aktuellNod=false;
public DjikstraObjekt(E nod, int vikt, E frånNod, boolean aktuellNod){
this.nod=nod;
this.vikt=vikt;
this.frånNod=frånNod;
this.aktuellNod=aktuellNod;
}
public E getNode() {
return nod;
}
public void updateVikt(int nyvikt){
vikt=nyvikt;
}
public int getVikt() {
return vikt;
}
public boolean getAktuell() {
return aktuellNod;
}
public void aktuellNod(){
aktuellNod=true;
}
public void setFrån(E från)
{
frånNod = från;
}
public int compareTo(DjikstraObjekt<E> other) {
return getVikt() - other.getVikt();
}
}
公共静态列表最短路径(图形、字符串från、字符串till){
//如果(!pathExists(图,från,till))
//返回null;
PriorityQueue prioQueue=新的PriorityQueue();
LinkedHashMap samling=新LinkedHashMap();
for(字符串bla:graph.getNodes())
put(bla,新的DjikstraObjekt(bla,Integer.MAX_值,null,false));
samling.get(från).updateVikt(0);
prioQueue.add(samling.get(från));
而(!samling.get(till.getAktuell())
{
DjikstraObjekt currentNode=prioQueue.poll();
if(currentNode==null)
打破
if(currentNode.getAktuell())
继续;
currentNode.aktuellNod();
对于(ListEdge:graph.GetEdgeFrom(currentNode.getNode()))
{
System.out.println(“从中获取边”);
int nyVikt=edge.getVikt()+currentNode.getVikt();
DjikstraObjekt toNode=samling.get(edge.getDest());
如果(!toNode.getAktuell()&&nyVikt 对于(int i=0;i我认为这可能是一个问题:
//...
samling.put(bla, new DjikstraObjekt<String>(bla, Integer.MAX_VALUE, null, false));
samling.get(från).updateVikt(0);
/。。。
put(bla,新的DjikstraObjekt(bla,Integer.MAX_值,null,false));
samling.get(från).updateVikt(0);
编辑:
对不起,我以为{}在那里。那里一切正常。我会继续找。也许可以试试这个:
if(currentNode==null || currentNode.getAktuell() == null)
break;
if(currentNode.getAktuell())
continue;
我无法重建您告诉我们的NullPointerException。正如Leandro指出的,问题可能在于您对ListEdge和Graph的实现
我自己实现了这两个类来测试您的代码
我能找到的唯一问题是在最后创建结果列表的地方:
for(int i=0;i<samling.size();i++){
if(samling.get(i).getNode()!=från){
此外,我假设您不想返回从from
到to
的实际路径,因此您需要向DijkstraObjekt
添加一个gettergetFrån()
,然后像这样构建列表:
String fromNode = samling.get(to).getNode();
djikstaList.add(to);
while(fromNode != from){
fromNode = samling.get(fromNode).getFrån();
djikstaList.add(fromNode);
}
在此之后,列表将按相反顺序包含完整路径(包括开始和结束节点)
如果需要,我可以发布用于测试/调试的所有类
干杯
tannerli对于非斯堪的纳维亚人,“vikt”表示“重量”,“från”表示“来自”,而“aktuell”表示“当前”。是的,对此感到抱歉。我有一种将变量/方法名称与英语和瑞典语混合的坏习惯:)请给我们您的DijkstraObject代码或完整的stacktrace。当您在该行前面检查currentNode
中的null
时,NullPointerException
必须来自getAktuell()
method。我确实在页面底部包含了DijkstraObject类。如果您提供了Graph和ListEdge类,则会更容易找到错误。如果您还没有解决问题,请提交该信息。我对此感到好奇:)我之前尝试过,但稍后在代码中它会给我一个空指针。我想我做了其他事情我在这里,但不知道是什么!我已经编辑了我的主要帖子,添加了我图表中缺少的方法。现在不在家,所以还不能尝试你的答案,但我会让你知道,如果我能用你的答案解决问题,我发现你添加的这两个类没有明显的错误(尽管拥有整个ListGraph类会很好),我认为我提到的部分仍然存在问题,因为我必须对算法本身的逻辑进行任何更改才能使其工作。谢谢你的帮助。我现在正在休假,但我会尝试你的建议,并将其标记为已解决,如果我在两周后一回家就让它工作:)我让算法开始工作。正如你所说的那样,我以错误的方式构建了列表。我还添加了你来自哪个节点,以及以何种方式添加到djikstraObject类。非常感谢,你是个救命恩人:)总是乐于助人,我不得不为我的“数据结构和算法”考试而学习:)
for(int i=0;i<samling.size();i++){
if(samling.get(i).getNode()!=från){
List<String> djikstaList = new ArrayList<String>();
for(String key : samling.keySet()){
if(samling.get(key).getNode()!=från){
System.out.println(samling.get(key).getNode());
djikstaList.add(samling.get(key).getNode());
}
}
String fromNode = samling.get(to).getNode();
djikstaList.add(to);
while(fromNode != from){
fromNode = samling.get(fromNode).getFrån();
djikstaList.add(fromNode);
}