【问题标题】:Constructor value failed to get the value and assign to variable构造函数值无法获取值并分配给变量
【发布时间】:2016-10-22 12:57:29
【问题描述】:

我尝试实现 Greedy Best First Search。 我的图表和启发式是这样的:

来源:S 目的地:G。正确的方法是:S A C E G。

我看到的问题是他没有从构造函数中获取 hNod,当我声明节点时它是:Node s = new Node("S", 12); 我在尝试调试时打印了节点的 hNod,但我不知道问题出在哪里。

这是我的代码:

package com.gbfs.algorithm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;

class Node{
    public String numeNod;
    public int hNod;
    public Node parent;
    public Edge[] adjacencies = new Edge[]{};

    public Node(String numeNod, int hNod){
            this.numeNod = numeNod;
            hNod = this.hNod;
    }

    public String toString(){
            return numeNod;
    }    
}

class Edge{
    public Node target;

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

    public Edge(Node target){
            this.target = target;
    }
}

public class GreedyBFS {

    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),
                new Edge(a)
        };

        b.adjacencies = new Edge[]{
                new Edge(d),
                new Edge(g)
        };

        d.adjacencies = new Edge[]{
                new Edge(g),
                new Edge(h)
        };

        h.adjacencies = new Edge[]{
                new Edge(f)
        };

        a.adjacencies = new Edge[]{
                new Edge(g),
                new Edge(c)
        };

        c.adjacencies = new Edge[]{
                new Edge(e)
        };

        e.adjacencies = new Edge[]{
                new Edge(g)
        };

        g.adjacencies = new Edge[] {
                new Edge(b),
                new Edge(e),
                new Edge(c),
                new Edge(a)
        };

        f.adjacencies = new Edge[] {
                new Edge(h)
        };

        GreedyBFS(s, g);

        List<Node> path = printPath(g);

        System.out.println("Path: " + path);
}

    public static void GreedyBFS(final Node source, final Node goal) {

        Set<Node> explored = new HashSet<Node>();

        PriorityQueue<Node> queue = new PriorityQueue<Node>(8, new Comparator<Node>() {

            @Override
            public int compare(Node o1, Node o2) {

                if(o1.hNod <= o2.hNod) {
                    System.out.println("Primu if: o1.hnod " + o1.hNod);
                    System.out.println("Primu if: o2.hnod " + o2.hNod);
                    return 1;
                }

                else if(o1.hNod >= o2.hNod) {
                    System.out.println("2 if: o1.hnod " + o1.hNod);
                    System.out.println("2 if: o2.hnod " + o2.hNod);

                    return -1;
                }

                else
                    return 0;
            }
        });

        queue.add(source);

        boolean found = false;

        while( !queue.isEmpty() && !found ) {

            Node current = (Node) queue.poll();

            explored.add(current);

            if(current.numeNod.equals(goal.numeNod)){
                found = true;
            }

            for(Edge o : current.adjacencies) {

                Node child = o.target;
                int temp_hNod = current.hNod;
                System.out.println("temp_hnod = current.Hnod " + temp_hNod);

                if(explored.contains(child) && (temp_hNod >= child.hNod)) {
                    continue;
                }

                else if(!(queue.contains(child)) || (temp_hNod < child.hNod)) {

                    child.parent = current;
                    child.hNod = temp_hNod;

                    if( queue.contains(child) ) {
                        queue.remove(child);
                    }

                    queue.add(child);

                }
            }
        }        
    }

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

}

【问题讨论】:

  • 你的Comparator 毫无意义。 if-else if 案例与 = 重叠。并且hNod 对于两个节点都始终为 0。
  • 顺便说一句,您的数据模型中有几件事我不明白。从图中可以看出,边缘是双向的并且具有权重。在 Java 中,它们似乎被建模为单向的(其中一些是相反的两倍),而且我没有看到权重。我不知道这是否重要。

标签: java algorithm graph artificial-intelligence graph-algorithm


【解决方案1】:

这个任务出错了:hNod = this.hNod;。与上面的行进行比较。应该是this.hNod = hNod;

您的 IDE 应该警告您这里有问题。当您的程序未按预期运行时,您通常可以通过尝试理解收到的警告消息来了解原因。

【讨论】:

  • 我没有看到,但是现在他取了parent的值并保持这样。 12 无处不在
  • 您的 for 循环似乎将currenthNod 分配给current 的所有孩子。这难道不是 12 个被分发到所有节点的原因吗?
【解决方案2】:

我改变了你所说的,现在我知道问题出在哪里了。我把我认为错的地方加粗了。

所以贪婪的 bfs 比较每个节点的启发式并继续最低的一个。所以我从队列中取出一个节点,我说他是一个孩子,我怎么知道那个父母的所有孩子可以在他们之间进行比较?这就是我失败的地方,我知道在我更新的代码中用粗体表示的是什么,我比较了完全相同的东西,但我不知道如何在代码中编写它......:(

这是我的代码更新:

package com.gbfs.algorithm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;

class Node{
    public final String numeNod;
    public final int hNod;
    public Node parent;
    public Edge[] adjacencies = new Edge[]{};
    public int temp_hNod;

    public Node(String numeNod, int hNod){
            this.numeNod = numeNod;
            this.hNod = hNod;
    }

    public String toString(){
            return numeNod;
    }    
}

class Edge{
    public Node target;

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

    public Edge(Node target){
            this.target = target;
    }
}

public class GreedyBFS {

    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),
                new Edge(a)
        };

        b.adjacencies = new Edge[]{
                new Edge(g),
                new Edge(d)
        };

        d.adjacencies = new Edge[]{
                new Edge(g),
                new Edge(h)
        };

        h.adjacencies = new Edge[]{
                new Edge(f)
        };

        a.adjacencies = new Edge[]{
                new Edge(g),
                new Edge(c)
        };

        c.adjacencies = new Edge[]{
                new Edge(e)
        };

        e.adjacencies = new Edge[]{
                new Edge(g)
        };

        GreedySearch(s, g);

        List<Node> path = printPath(g);

        System.out.println("Path: " + path);
}

    public static void GreedySearch(Node source, Node goal) {

        Set<Node> explored = new HashSet<Node>();

        PriorityQueue<Node> queue = new PriorityQueue<Node>(8, new Comparator<Node>() {

            @Override
            public int compare(Node o1, Node o2) {

                if(o1.hNod > o2.hNod) {
                    return 1;
                }

                else if(o1.hNod <o2.hNod){

                    return -1;
                }

                else
                    return 0;
            }
        });

        queue.add(source);

        boolean found = false;

        while( !queue.isEmpty() && !found ) {

            Node current = (Node) queue.poll();

            explored.add(current);

            if(current.numeNod.equals(goal.numeNod)){
                found = true;
            }

            for(Edge o : current.adjacencies) {

                **Node child = o.target;**

                if(explored.contains(child) && (**child.hNod >= child.hNod**)) {
                    continue;
                }

                else if(!(queue.contains(child)) || (**child.hNod < child.hNod**)) {

                    child.parent = current;

                    if( queue.contains(child) ) {
                        queue.remove(child);
                    }

                    queue.add(child);

                }
            }
        }        
    }

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

}

【讨论】: