作业要解决八数码问题,刚开始确实没什么思路,看了很多网上大神的方法,自己蛮有收获,决定把自己调试的代码分享下。第一次发可能方法不是太好,见谅!!!
<pre name="code" class="java">package com.whl;
public class BFSMain {
public static void main(String args[]) {
BFS bfs = new BFS();
bfs.init();//初始化目标和初始状态
bfs.bfs();
}
}
//创建节点类
class Node {
int num[] = new int[9];
int last;
int space;
}
//搜索方法类
class BFS {
Node state[] = new Node[362881];//存放搜索到的节点数组
Node goal = new Node();
Node temp = new Node();
int head = 0;//对的头节点
int tail = 0;//对的尾节点
int sampleCount=0;//与目标棋盘相同的个数
public void bfs() {
int k;//方向变量
if (!judge()) {
System.out.println("目标状态与初始状态的逆序奇偶性不同,目标不可达!");
return;
}
while (head <= tail && tail < 362881) {
//k表示空格移动的是个方向
for (k = 1; k <=4; k++) {
for (int i = 0; i < 9; i++) {
temp.num[i] = state[head].num[i];
}
temp.space = state[head].space;
//扩展节点
if (expend(temp, k)) {
if (repeat(state, temp, tail)) {
continue;
}
tail++;
for (int j = 0; j < 9; j++) {
state[tail].num[j] = temp.num[j];
state[tail].space = temp.space;
state[tail].last = head;
}
//当相同个数达到9,已找到目标节点
if(sampleCount==9){
System.out.println("已找到目标结果,输出路径:");
tail++;
state[tail].last = tail - 1;
printPath(state, tail);
return;
}
}
}
head++;
}
System.out.println("很遗憾,未找到目标结果!");
}
// 判断目标状态是否可达
public boolean judge() {
int count1 = 0;
int count2 = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < i; j++) {
if (state[0].num[i] > state[0].num[j]) {
count1++;
}
if (goal.num[i] > goal.num[j]) {
count2++;
}
}
}
if (count1 % 2 == count2 % 2) {
return true;
}
return false;
}
// 四个方向移动空格
public boolean expend(Node temp, int k) {
if (k == 2 && (temp.space == 3 || temp.space == 6))
return false;
if (k == 3 && (temp.space == 2 || temp.space == 5))
return false;
int i = temp.space - 5 + 2 * k;
if (i < 0 || i > 8)
return false;
temp.num[temp.space] = temp.num[i];
temp.num[i] = 0;
temp.space = i;
int sample=0;
for(int m=0;m<9;m++){
if(temp.num[m]==goal.num[m]){
sample++;
}
}
if(sample>=sampleCount){
sampleCount=sample;
return true;
}
return false;
}
// 判断是否有重复节点
public boolean repeat(Node state[], Node temp, int tail) {
int i, j;
for (i = 0; i <= tail; i++) {
for (j = 0; j < 9; j++)
if (state[i].num[j] != temp.num[j])
break;
if (j == 9)
return true;
}
return false;
}
// 递归打印路径
public void printPath(Node state[], int tail) {
if (tail > 0) {
tail = state[tail].last;
printPath(state, tail);
for (int j = 0; j < 9; j++) {
System.out.print(state[tail].num[j] + "\t");
if ((j + 1) % 3 == 0) {
System.out.println("\n");
}
}
System.out.print("*******************\n");
}
}
// 初始化节点
public void init() {
for (int i = 0; i < state.length; i++) {
state[i] = new Node();
}
state[0].num[0] = 2;
state[0].num[1] = 8;
state[0].num[2] = 3;
state[0].num[3] = 1;
state[0].num[4] = 0;
state[0].num[5] = 4;
state[0].num[6] = 7;
state[0].num[7] = 6;
state[0].num[8] = 5;
state[0].last = 0;
state[0].space = 4;
goal.num[0] = 1;
goal.num[1] = 2;
goal.num[2] = 3;
goal.num[3] = 7;
goal.num[4] = 8;
goal.num[5] = 4;
goal.num[6] = 0;
goal.num[7] = 6;
goal.num[8] = 5;
goal.space = 6;
}
}