Java 递归图遍历

Java 递归图遍历,java,graph,path,traversal,depth-first-search,Java,Graph,Path,Traversal,Depth First Search,我正在用Java编写一个程序来解决这个游戏中的难题: 我对这个问题建模如下 节点类: package model; import java.util.ArrayList; public class Node { private final int nodeId; private ArrayList<Edge> edges; ArrayList<Edge> getEdges() { return edges;

我正在用Java编写一个程序来解决这个游戏中的难题:

我对这个问题建模如下

节点类:

 package model;

    import java.util.ArrayList;

    public class Node {
    private final int nodeId;
    private ArrayList<Edge> edges;

    ArrayList<Edge> getEdges() {
        return edges;
    }

    public int getNodeId() {
        return nodeId;
    }

    public Node(int id) {
        nodeId = id;
        edges = new ArrayList<Edge>();
    }

    @SuppressWarnings("unused")
    private Node() {
        nodeId = -1;
    }

    private void addEdge(Edge toBeAdded) {

        if (toBeAdded != null)
            edges.add(toBeAdded);
    }

    public void addEdgeTo(Node to, Star star) {
        if(this.equals(to))
            return;
        if (to != null) {
            Edge edge = new Edge(to, star);
            addEdge(edge);
        }

    }

    public void addEdgeTo(Node to) {
        if(this.equals(to))
            return;
        if (to != null) {
            Edge edge = new Edge(to);
            addEdge(edge);
        }

    }

    public Edge getEdge(Node to)
    {
        Node edgeDestination;
        for(Edge edgeIterator: edges)
        {
            edgeDestination = edgeIterator.goesTo();
            if(edgeDestination.equals(to))
                return edgeIterator;
        }
        return null;
    }

    public Edge popEdge(Node to)
    {

        Node edgeDestination;
        for(Edge edgeIterator: edges)
        {
            edgeDestination = edgeIterator.goesTo();
            if(edgeDestination.equals(to))
            {
                edges.remove(edgeIterator);
                return edgeIterator;
            }
        }
        return null;
    }



    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Node other = (Node) obj;
        if (nodeId != other.nodeId)
            return false;
        return true;
    }
    }
星级

 package model;

    public class Star {

    boolean dead = false;
    public void die() {
        dead = true;
    }

    public boolean isAlive()
    {
        return !dead; 
    }
    }
和图形类:

package model;

import java.util.ArrayList;

public class Graph {

private ArrayList<Node> nodes = null;
private ArrayList<Star> stars = null;
private Node startNode = null;
private final int startNodeID = 0;

public Graph(ArrayList<Node> nodeArr, ArrayList<Star> starArr) {
    // TODO Auto-generated constructor stub

    nodes = nodeArr;
    stars = starArr;
    setStartNode();
}

private void setStartNode() {
    for (Node nodeIterator : nodes) {
        if (nodeIterator.getNodeId() == startNodeID) {
            startNode = nodeIterator;
            break;
        }
    }
}

public Graph(Graph other) {

    nodes = new ArrayList<Node>();
    stars = new ArrayList<Star>();
    nodes.addAll(other.getNodes());
    stars.addAll(other.getStars());
    setStartNode();
}

public ArrayList<Node> solve() {

    final int numberOfStars = stars.size();
    ArrayList<Node> solution = new ArrayList<Node>();
    solution.add(startNode);
    recursiveSolver(startNode, numberOfStars, solution);
    return solution;
}

private boolean recursiveSolver(Node currentNode, int numberOfStars,
        ArrayList<Node> solutionPointer) {

    if (numberOfStars == 0) 
        return true;
    for(Edge edgeIterator: currentNode.getEdges())
    {
        Node nextNode = edgeIterator.goesTo();
        Graph deepCopy = new Graph(this);
        currentNode = deepCopy.getNode(currentNode);
        nextNode = deepCopy.getNode(nextNode);
        //deepCopy.traverse(currentNode, nextNode);
                    //deepCopy.recursiveSolver(.....);
        //Not sure how to finish this <---------------------------PROBLEM AREA
    }


}

private Node getNode(Node currentNode) {
    return getNode(currentNode.getNodeId());

}

private ArrayList<Node> getNodes() {
    return nodes;
}

private ArrayList<Star> getStars() {
    return stars;
}

public void linkNodesWith(int fromNodeID, int toNodeID, Star star) {

    final Node from = getNode(fromNodeID);
    final Node to = getNode(toNodeID);
    if (from != null && to != null)
        linkNodesWith(from, to, star);

}

private void linkNodesWith(Node nodeFrom, Node nodeTo, Star star) {
    nodeFrom.addEdgeTo(nodeTo, star);
    nodeTo.addEdgeTo(nodeFrom, star);

}

public Node getNode(int nodeId) {

    for (Node iteratorNode : nodes) {
        if (iteratorNode.getNodeId() == nodeId)
            return iteratorNode;
    }
    return null;
}

public void removeNode(Node nodeToRemove) {
    nodes.remove(nodeToRemove);
    for (Node nodeIterator : nodes) {
        nodeIterator.popEdge(nodeToRemove);
    }
}

public void removeNode(int nodeIdToRemove) {
    Node nodeToRemove = getNode(nodeIdToRemove);
    removeNode(nodeToRemove);
}

    //Last three functions are used to create a specific graph to solve
public void populateEdges() {
    for (Node nodeFromIterator : nodes) {
        for (Node nodeToIterator : nodes) {
            nodeFromIterator.addEdgeTo(nodeToIterator);
        }
    }
}

public void replaceEdge(int nodeFromID, int nodeToID, Star star) {
    Node nodeFrom = getNode(nodeFromID);
    Node nodeTo = getNode(nodeToID);
    unlinkNodes(nodeFrom, nodeTo);
    linkNodesWith(nodeFrom, nodeTo, star);

}

private void unlinkNodes(Node nodeFrom, Node nodeTo) {
    nodeFrom.popEdge(nodeTo);
    nodeTo.popEdge(nodeFrom);
}
}
包模型;
导入java.util.ArrayList;
公共类图{
私有ArrayList节点=null;
private ArrayList stars=null;
私有节点startNode=null;
私有最终int startNodeID=0;
公共图(ArrayList nodeArr、ArrayList starArr){
//TODO自动生成的构造函数存根
节点=节点耳环;
星=星;
setStartNode();
}
私有void setStartNode(){
用于(节点节点运算符:节点){
if(nodeIterator.getNodeId()==startNodeID){
startNode=节点转换器;
打破
}
}
}
公共图形(其他图形){
节点=新的ArrayList();
stars=新的ArrayList();
nodes.addAll(other.getNodes());
stars.addAll(other.getStars());
setStartNode();
}
公共ArrayList solve(){
最终整数numberOfStars=stars.size();
ArrayList解决方案=新建ArrayList();
添加(startNode);
递归解算器(startNode,numberOfStars,solution);
回流液;
}
私有布尔递归解算器(节点currentNode,int numberOfStars,
ArrayList解决方案(指针){
如果(numberOfStars==0)
返回true;
对于(Edge edgeIterator:currentNode.GetEdge())
{
Node nextNode=edgeIterator.goesTo();
Graph deepCopy=新图形(此);
currentNode=deepCopy.getNode(currentNode);
nextNode=deepCopy.getNode(nextNode);
//遍历(currentNode,nextNode);
//recursiveSolver(…);

//不确定如何完成这个例如,您可以使用递归回溯解决方案和不可变图来完成

1) 构建一个包含所有节点+所有边和星形列表的图形(每个星形包含其所在的所有边的列表,或者每个边包含对其路径上的星形(而不是副本)的引用列表。任何对您更有意义的)

2) 编写递归方法。其参数为:

  • 图形+星星列表(不可变)
  • 到目前为止已获取的节点列表,按顺序排列
  • 到目前为止获取的边的列表,按顺序
  • 剩下的明星名单
它应做到以下几点:

2a)如果它有可能采取的移动(来自它所在节点的、不在到目前为止所采取的移动列表中的移动),则递归地分支并通过调用自身来尝试下一步的每个移动

  • 图形+星星列表(不可变)
  • 到目前为止获取的边列表的副本,按顺序添加此模式获取的新边
  • 到目前为止获取的节点列表的副本,按顺序添加此模式获取的新节点
  • 一份剩下的要拍摄的星星列表,减去这次移动拍摄的新星星

2b)如果没有可能的模式可供选择,请检查我们是否选择了所有星星。如果选择了,则这是解决方案(打印出所选边的列表)

我不明白您是如何得出必须修改图表的结论的。解决这一问题需要一个简单的回溯应用程序。任何更改的状态都可以存储在您传递的堆栈中,或者您可以临时修改节点以将其标记为已访问。也就是说,如果希望人们阅读,请缩进代码!我没有得出结论那就是,我不知道如何在不修改图表的情况下进行搜索。你能给我举个例子吗?在网上搜索“回溯”。
package model;

import java.util.ArrayList;

public class Graph {

private ArrayList<Node> nodes = null;
private ArrayList<Star> stars = null;
private Node startNode = null;
private final int startNodeID = 0;

public Graph(ArrayList<Node> nodeArr, ArrayList<Star> starArr) {
    // TODO Auto-generated constructor stub

    nodes = nodeArr;
    stars = starArr;
    setStartNode();
}

private void setStartNode() {
    for (Node nodeIterator : nodes) {
        if (nodeIterator.getNodeId() == startNodeID) {
            startNode = nodeIterator;
            break;
        }
    }
}

public Graph(Graph other) {

    nodes = new ArrayList<Node>();
    stars = new ArrayList<Star>();
    nodes.addAll(other.getNodes());
    stars.addAll(other.getStars());
    setStartNode();
}

public ArrayList<Node> solve() {

    final int numberOfStars = stars.size();
    ArrayList<Node> solution = new ArrayList<Node>();
    solution.add(startNode);
    recursiveSolver(startNode, numberOfStars, solution);
    return solution;
}

private boolean recursiveSolver(Node currentNode, int numberOfStars,
        ArrayList<Node> solutionPointer) {

    if (numberOfStars == 0) 
        return true;
    for(Edge edgeIterator: currentNode.getEdges())
    {
        Node nextNode = edgeIterator.goesTo();
        Graph deepCopy = new Graph(this);
        currentNode = deepCopy.getNode(currentNode);
        nextNode = deepCopy.getNode(nextNode);
        //deepCopy.traverse(currentNode, nextNode);
                    //deepCopy.recursiveSolver(.....);
        //Not sure how to finish this <---------------------------PROBLEM AREA
    }


}

private Node getNode(Node currentNode) {
    return getNode(currentNode.getNodeId());

}

private ArrayList<Node> getNodes() {
    return nodes;
}

private ArrayList<Star> getStars() {
    return stars;
}

public void linkNodesWith(int fromNodeID, int toNodeID, Star star) {

    final Node from = getNode(fromNodeID);
    final Node to = getNode(toNodeID);
    if (from != null && to != null)
        linkNodesWith(from, to, star);

}

private void linkNodesWith(Node nodeFrom, Node nodeTo, Star star) {
    nodeFrom.addEdgeTo(nodeTo, star);
    nodeTo.addEdgeTo(nodeFrom, star);

}

public Node getNode(int nodeId) {

    for (Node iteratorNode : nodes) {
        if (iteratorNode.getNodeId() == nodeId)
            return iteratorNode;
    }
    return null;
}

public void removeNode(Node nodeToRemove) {
    nodes.remove(nodeToRemove);
    for (Node nodeIterator : nodes) {
        nodeIterator.popEdge(nodeToRemove);
    }
}

public void removeNode(int nodeIdToRemove) {
    Node nodeToRemove = getNode(nodeIdToRemove);
    removeNode(nodeToRemove);
}

    //Last three functions are used to create a specific graph to solve
public void populateEdges() {
    for (Node nodeFromIterator : nodes) {
        for (Node nodeToIterator : nodes) {
            nodeFromIterator.addEdgeTo(nodeToIterator);
        }
    }
}

public void replaceEdge(int nodeFromID, int nodeToID, Star star) {
    Node nodeFrom = getNode(nodeFromID);
    Node nodeTo = getNode(nodeToID);
    unlinkNodes(nodeFrom, nodeTo);
    linkNodesWith(nodeFrom, nodeTo, star);

}

private void unlinkNodes(Node nodeFrom, Node nodeTo) {
    nodeFrom.popEdge(nodeTo);
    nodeTo.popEdge(nodeFrom);
}
}