A*算法中的优先队列空指针异常

我在尝试实现A*算法时遇到了这个问题,不知道为什么会出现这个错误:

enter image description here

我的图和启发式函数如下:

enter image description here

我在创建节点时设置了启发式函数的值,并且在创建边时设置了边的值。

以下是代码:

package com.astar.algorithm;import java.util.PriorityQueue;import java.util.HashSet;import java.util.Set;import java.util.List;import java.util.Comparator;import java.util.ArrayList;import java.util.Collections;public class AStar {        public static void main(String[] args){                Node s = new Node("S", 12);                Node a = new Node("A", 5);                Node b = new Node("B", 5);                Node c = new Node("C", 5);                Node d = new Node("D", 2);                Node e = new Node("E", 2);                Node f = new Node("F", 1);                Node h = new Node("H", 1);                Node g = new Node("G", 0);                s.adjacencies = new Edge[]{                        new Edge(b, 8),                        new Edge(a, 10)                };                b.adjacencies = new Edge[]{                        new Edge(d, 8),                        new Edge(g, 16)                };                d.adjacencies = new Edge[]{                        new Edge(g, 3),                        new Edge(h, 1)                };                h.adjacencies = new Edge[]{                        new Edge(f, 1)                };                a.adjacencies = new Edge[]{                        new Edge(g, 10),                        new Edge(c, 2)                };                c.adjacencies = new Edge[]{                        new Edge(e, 3)                };                e.adjacencies = new Edge[]{                        new Edge(g, 2)                };                AstarSearch(s, g);                List<Node> path = printPath(g);                        System.out.println("Path: " + path);        }        public static List<Node> printPath(Node target){                List<Node> path = new ArrayList<Node>();        for(Node node = target; node!=null; node = node.parent){            path.add(node);        }        Collections.reverse(path);        return path;        }        public static void AstarSearch(Node source, Node goal){                Set<Node> explored = new HashSet<Node>();                PriorityQueue<Node> queue = new PriorityQueue<Node>(8, new Comparator<Node>(){                                 //override compare method                 public int compare(Node i, Node j){                    if(i.f_scores > j.f_scores){                        return 1;                    }                    else if (i.f_scores < j.f_scores){                        return -1;                    }                    else{                        return 0;                    }                 }                        }                        );                //cost from start                source.g_scores = 0;                queue.add(source);                boolean found = false;                while((!queue.isEmpty())&&(!found)){                        //the node in having the lowest f_score value                        Node current = queue.poll();                        explored.add(current);                        //goal found                        if(current.value.equals(goal.value)){                                found = true;                        }                        //check every child of current node                        for(Edge o : current.adjacencies){                                Node child = o.target;                                double cost = o.cost;                                double temp_g_scores = current.g_scores + cost;                                double temp_f_scores = temp_g_scores + child.h_scores;                                /*if child node has been evaluated and                                 the newer f_score is higher, skip*/                                if((explored.contains(child)) && (temp_f_scores >= child.f_scores)) {                                        continue;                                }                                /*else if child node is not in queue or                                 newer f_score is lower*/                                else if((!queue.contains(child)) || (temp_f_scores < child.f_scores)){                                        child.parent = current;                                        child.g_scores = temp_g_scores;                                        child.f_scores = temp_f_scores;                                        if(queue.contains(child)){                                                queue.remove(child);                                        }                                        queue.add(child);                                }                        }                }        }}class Node{        public final String value;        public double g_scores;        public final double h_scores;        public double f_scores = 0;        public Edge[] adjacencies;        public Node parent;        public Node(String val, double hVal){                value = val;                h_scores = hVal;        }        public String toString(){                return value;        }}class Edge{        public final double cost;        public final Node target;        public Edge(Node targetNode, double costVal){                target = targetNode;                cost = costVal;        }}

回答:

你的程序在向队列中添加节点G时失败了,因为它没有为节点设置任何邻接值。

以下代码尝试添加未分配邻接值的子节点:

queue.add(child);

快速修复方法是修改Node类,并用一个空数组初始化adjacencies,如下所示:

public Edge[] adjacencies = new Edge[]{};

因此,Node类将如下所示:

class Node{        public final String value;        public double g_scores;        public final double h_scores;        public double f_scores = 0;        public Edge[] adjacencies = new Edge[]{};        public Node parent;        public Node(String val, double hVal){                value = val;                h_scores = hVal;        }        public String toString(){                return value;        }    }

更好的解决方案是用ArrayList替换数组。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注