使用Dijkstra算法的最短路径

约翰·斯诺(John Snow):

我目前正在恢复旧的作业分配,在其中编写的程序除其他功能外,还涉及使用Dijkstra算法在图形中找到最短路径。

我想我大部分时候都做对了,但是NullPointerException执行时我一直保持在第58行if(currentNode.getAktuell())

我一直在尝试几种解决方案,但似乎无法弄清楚出什么问题了,但是当队列为空时prioQueue.poll();返回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();
    }
}

这是我的listEdge类:

public class ListEdge<E> {

    private E dest;
    private String namn;
    private Integer vikt;


    public ListEdge(E dest, String namn, Integer vikt){
        this.dest=dest;
        this.namn=namn;
        this.vikt=vikt;

    }

    public E getDest(){
        return dest;
    }
    public void ändraVikt(Integer nyVikt){
        if(vikt<0)
            throw new IllegalArgumentException();
        vikt=nyVikt;

        }
    public String getNamn(){
        return namn;
    }
     public int compareTo(ListEdge other) {
         return this.vikt.compareTo(other.getVikt());
 }

    public int getVikt(){
        return vikt;
    }
    public String toString(){
        return "till " + dest + " med " + namn +" "+ vikt;
    }
}

这些应该是我的ListGraph类的relevent方法:

public List<E> getNodes(){
    List<E> temp = new ArrayList<E>();
    for(E test : noder.keySet()){
        temp.add(test);

    }
return temp;
}

public List<ListEdge<E>> getEdgesFrom(E nod) {
        List<ListEdge<E>> temp = new ArrayList<ListEdge<E>>();
        if(noder.containsKey(nod)){
            try{
                for(Map.Entry<E, List<ListEdge<E>>> test : noder.entrySet()){
                    if(test.getKey().equals(nod)){
                        System.out.println(nod+" "+test.getKey());
                        for(ListEdge<E> e: test.getValue()){
                            temp.add(e);
                    }
                }
            }
        }
            catch(NoSuchElementException E){

            }

        }
        return temp;
    }
tannerli:

我无法重建您告诉我们的NullPointerException。正如Leandro指出的那样,问题可能出在ListEdge和Graph的实现上。

我自己做了两个类的实现,以测试您的代码。

我唯一能找到的问题是最后创建结果列表:

for(int i=0;i<samling.size();i++){
        if(samling.get(i).getNode()!=från){

这将始终导致,NullPointerException因为get()需要键,而在您的情况下为String,而不是int要遍历地图,请使用类似

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());
    }       
}

此外,我想你wan't从返回的实际路径fromto,所以你需要一个getter添加getFrån()DijkstraObjekt,然后建立列表如下:

   String fromNode = samling.get(to).getNode();
   djikstaList.add(to);
   while(fromNode != from){   
       fromNode = samling.get(fromNode).getFrån();
       djikstaList.add(fromNode);
   }

此后,列表将以相反的顺序包含完整的路径(包括“开始”和“结束”节点)。

如果需要,我可以发布所有用于测试/调试的类。

干杯

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

与Dijkstra算法最短路径

Dijkstra算法的替代方案-图形中的最短路径,公交路线

使用递归算法查找迷宫中的最短路径

如何在dijkstra算法中保存最短路径

当距离为坐标时,使用Dijkstra算法获得最短路径

使用字典的最短路径算法[Python]

使用Floyd算法找到最短路径

增量Dijkstra还是最短路径算法?

Dijkstra算法来找到大图中两个节点之间的最短路径?

用Dijkstra最短路径算法设置顶点权重

使用Dijkstra在升压图中找到最短路径

最短路径算法的蛮力BFS与Dijkstra的运行时间分析

如何使Dijkstra的算法报告该最短路径的完整最终距离

Dijkstra的最短路径算法,具有部分排序的树作为优先级队列

使用行走代理的“最短路径”算法

如何使用Dijkstra算法找到具有顶点约束的最短路径

在使用集合Dijkstra最短路径算法的字典中删除给定节点时出现KeyError

Dijkstra最短路径算法优化

Dijkstra最短路径算法

修正的最短路径算法

是否可以使用Dijkstra的最短路径算法来找到最短的哈密顿路径?(在多项式时间内)

最短路径算法:动态规划与Dijkstra算法

最短路径的困难和Dijkstra算法

Djikstra的最短路径算法

最短路径算法

寻找最短路径算法

使用 Dijkstra 算法跟踪两个节点之间的最短路径

使用 Dijkstra 算法获取 3d 模型中两个节点之间的最短路径

我的 Dijkstra 算法实现不返回最短路径