【问题标题】:BreadthFirst search in JavaJava中的广度优先搜索
【发布时间】:2015-01-21 08:00:31
【问题描述】:

我使用这种类型的构造函数在 Java 中创建了一个树:

public class Node
{
    private List<Node> children = null;
    private String value;

    public Node(String value)
    {
        this.children = new ArrayList<>();
        this.value = value;
    }

    public void addChild(Node child)
    {
        children.add(child);
    }

}

取自How to create own tree in java?

我正在使用某些方法,为每个节点创建子节点。

我不知道如何使用广度优先和深度优先来生成节点。 我尝试了一种递归方法,但它不起作用:

public void depthFirst(Node node, int op){
    if (op == 1) operationsNoTrim(node); //child generator method
    else if (op == 2) operationsWithTrim(node); //child generator method
    else if (op == 3) operationsWithTrimNSecure(node); //child generator method
    for(int i = 0; i < node.getTotalChild(); i++){
        depthFirst(node.getChild(i), op);
    }
}

我需要为一个人工智能项目生成具有呼吸优先和深度优先方法的孩子,使用迭代或递归方式。 如果我管理这些,我可能会弄清楚如何使用 A* 和 IDA* 生成节点......我已经对质量和启发式进行了编程。

operationsNoTrim 包含 4 个操作符,它们的工作方式类似(就生成节点而言),但规则不同。请注意,这里的 State = Node。

public void operateYellow(State state){
    int pos = 0;
    while (pos <= sqn*sqn-1 && foundObjective == false){//try each position         if (checkPosPiece(state, pos, -1) == true){ //check if field is empty
            State clonedState = cloneState(state);
            removePieceFromList(clonedState); //removes the next piece to be added, from the list
            setPieceToState(clonedState, 3, pos); //sets the piece on the field
            int points = 0;
            nodes++;
            modifyBoard(clonedState, pos, 3); //updates the board
            //Verifies if a figure has been made
            int tempPos = 0;
            boolean figureFound = false;
            while (tempPos <= (sqn*sqn-1)-(sqn+1) && figureFound == false){ //Verifies if there is a figure corner between field 0 and 18
                if (checkYellow(clonedState,tempPos)) figureFound = true;
                tempPos++;
            }
            if (figureFound){
                points = calculatePoints(armLength(clonedState, tempPos-1, 0, 1, 3)*4); //computes the size of the figure
                clearYellow(clonedState, tempPos-1);
            }
            setTotalPointsOfState(clonedState, points);
            setStateID(clonedState);
            setParentStateID(state, clonedState);
            state.addChild(clonedState);
            if (objectiveState(clonedState)){ 
                pos = sqn*sqn;
                foundObjective = true;
            }
        }
        pos++;
    }
}

我设法用数组列表创建了一种游戏树:

public void breadthFirst(State state, int op){
        int i = 0;
        while (foundObjective == false){ //Generate nodes until a solution is found
            if (op == 1) noTrimOperations(state);
            else if (op == 2) operationsWithTrim(state);
            else if (op == 3) operationsWithTrimNSeg(state);
            i++;
            try{
                state = cloneState(States.get(i)); //The next node to be expanded                   
                System.out.println("State: " + i);  
                System.out.println("Nodes: "+ (States.size()));
            } catch(IndexOutOfBoundsException e) { //if no mode nodes can be generated due to empty list of pieces
                return;
            }
        }
    }

但是,使用这个数组列表我无法创建 A* 和 IDA*。

State 构造函数包含一个 ID 和一个 Parent ID 字段。 因此,在找到解决方案后,我会回溯状态直到根状态,用于必须放置碎片的位置。

【问题讨论】:

  • 我不明白这个问题。首先,方法breadthFirst 似乎实现了深度优先搜索,而不是广度优先搜索。 “子生成器方法”应该做什么?
  • 感谢您抽出宝贵时间!我有子生成器方法,只要找到解决方案,或者直到找不到可能的解决方案,它就应该生成子代。他们应该以广度优先和深度优先的方式做到这一点
  • 请展示子生成器方法的实现。在breadthFirst 中,没有使用它们的返回值。如果子生成器方法应该过滤子代以供以后处理,这可能就是问题所在。
  • 假设我有一个带有 2x2 字段的空棋盘和一个棋子列表。子生成器将第一块放在每个字段上,生成 4 个子节点(另外 4 个节点)。然后,应该取第二个节点,并将第二个部分放在剩余的字段上,依此类推。
  • 我并没有真正关注你。您是否要按照此处所述表示游戏树? en.wikipedia.org/wiki/Game_tree

标签: java tree depth


【解决方案1】:

如果这是您的深度优先:

public void depthFirst(Node node, int op){
    if (op == 1) operationsNoTrim(node); //child generator method
    else if (op == 2) operationsWithTrim(node); //child generator method
    else if (op == 3) operationsWithTrimNSecure(node); //child generator method
    for(int i = 0; i < node.getTotalChild(); i++){
        depthFirst(node.getChild(i), op);
    }
}

那么这将是您的广度优先(从包含根的列表开始)

public void breadthFirst(ArrayList<Node> nodes, int op) {
    ArrayList<Node> children = new ArrayList<>();
    // nodes contain the nodes on the previous (or parent) level
    for(int i = 0; i < nodes.size(); ++i) {
        Node node = nodes.get(i);
        if (op == 1) operationsNoTrim(node); //child generator method
        else if (op == 2) operationsWithTrim(node); //child generator method
        else if (op == 3) operationsWithTrimNSecure(node); //child generator method
        for(int i = 0; i < node.getTotalChild(); ++i) {
            children.add(node.getChild(i));
        }
    }
    // children contain the nodes on the current level
    // all the nodes have been created, but not processed yet
    // now process this level recursively...
    breadthFirst(children, op);
}

并且没有递归:

public void breadthFirst(Node root, int op) {
    ArrayList<Node> nodes = new ArrayList<>();
    ArrayList<Node> children = new ArrayList<>();
    // start
    nodes.add(root);
    // as long as unprocessed nodes are available...
    while(!nodes.isEmpty()) {
        // nodes contain the nodes on the previous (or parent) level
        for(int i = 0; i < nodes.size(); ++i) {
            Node node = nodes.get(i);
            if (op == 1) operationsNoTrim(node); //child generator method
            else if (op == 2) operationsWithTrim(node); //child generator method
            else if (op == 3) operationsWithTrimNSecure(node); //child generator method
            for(int i = 0; i < node.getTotalChild(); ++i) {
                children.add(node.getChild(i));
            }
        }
        // children contain the nodes on the current level
        // all the nodes have been created, but not processed yet
        // now process this level...
        ArrayList<Node> tmp = nodes;
        nodes = children; // children is the new "parent level"
        children = tmp;
        children.clear(); // throw away previous level
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多