Java:具有节点类的统一成本搜索
下面的代码用于检测图像,创建包含该图像像素值的2d数组,并确定从图像内的点a到图像内的点B的最低成本路径(我使用了统一成本搜索)。当我运行代码时,出现以下错误:Java:具有节点类的统一成本搜索,java,graph-algorithm,priority-queue,comparable,Java,Graph Algorithm,Priority Queue,Comparable,下面的代码用于检测图像,创建包含该图像像素值的2d数组,并确定从图像内的点a到图像内的点B的最低成本路径(我使用了统一成本搜索)。当我运行代码时,出现以下错误: Exception in thread "main" java.lang.ClassCastException: UniformCostSearch$Node cannot be cast to java.lang.Comparable at java.util.PriorityQueue.siftUpComparabl
Exception in thread "main" java.lang.ClassCastException: UniformCostSearch$Node
cannot be cast to java.lang.Comparable
at java.util.PriorityQueue.siftUpComparable(Unknown Source)
at java.util.PriorityQueue.siftUp(Unknown Source)
at java.util.PriorityQueue.offer(Unknown Source)
at java.util.PriorityQueue.add(Unknown Source)
at UniformCostSearch.uCostSearch(UniformCostSearch.java:159)
at UniformCostSearch.main(UniformCostSearch.java:216)
为什么会发生这种情况,我如何解决?我看过其他的解决方案,但我相信我有一个不同的问题
public class UniformCostSearch
{
//------------------------------------
// Node Class
//------------------------------------
public static class Node implements Comparator<Node>
{
public double cost;
Node parent;
public int x;
public int y;
public Node(){}
public Node(double cost, Node parent, int x, int y)
{
this.cost = cost;
this.parent = parent;
this.x = x;
this.y = y;
}
@Override
public int compare(Node node1, Node node2)
{
if(node1.cost < node2.cost)
return -1;
if(node1.cost > node2.cost)
return 1;
return 0;
}
@Override
public boolean equals(Object obj)
{
if(obj instanceof Node)
{
Node node = (Node) obj;
if (this.parent == node.parent)
return true;
}
return false;
}
}
public static void uCostSearch(Node startState, Node endNode,
BufferedImage img){
int adjacencyMatrix[][] = null;
PriorityQueue<Node> pq = new PriorityQueue<Node>();
startState.cost = 0.0;
startState.parent = null;
int inc = 0;
pq.add(startState);
Set<Point> visited = new HashSet<Point>();
Point startPoint = new Point(startState.x, startState.y);
visited.add(startPoint);
byte[] terrain =
((DataBufferByte)img.getRaster().getDataBuffer()).getData();
int width = img.getWidth();
int height = img.getHeight();
final boolean hasAlphaChannel = img.getAlphaRaster() != null;
int channel_count = 4;
int green_channel = 2; // 0=alpha, 1=blue, 2=green, 3=red
int[][] result = new int[height][width];
// Source: http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image
if (hasAlphaChannel) {
final int pixelLength = 4;
for (int pixel = 0, row = 0, col = 0; pixel < terrain.length; pixel += pixelLength) {
int argb = 0;
argb += (((int) terrain[pixel] & 0xff) << 24); // alpha
argb += ((int) terrain[pixel + 1] & 0xff); // blue
argb += (((int) terrain[pixel + 2] & 0xff) << 8); // green
argb += (((int) terrain[pixel + 3] & 0xff) << 16); // red
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
} else {
final int pixelLength = 3;
for (int pixel = 0, row = 0, col = 0; pixel < terrain.length; pixel += pixelLength) {
int argb = 0;
argb += -16777216; // 255 alpha
argb += ((int) terrain[pixel] & 0xff); // blue
argb += (((int) terrain[pixel + 1] & 0xff) << 8); // green
argb += (((int) terrain[pixel + 2] & 0xff) << 16); // red
result[row][col] = argb;
col++;
if (col == width) {
col = 0;
row++;
}
}
}
while(!pq.isEmpty()){
Node s = pq.remove();
if(s == endNode)
return;
else{
if(inc++ % 5000 < 1000){
// set to Green
img.setRGB(s.y, s.x, 0xFF00FF00);
}
ArrayList<Point> directions = new ArrayList<Point>();
directions.add(new Point(s.x, s.y+1));
directions.add(new Point(s.x, s.y-1));
directions.add(new Point(s.x+1, s.y));
directions.add(new Point(s.x-1, s.y));
for(Point step: directions){
int x = step.x;
int y = step.y;
if(0 <= y && y < height && 0 <= x && x < width
&& !(visited.contains(step))){
visited.add(step);
Node temp = new Node(s.cost + channel_count *
(y * width + x) + green_channel, s, x, y);
pq.add(temp);
}
}
}
inc++;
System.out.print(inc);
}
}
public static BufferedImage GetImage(String filename)
{
BufferedImage bImage = null;
try{
bImage = ImageIO.read(new File(filename));
}
catch(Exception e)
{
e.printStackTrace();
}
return bImage;
}
/*
public createPath(Node node, BufferedImage image){
while(node.parent != null){
//set pixel to red;
node = node.parent;
}
}
*/
// main method
public static void main(String[] args)
{
int startX = 0, startY = 0, endX = 0, endY = 0;
BufferedImage bufferedImage = null;
// Get filename and start and end points from command line
try{
String filename = args[0];
startX = Integer.parseInt(args[1]);
startY = Integer.parseInt(args[2]);
endX = Integer.parseInt(args[3]);
endY = Integer.parseInt(args[4]);
bufferedImage = GetImage(filename);
}
catch(Exception e)
{
e.printStackTrace();
System.out.print("Please enter filename start.x start.y" +
" end.x end.y in that order");
}
Node startingPoint = new Node(0.0, null, startX, startY);
Node endingPoint = new Node();
endingPoint.x = endX;
endingPoint.y = endY;
uCostSearch(startingPoint, endingPoint, bufferedImage);
//createPath(endingPoint, bufferedImage)
//saveImage
//PrintCost
//Output Image
}
}
公共类UniformCostSearch
{
//------------------------------------
//节点类
//------------------------------------
公共静态类节点实现了Comparator
{
公共双重成本;
节点父节点;
公共int x;
公共智力;
公共节点(){}
公共节点(双重成本、节点父节点、整数x、整数y)
{
成本=成本;
this.parent=parent;
这个.x=x;
这个。y=y;
}
@凌驾
公共整数比较(节点1、节点2)
{
if(节点1.成本<节点2.成本)
返回-1;
if(node1.cost>node2.cost)
返回1;
返回0;
}
@凌驾
公共布尔等于(对象obj)
{
if(节点的obj实例)
{
Node Node=(Node)obj;
if(this.parent==node.parent)
返回true;
}
返回false;
}
}
公共静态无效uCostSearch(节点startState、节点endNode、,
缓冲区图像(img){
int-adjacencyMatrix[][]=null;
PriorityQueue pq=新的PriorityQueue();
startState.cost=0.0;
startState.parent=null;
int inc=0;
pq.添加(开始状态);
Set visted=新HashSet();
点startPoint=新点(startState.x,startState.y);
已访问。添加(startPoint);
字节[]地形=
((DataBufferByte)img.getRaster().getDataBuffer()).getData();
int width=img.getWidth();
int height=img.getHeight();
最终布尔值hasAlphaChannel=img.getAlphaRaster()!=null;
int通道_计数=4;
int green_channel=2;//0=alpha,1=blue,2=green,3=red
int[][]结果=新的int[高度][宽度];
//资料来源:http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image
中频(信道){
最终整数像素长度=4;
对于(int-pixel=0,row=0,col=0;pixel argb+=((int)terrain[pixel]&0xff)为了满足PriorityQueue
类(由UniformCostSearch使用)的排序能力,您的节点
类必须实现Comparable
接口,而不是Comparator
接口
要在比较中使用节点父节点,可以尝试以下操作:
@Override
public int compareTo(Node that)
{
if (this.parent != null && that.parent != null) {
return this.parent.compareTo(that.parent);
}
return this.cost - that.cost;
}
不过,这只是一个例子。我并不声称它将满足您的要求,但它将防止NullPointerException。谢谢。明天第一件事就是更新并共享结果。我现在使用Comparable,它解决了我的ClassCastException。但是,当我包含它时,会引发null指针异常。下面是我的代码compareTo:@Override public int compareTo(Node Node){返回this.parent.compareTo(Node.parent);}这是可能的this.parent.compareTo()
将在树上递归,直到它到达根节点,我假设根节点没有父节点(null),此时调用compareTo()
在空父节点上生成NullPointerException。此外,我相信您会发现,仅按父节点进行比较不足以满足Comparable.compareTo()
的约定,因此您可能需要基于被比较节点的某些属性的辅助比较条件。我将其修改为:this.parent.compareTo(node);我仍然得到NPE。同样的事情,兄弟-该语句递归到树结构的顶部,然后尝试在顶层调用空父级上的compareTo()
。请参阅我的编辑。