Java 深度优先搜索多个解决方案
我有一个迷宫,用无向图表示。 下面是它的样子:Java 深度优先搜索多个解决方案,java,stack,path-finding,depth-first-search,undirected-graph,Java,Stack,Path Finding,Depth First Search,Undirected Graph,我有一个迷宫,用无向图表示。 下面是它的样子: 11 3 2 3 0 3 1 4 5 4 5 7 6 7 7 8 8 9 9 10 6 11 7 11 在这个图中,使用深度优先搜索,它向我展示了从开始节点到目标节点的解决方案。我作为起始节点的输入是0,我的目标节点是1。我得到的通往目标的解决方案是0-3-11-7-5-4-1,但如果你再分析一下,还有另一个解决方案是0-3-11-6-7-5-4-1。我在这里的目的不是展示最佳解决方案,而是展示他们的解决方案有多少,并在以后分析最佳解决方案 我遇
11 3
2 3
0 3
1 4
5 4
5 7
6 7
7 8
8 9
9 10
6 11
7 11
在这个图中,使用深度优先搜索,它向我展示了从开始节点到目标节点的解决方案。我作为起始节点的输入是0
,我的目标节点是1
。我得到的通往目标的解决方案是0-3-11-7-5-4-1
,但如果你再分析一下,还有另一个解决方案是0-3-11-6-7-5-4-1
。我在这里的目的不是展示最佳解决方案,而是展示他们的解决方案有多少,并在以后分析最佳解决方案
我遇到的困难是我无法打印多个解决方案。它只打印0-3-11-7-5-4-1
其他内容,有时还打印0-3-11-6-7-5-4-1
,因为我希望打印其中两个。以下是我迄今为止完成的代码:
public class DepthFirstSearch {
private final boolean[] visited;
private final int sourceNode;
private final int[] pathTo;
/**
*
* @param mazeGraph
* @param sourceNode
* @param goal
*/
public DepthFirstSearch(MazeGraph mazeGraph, int sourceNode, int goal) {
this.sourceNode = sourceNode;
visited = new boolean[mazeGraph.node];
pathTo = new int[mazeGraph.node];
performRecursiveDFS(mazeGraph, sourceNode, goal);
}
//Perform recursive depth-first search
private void performRecursiveDFS(MazeGraph mazeGraph, int node, int goal) {
visited[node] = true;
for (int arc : mazeGraph.getAdjacencyList(node)) {
if (!visited[arc]) {
pathTo[arc] = node;
performRecursiveDFS(mazeGraph, arc, goal);
}
}
}
//Put path to goal in the stack
public Stack<Integer> pathTo(int toGoalNode) {
if (!visited[toGoalNode]) {
return null;
}
Stack<Integer> pathStack = new Stack<Integer>();
for (int pathToGoalNode = toGoalNode; pathToGoalNode != sourceNode; pathToGoalNode = pathTo[pathToGoalNode]) {
pathStack.push(pathToGoalNode);
}
pathStack.push(sourceNode);
reverseStack(pathStack);
return pathStack;
}
//Reverse the stack
public void reverseStack(Stack<Integer> stackToBeReverse) {
if (stackToBeReverse.isEmpty()) {
return;
}
int bottom = popBottomStack(stackToBeReverse);
reverseStack(stackToBeReverse);
stackToBeReverse.push(bottom);
}
//Pop the bottom of the stack
private int popBottomStack(Stack<Integer> stackToBeReverse) {
int popTopStack = stackToBeReverse.pop();
if (stackToBeReverse.isEmpty()) {
return popTopStack;
} else {
int bottomStack = popBottomStack(stackToBeReverse);
stackToBeReverse.push(popTopStack);
return bottomStack;
}
}
//Print the path to goal
public void printPath( int toGoal) {
if (visited[toGoal]) {
out.println("Path to Goal: ");
for (int x : pathTo(toGoal)) {
if (x == toGoal) {
out.print(x);
} else {
out.print(x + " - ");
}
}
out.println();
}
}
/**
*
* @param args
*/
public static void main(String[] args) {
Scanner scanFile = new Scanner(in);
out.print("Enter maze file: ");
String file = scanFile.nextLine();
out.print("Enter start node: ");
int startNode = scanFile.nextInt();
out.print("Enter goal node: ");
int goalNode = scanFile.nextInt();
MazeGraph mazeGraph = new MazeGraph(file);
mazeGraph.print();
out.println("Starting at 0\nGoal at 1");
DepthFirstSearch depthFirstSearch = new DepthFirstSearch(mazeGraph, startNode, goalNode);
depthFirstSearch.printPath( goalNode);
}
}
公共类DepthFirstSearch{
参观私人住宅;
私有最终int源节点;
私有最终int[]路径;
/**
*
*@param mazeGraph
*@param sourceNode
*@param-goal
*/
公共深度优先搜索(MazeGraph MazeGraph,int sourceNode,int goal){
this.sourceNode=sourceNode;
visited=新布尔值[mazeGraph.node];
pathTo=新的int[mazeGraph.node];
performRecursiveDFS(mazeGraph、sourceNode、goal);
}
//执行递归深度优先搜索
私有void performRecursiveDFS(MazeGraph MazeGraph,int节点,int目标){
已访问[节点]=真;
for(int-arc:mazeGraph.getAdjacencyList(节点)){
如果(!已访问[arc]){
路径到[弧]=节点;
绩效考核(马自格拉夫、弧线、目标);
}
}
}
//将目标路径放入堆栈中
公共堆栈路径(int-toGoalNode){
如果(!已访问[toGoalNode]){
返回null;
}
堆栈路径堆栈=新堆栈();
对于(int-pathToGoalNode=toGoalNode;pathToGoalNode!=sourceNode;pathToGoalNode=pathTo[pathToGoalNode]){
推送(pathToGoalNode);
}
push(sourceNode);
反向堆栈(路径堆栈);
返回路径堆栈;
}
//倒立
公共无效反向堆栈(堆栈反向堆栈){
if(stackToBeReverse.isEmpty()){
返回;
}
int bottom=popBottomStack(stackToBeReverse);
反向堆叠(stackToBeReverse);
向上推(底部);
}
//弹出堆栈的底部
私有int popBottomStack(堆栈堆栈到反向){
int-popTopStack=stackToBeReverse.pop();
if(stackToBeReverse.isEmpty()){
返回popTopStack;
}否则{
int bottomStack=popBottomStack(stackToBeReverse);
堆栈反向推送(popTopStack);
返回底部堆栈;
}
}
//打印目标路径
公共void打印路径(int-toGoal){
如果(访问[多哥]){
println(“目标路径:”);
用于(整数x:pathTo(多哥)){
如果(x==多哥){
打印(x);
}否则{
打印输出(x+“-”);
}
}
out.println();
}
}
/**
*
*@param args
*/
公共静态void main(字符串[]args){
扫描仪扫描文件=新扫描仪(英寸);
打印(“输入迷宫文件:”);
String file=scanFile.nextLine();
打印(“输入开始节点:”);
int startNode=scanFile.nextInt();
打印(“输入目标节点:”);
int goalNode=scanFile.nextInt();
MazeGraph MazeGraph=新MazeGraph(文件);
mazeGraph.print();
out.println(“从0开始\n从1开始”);
DepthFirstSearch DepthFirstSearch=新的DepthFirstSearch(mazeGraph、startNode、goalNode);
depthFirstSearch.printPath(goalNode);
}
}
MazeGraph源代码:
public class MazeGraph {
final int node; //Declaring constant value of a node.
int arc;
List<Integer>[] adjacencyList;
final static Set<Integer> setOfNodes = new HashSet<Integer>();
/**
* This constructors takes an integer parameter for reading node indexes in
* a list of adjacent nodes.
*
* @param node - integer parameter for passing the nodes value from the file
* and create a list of adjacent nodes.
*/
MazeGraph(int node) {
this.node = node;
this.arc = 0;
adjacencyList = (List<Integer>[]) new List[node];
for (int index = 0; index < node; index++) {
adjacencyList[index] = new LinkedList<Integer>();
}
}
/**
* The main constructor that takes a String for reading maze file.
*
* @param mazeFile
*/
public MazeGraph(String mazeFile) {
this(getNodeSize(mazeFile));
Scanner scan;
try {
//Scan maze file.
scan = new Scanner(new File(mazeFile));
/*loop when it has next integer then read two nodes from the file and add arc for it.*/
while (scan.hasNextInt()) {
int node1 = scan.nextInt();
int node2 = scan.nextInt();
addArc(node1, node2);
}
} catch (FileNotFoundException ex) {
out.println("File not found.");
}
}
/**
* This method returns a size of the set of nodes by taking a String
* parameter which the name of the maze file.
*
* @param mazeFile - String parameter for reading maze file for scanning the
* size of the nodes.
* @return - returns an integer value for the size of the set of nodes.
*/
public static int getNodeSize(String mazeFile) {
Scanner scanNodeSize;
try {
scanNodeSize = new Scanner(new File(mazeFile));
while (scanNodeSize.hasNextInt()) {
int node1 = scanNodeSize.nextInt();
int node2 = scanNodeSize.nextInt();
setOfNodes.add(node1);
setOfNodes.add(node2);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return setOfNodes.size();
}
/**
* This method adds an arc by adding two different nodes in array of list
* called adjacency list.
*
* @param node1 - first node.
* @param node2 - next node.
*/
private void addArc(int node1, int node2) {
arc++; //Increase arc by one whenever this addArc method is called.
adjacencyList[node1].add(node2);
adjacencyList[node2].add(node1);
}
/**
* Print the nodes and its arcs by looping through the adjacency list.
*/
public void print() {
out.println(node + " Nodes, " + arc + " Arcs \n");
for (int n = 0; n < node; n++) {
out.print(n + " connected to ");
for (int w : adjacencyList[n]) {
out.print(w + " ");
}
out.println();
}
}
/**
* This method returns a list of nodes to allow objects to be the target for
* "for-each" statement.
*
* @param nodes - an Integer parameter for getting the number of nodes in a
* list.
* @return - returns a list of nodes.
*/
public Iterable<Integer> getAdjacencyList(int nodes) {
return adjacencyList[nodes];
}
/**
* Unit testing To test if it reads the file.
*
* @param args
*/
public static void main(String[] args) {
out.print("Enter maze file: ");
Scanner scanFile = new Scanner(in);
String file = scanFile.nextLine();
MazeGraph G = new MazeGraph(file);
G.print();
}
}
公共类MazeGraph{
final int node;//声明节点的常量值。
内弧;
列表[]邻接列表;
最终静态集合setOfNodes=新HashSet();
/**
*此构造函数采用整数参数来读取中的节点索引
*相邻节点的列表。
*
*@param node-用于从文件中传递节点值的整数参数
*并创建相邻节点的列表。
*/
MazeGraph(内部节点){
this.node=节点;
这是0.arc=0;
邻接列表=(列表[])新列表[节点];
for(int index=0;indexprivate void performRecursiveDFS(MazeGraph mazeGraph, int node, int goal) {
visited[node] = true; //set visited
for (int arc : mazeGraph.getAdjacencyList(node)) {
if (!visited[arc]) {
pathTo[arc] = node;
performRecursiveDFS(mazeGraph, arc, goal);
}
}
visited[node] = false; //unset visited
}
private void performRecursiveDFS(MazeGraph mazeGraph, int node, int goal) {
visited[node] = true; //set visited
if(node == goal) { //found the goal? Good, print it and backtrack.
printPath(goal);
} else {
for (int arc : mazeGraph.getAdjacencyList(node)) {
if (!visited[arc]) {
pathTo[arc] = node;
performRecursiveDFS(mazeGraph, arc, goal);
}
}
}
visited[node] = false; //unset visited
}
$ java DepthFirstSearch
Enter maze file: maze
Enter start node: 0
Enter goal node: 1
12 Nodes, 12 Arcs
0 connected to 3
1 connected to 4
2 connected to 3
3 connected to 11 2 0
4 connected to 1 5
5 connected to 4 7
6 connected to 7 11
7 connected to 5 6 8 11
8 connected to 7 9
9 connected to 8 10
10 connected to 9
11 connected to 3 6 7
Starting at 0
Goal at 1
Path to Goal:
0 - 3 - 11 - 6 - 7 - 5 - 4 - 1
Path to Goal:
0 - 3 - 11 - 7 - 5 - 4 - 1