修改这个 8 谜题代码以打印中间状态以得出解决方案
// 常见的 8 谜题问题中的广度优先搜索用法。
import java.util.*;
class EightPuzzle {
Queue<String> q = new LinkedList<String>(); // Use of Queue Implemented using LinkedList for Storing All the Nodes in BFS.
Map<String,Integer> map = new HashMap<String, Integer>(); // HashMap is used to ignore repeated nodes
public static void main(String args[]){
String str="087465132"; // Input the Board State as a String with 0 as the Blank Space
EightPuzzle e = new EightPuzzle(); // New Instance of the EightPuzzle
e.add(str,0); // Add the Initial State
while(e.q.peek()!=null){
e.up(e.q.peek()); // Move the blank space up and add new state to queue
e.down(e.q.peek()); // Move the blank space down
e.left(e.q.peek()); // Move left
e.right(e.q.remove()); // Move right and remove the current node from Queue
}
System.out.println("Solution doesn't exist");
}
//Add method to add the new string to the Map and Queue
void add(String str,int n){
if(!map.containsKey(str)){
map.put(str,n);
q.add(str);
}
}
/* Each of the Methods below Takes the Current State of Board as String. Then the operation to move the blank space is done if possible.
After that the new string is added to the map and queue.If it is the Goal State then the Program Terminates.
*/
void up(String str){
int a = str.indexOf("0");
if(a>2){
String s = str.substring(0,a-3)+"0"+str.substring(a-2,a)+str.charAt(a-3)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void down(String str){
int a = str.indexOf("0");
if(a<6){
String s = str.substring(0,a)+str.substring(a+3,a+4)+str.substring(a+1,a+3)+"0"+str.substring(a+4);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void left(String str){
int a = str.indexOf("0");
if(a!=0 && a!=3 && a!=6){
String s = str.substring(0,a-1)+"0"+str.charAt(a-1)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void right(String str){
int a = str.indexOf("0");
if(a!=2 && a!=5 && a!=8){
String s = str.substring(0,a)+str.charAt(a+1)+"0"+str.substring(a+2);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
}
我想修改代码,以便它打印用于达到解决方案的中间状态,而不仅仅是说出达到解决方案的级别。
例如,给定这个板
1 4 2
3 0 5
6 7 8
(作为字符串142305678),
我希望它打印:(
1 4 2
3 0 5
6 7 8
作为字符串142305678)
1 0 2
3 4 5
6 7 8
(作为字符串102345678)
0 1 2
3 4 5
6 7 8
(作为字符串012345678)
通过查看代码,我相信这个中间字符串是通过存储的添加方法到队列中:
void add(String str,int n){
if(!map.containsKey(str)){
map.put(str,n);
q.add(str);
}
}
我没有使用 HashMap 的经验,我将如何查看存储在那里的中间状态?
// Breadth First Search Usage in the common Eight Puzzle Problem.
import java.util.*;
class EightPuzzle {
Queue<String> q = new LinkedList<String>(); // Use of Queue Implemented using LinkedList for Storing All the Nodes in BFS.
Map<String,Integer> map = new HashMap<String, Integer>(); // HashMap is used to ignore repeated nodes
public static void main(String args[]){
String str="087465132"; // Input the Board State as a String with 0 as the Blank Space
EightPuzzle e = new EightPuzzle(); // New Instance of the EightPuzzle
e.add(str,0); // Add the Initial State
while(e.q.peek()!=null){
e.up(e.q.peek()); // Move the blank space up and add new state to queue
e.down(e.q.peek()); // Move the blank space down
e.left(e.q.peek()); // Move left
e.right(e.q.remove()); // Move right and remove the current node from Queue
}
System.out.println("Solution doesn't exist");
}
//Add method to add the new string to the Map and Queue
void add(String str,int n){
if(!map.containsKey(str)){
map.put(str,n);
q.add(str);
}
}
/* Each of the Methods below Takes the Current State of Board as String. Then the operation to move the blank space is done if possible.
After that the new string is added to the map and queue.If it is the Goal State then the Program Terminates.
*/
void up(String str){
int a = str.indexOf("0");
if(a>2){
String s = str.substring(0,a-3)+"0"+str.substring(a-2,a)+str.charAt(a-3)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void down(String str){
int a = str.indexOf("0");
if(a<6){
String s = str.substring(0,a)+str.substring(a+3,a+4)+str.substring(a+1,a+3)+"0"+str.substring(a+4);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void left(String str){
int a = str.indexOf("0");
if(a!=0 && a!=3 && a!=6){
String s = str.substring(0,a-1)+"0"+str.charAt(a-1)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
void right(String str){
int a = str.indexOf("0");
if(a!=2 && a!=5 && a!=8){
String s = str.substring(0,a)+str.charAt(a+1)+"0"+str.substring(a+2);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("Solution Exists at Level "+map.get(s)+" of the tree");
System.exit(0);
}
}
}
}
I want to modify the code so that it prints the intermediate states used to reach the solution, instead of just saying the level on which the solution was reached.
For example, given this board
1 4 2
3 0 5
6 7 8
(as String 142305678)
I want it to print:
1 4 2
3 0 5
6 7 8
(as the String 142305678)
1 0 2
3 4 5
6 7 8
(as the String 102345678)
0 1 2
3 4 5
6 7 8
(as the String 012345678)
By looking at the code, I believe this intermediate strings are getting stored via the add method into the Queue:
void add(String str,int n){
if(!map.containsKey(str)){
map.put(str,n);
q.add(str);
}
}
I have no experience working with HashMap, how would I look into the intermediate states stored there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
以下是我如何满足您的请求,以获取链接开始到目标的跟踪:
stateHistory
映射,将每个状态与其前一个状态关联起来。checkCompletion
方法。add
方法以获取新旧状态(将深度查找内部化到该方法)并维护stateHistory
映射以及stateDepth
地图和议程
队列。checkCompletion
方法,将stateHistory
从目标状态(一旦达到)返回到原始状态(没有前驱状态)。运行修改后的代码会产生以下输出:
进一步修改以向前顺序(从开始到目标,而不是从目标到开始向后)打印序列,作为练习留给学生。
Here's how I addressed your request to get the trail linking start to goal:
stateHistory
map to relate each state to its predecessor.checkCompletion
method.add
method to take new and old states (internalized the depth lookup to that method) and to maintain thestateHistory
map as well as thestateDepth
map andagenda
queue.checkCompletion
method to walk thestateHistory
back from the goal state (once reached) to the original state (the one with no predecessor).Running the modified code produces this output:
Further modification to print the sequence in forward order (start-to-goal, rather than backwards from goal-to-start) is left as an exercise to the student.
对 Joel Neely 版本的一个小增强:初始化
e.stateDepth.put(null, -1);
简化了 add 方法中的逻辑,int newValue = stateDepth.get(oldState) + 1 ;
。A small enhancement to Joel Neely's version: initializing
e.stateDepth.put(null, -1);
simplifies the logic in the add method,int newValue = stateDepth.get(oldState) + 1;
.实际上,解决方案似乎存储在队列中。该映射仅用于检测重复状态。
完成后,将每个项目从队列中弹出并打印出来。
Actually, the solution appears to be stored in the queue. The map is only used to detect repeated states.
When it's finished, pop each item off the queue and print it out.
您只需要添加一行代码即可打印中间状态。
在add函数中,插入代码
整个代码将如下所示。
输出将如下所示。输出
但是,它还会打印对到达没有贡献的状态目标状态。
You just need to add one line of code to print the intermediate states.
In the add function, insert the code
The entire code will look like this.
The output will look like this.output
However, it also prints states that did not contribute to reach the goal state.