Java:具有节点类的统一成本搜索

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

下面的代码用于检测图像,创建包含该图像像素值的2d数组,并确定从图像内的点a到图像内的点B的最低成本路径(我使用了统一成本搜索)。当我运行代码时,出现以下错误:

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;pixelargb+=((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()
。请参阅我的编辑。