完整源码 - Eclipse项目文件 - GitHub地址


题目描述


关于本算法

两个晚上写完的,不足之处多多指教…

启发函数的选择:

一开始选用不在位数码个数+节点深度作为启发函数,效果不是很好。

后来改用所有数码到目标位置的矩形距离+节点深度作为启发函数,计算出:

  • 从初始到达目标状态深度为14(步),见附录
  • 一共进行了68次拓展
  • 最后一次拓展时Open表Board个数为70
/*** 设计一个启发函数,利用A*算法求解15数码问题* * 要求: 尽可能用与A*算法一致的思路实现算法, 力求简单明了地给出一个解. *      1)打印并上交带有关键步骤说明的程序代码.*      2)演示运行过程,并回答老师的询问* * @author luyang.gong* * f(n)=g(n)+h(n)* g(n):已经走过* h(n):对未来的估计* * Begin: 读入初始状态和目标状态,并计算初始状态评价函数值f; 初始化两个open表和closed表,将初始状态放入open表中If(open表为空)查找失败;End ifelse  ①   在open表中找到评价值最小的节点,作为当前结点,并放入closed表中; ②    判断当前结点状态和目标状态是否一致,若一致,跳出循环;否则跳转到③; ③    对当前结点,分别按照上、下、左、右方向移动空格位置来扩展新的状态结点,并计算新扩展结点的评价值f并记录其父节点; ④ 对于新扩展的状态结点,进行如下操作:A.新节点既不在open表中,也不在closed表中,则ADD (mj, OPEN);B.新节点在open表中,则 IF f(n-mk) < f(mk)  THEN f(mk):=f(n-mk), C.新节点在closed表中,则IF f(n-ml) < f(ml)  THEN f(ml):=f(n-ml),     ⑤ 把当前结点从open表中移除; End ifEnd**/




题解 - 目录结构


题解 - 代码实现 Java

Main.java

public class Main {public static Board beginBoard = new Board(Init.BEGINARR);public static Board endBoard = new Board(Init.ENDARR);public static void main(String[] args) {OpenTable openTable = new OpenTable();openTable.tbArr.add(beginBoard);// 这里需要拷贝逻辑 否则复制的只是指针CloseTable closeTable = new CloseTable();System.out.println(openTable);Board curBoard = null;int count = 0;while (openTable.tbArr.size() != 0) {System.out.println("第" + ++count + "次拓展");openTable.sortItSelf();curBoard = openTable.getMinBoard();closeTable.tbArr.add(curBoard);// 是否为endif (curBoard.equals(endBoard)) {System.out.println("SUCCESS:" + curBoard);while (curBoard.parentBoard != null) {System.out.println("上一步:");System.out.println(curBoard.parentBoard);curBoard = curBoard.parentBoard;}break;}// 4方向拓展for (int s = 0; s < 4; s++) {Board newBoard = null;if (s == 0) {if (curBoard.canDown()) {newBoard = curBoard.goDown();} else {continue;}} else if (s == 1) {if (curBoard.canUp()) {newBoard = curBoard.goUp();} else {continue;}} else if (s == 2) {if (curBoard.canRight()) {newBoard = curBoard.goRight();} else {continue;}} else if (s == 3) {if (curBoard.canLeft()) {newBoard = curBoard.goLeft();} else {continue;}}if (openTable.hasBoard(newBoard)) {// 新节点在open表中 比较已有fn和新节点fn的大小Board oldBoard = openTable.getBoardByArr(newBoard.arr);if (newBoard.fn < oldBoard.fn) {// 新的比旧的fn小// 更新指针newBoard.childBoards = oldBoard.childBoards;for (int i = 0; i < newBoard.childBoards.size(); i++) {newBoard.childBoards.get(i).parentBoard = newBoard;}// 删旧的 增新的openTable.tbArr.remove(openTable.getIndex(oldBoard));openTable.tbArr.add(newBoard);System.out.println("openTable:update");}} else if (closeTable.hasBoard(newBoard)) {// 新节点在close表中Board oldBoard = closeTable.getBoardByArr(newBoard.arr);if (newBoard.fn < oldBoard.fn) {newBoard.childBoards = oldBoard.childBoards;for (int i = 0; i < newBoard.childBoards.size(); i++) {newBoard.childBoards.get(i).parentBoard = newBoard;}closeTable.tbArr.remove(closeTable.getIndex(oldBoard));
//                      closeTable.tbArr.add(newBoard);openTable.tbArr.add(newBoard);// 重新放回open表中System.out.println("openTable:update");}} else {// 两表都不在openTable.tbArr.add(newBoard);System.out.println("openTable:add");}}openTable.tbArr.remove(openTable.getIndex(curBoard));}}
}

Init.java

package cn.hanquan.ai;public class Init {/*** 数组大小*/public static final int SIZE = 4;/*** 初始状态*/public static final int[][] BEGINARR = { { 5, 1, 2, 4 }, { 9, 6, 3, 8 }, { 13, 15, 10, 11 }, { 14, 0, 7, 12 } };/*** 目标状态*/public static final int[][] ENDARR = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 0 } };
}

Utils.java

package cn.hanquan.ai;public class Utils {/*** 计算不在位的将牌个数* @param tbArr 15数码的一个状态* @return 不在位的将牌个数*/public static int getAbsentCount(Board curBoard, Board endBoard) {// System.out.println(curBoard);// System.out.println(endBoard);int count = 0;for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {label: for (int m = 0; m < Init.SIZE; m++) {for (int n = 0; n < Init.SIZE; n++) {if (curBoard.arr[i][j] == endBoard.arr[m][n]) {count += getDistance(i, j, m, n);break label;}}}}}return count;}/*** 计算两坐标的矩形距离* @param x1* @param y1* @param x2* @param y2* @return*/public static int getDistance(int x1,int y1,int x2,int y2) {return Math.abs(x1-x2)+Math.abs(y1-y2);}/*** 计算不在位的将牌个数 重载* @param arr 15数码的一个状态* @return 不在位的将牌个数*/public static int getAbsentCount(Board curBoard, int[][] arr) {// System.out.println(curBoard);// System.out.println(endBoard);int count = 0;for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (curBoard.arr[i][j] != 0 && curBoard.arr[i][j] != arr[i][j]) {count++;}}}return count;}
}

Board.java

package cn.hanquan.ai;import java.util.ArrayList;
import java.util.Arrays;public class Board {/*** 将牌状态*/public int[][] arr;/*** 总耗散值*/public int fn=-1;/*** 当前已走深度(耗散值)*/public int dn=0;/*** 不在位将牌个数(耗散值)*/public int hn=-1;/*** 父节点*/public Board parentBoard;/*** 子节点列表*/public ArrayList<Board> childBoards=new ArrayList<Board>();public Board(int[][] arr) {super();this.arr = arr;this.dn = 0;this.hn = Utils.getAbsentCount(this, Init.ENDARR);this.fn = this.dn + this.hn;}public Board() {super();}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("\n");for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {sb.append(arr[i][j] + "\t");}sb.append("\n");}sb.append("fn gn hn = " + fn + " " + dn + " " + hn+"\n");return sb.toString();}/*** 复制本身arr数值* @return*/public int[][] copySelfArr() {int[][] newArr = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {newArr[i][j] = arr[i][j];}}return newArr;}/*** 判断两个board是否arr值相等* @param board* @return*/public boolean equals(Board board) {boolean isEqual = true;for (int i = 0; i < Init.SIZE && isEqual == true; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] != board.arr[i][j]) {isEqual = false;break;}}}return isEqual;}/*** 重载,判断board和arr是否值相等* @param board* @return*/public boolean equals(int[][] array) {boolean isEqual = true;for (int i = 0; i < Init.SIZE && isEqual == true; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] != array[i][j]) {isEqual = false;break;}}}return isEqual;}/*** 是否可以向下移动* @return*/public boolean canDown() {boolean isOK = true;label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] == 0 && i == Init.SIZE-1) {isOK = false;break label;}}}System.out.println("canDown:"+isOK);return isOK;}/*** 是否可以向右移动* @return*/public boolean canRight() {boolean isOK = true;label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] == 0 && j == Init.SIZE-1) {isOK = false;break label;}}}System.out.println("canRight:"+isOK);return isOK;}/*** 是否可以向左移动* @return*/public boolean canLeft() {boolean isOK = true;label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] == 0 && j == 0) {isOK = false;break label;}}}System.out.println("canLeft:"+isOK);return isOK;}/*** 是否可以向上移动* @return*/public boolean canUp() {boolean isOK = true;label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (arr[i][j] == 0 && i == 0) {isOK = false;break label;}}}System.out.println("canUp:" + isOK);return isOK;}/*** 向下移动* @return*/public Board goDown() {System.out.println("Go Down");Board newBoard = new Board(this.copySelfArr());label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (newBoard.arr[i][j] == 0) {int t;t = newBoard.arr[i][j];newBoard.arr[i][j] = newBoard.arr[i + 1][j];newBoard.arr[i + 1][j] = t;break label;// 这里label退出循环!!避免重复操作!!}}}newBoard.dn = this.dn + 1;// 深度newBoard.hn = Utils.getAbsentCount(newBoard, Main.endBoard);// 不在位将牌个数newBoard.fn = newBoard.dn + newBoard.hn;newBoard.parentBoard=this;this.childBoards.add(newBoard);return newBoard;}/*** 向上移动* @return*/public Board goUp() {System.out.println("Go Up");Board newBoard = new Board(this.copySelfArr());//这里不能这样复制label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (newBoard.arr[i][j] == 0) {int t;t = newBoard.arr[i][j];newBoard.arr[i][j] = newBoard.arr[i - 1][j];newBoard.arr[i - 1][j] = t;break label;}}}newBoard.dn = this.dn + 1;// 深度newBoard.hn = Utils.getAbsentCount(newBoard, Main.endBoard);// 不在位将牌个数newBoard.fn = newBoard.dn + newBoard.hn;newBoard.parentBoard = this;this.childBoards.add(newBoard);return newBoard;}/*** 向右移动* @return*/public Board goRight() {System.out.println("Go Right");Board newBoard = new Board(this.copySelfArr());label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (newBoard.arr[i][j] == 0) {int t;t = newBoard.arr[i][j];newBoard.arr[i][j] = newBoard.arr[i][j+1];newBoard.arr[i][j+1] = t;break label;}}}newBoard.dn = this.dn + 1;// 深度newBoard.hn = Utils.getAbsentCount(newBoard, Main.endBoard);// 不在位将牌个数newBoard.fn = newBoard.dn + newBoard.hn;newBoard.parentBoard=this;this.childBoards.add(newBoard);return newBoard;}/*** 向左移动* @return*/public Board goLeft() {System.out.println("Go Left");Board newBoard = new Board(this.copySelfArr());label: for (int i = 0; i < Init.SIZE; i++) {for (int j = 0; j < Init.SIZE; j++) {if (newBoard.arr[i][j] == 0) {int t;t = newBoard.arr[i][j];newBoard.arr[i][j] = newBoard.arr[i][j-1];newBoard.arr[i][j-1] = t;break label;}}}newBoard.dn = this.dn + 1;// 深度newBoard.hn = Utils.getAbsentCount(newBoard, Main.endBoard);// 不在位将牌个数newBoard.fn = newBoard.dn + newBoard.hn;newBoard.parentBoard=this;this.childBoards.add(newBoard);return newBoard;}
}

OpenTable.java

package cn.hanquan.ai;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;/*** Open表* @author luyang.gong**/
public class OpenTable {public ArrayList<Board> tbArr = new ArrayList<Board>();/*** Open表排序*/public void sortItSelf() {Collections.sort(tbArr, new Comparator<Board>() {@Overridepublic int compare(Board b1, Board b2) {// 重写 Comparator 函数if (b1.fn < b2.fn)//小的排前面return -1;else if (b1.fn > b2.fn)return 1;elsereturn 0;}});System.out.println("Open表Board个数:"+this.tbArr.size());
//      System.out.println("排序后:\n"+tbArr);System.out.println("最小fn="+tbArr.get(0));System.out.println("\n");}/*** 返回fn最小Board* @return*/public Board getMinBoard() {return tbArr.get(0);}/*** 判断Table中是否包含某个board* @param board* @return*/public boolean hasBoard(Board board) {boolean hasBoard = false;for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(board)) {hasBoard = true;break;}}return hasBoard;}/*** 获取Board在OpenTable中的索引* @param board* @return 索引值*/public int getIndex(Board board) {int index=-1;for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(board)) {index = i;break;}}return index;}public Board getBoardByArr(int[][] array){for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(array)) {return tbArr.get(i);}}try {throw new Exception("Opentable:不存在该arr!");} catch (Exception e) {e.printStackTrace();}return null;}@Overridepublic String toString() {StringBuilder sb=new StringBuilder();sb.append("\n");sb.append("OpenTable:\n");for(int i=0;i<tbArr.size();i++) {sb.append(tbArr.get(i).toString());sb.append("\n");}return sb.toString();}
}

CloseTable.java

package cn.hanquan.ai;import java.util.ArrayList;public class CloseTable {ArrayList<Board> tbArr = new ArrayList<Board>();/*** 判断Table中是否包含某个board* @param board* @return*/public boolean hasBoard(Board board) {boolean hasBoard = false;for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(board)) {hasBoard = true;break;}}return hasBoard;}/*** 获取Board在CloseTable中的索引* @param board* @return 索引值*/public int getIndex(Board board) {int index=-1;for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(board)) {index = i;break;}}return index;}public Board getBoardByArr(int[][] array){for (int i = 0; i < tbArr.size(); i++) {if (tbArr.get(i).equals(array)) {return tbArr.get(i);}}try {throw new Exception("Closetable:不存在该arr!");} catch (Exception e) {e.printStackTrace();}return null;}
}

附:输出结果

(这个倒着看,在SUCCESS之后,反向输出了一下过程)

OpenTable:5  1   2   4
9   6   3   8
13  15  10  11
14  0   7   12
fn gn hn = 12 0 12第1次拓展
Open表Board个数:1
最小fn=
5   1   2   4
9   6   3   8
13  15  10  11
14  0   7   12
fn gn hn = 12 0 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第2次拓展
Open表Board个数:3
最小fn=
5   1   2   4
9   6   3   8
13  0   10  11
14  15  7   12
fn gn hn = 17 1 16canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第3次拓展
Open表Board个数:5
最小fn=
5   1   2   4
9   6   3   8
13  10  0   11
14  15  7   12
fn gn hn = 16 2 14canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第4次拓展
Open表Board个数:7
最小fn=
5   1   2   4
9   6   3   8
13  10  7   11
14  15  0   12
fn gn hn = 15 3 12canDown:false
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第5次拓展
Open表Board个数:8
最小fn=
5   1   2   4
9   6   3   8
13  10  11  0
14  15  7   12
fn gn hn = 15 3 12canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第6次拓展
Open表Board个数:9
最小fn=
5   1   2   4
9   6   3   8
13  10  11  12
14  15  7   0
fn gn hn = 14 4 10canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第7次拓展
Open表Board个数:9
最小fn=
5   1   2   4
9   6   3   8
13  10  7   11
14  15  12  0
fn gn hn = 16 4 12canDown:false
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第8次拓展
Open表Board个数:9
最小fn=
5   1   2   4
9   6   3   8
13  10  7   11
14  0   15  12
fn gn hn = 16 4 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第9次拓展
Open表Board个数:10
最小fn=
5   1   2   4
9   6   3   8
13  15  10  11
14  7   0   12
fn gn hn = 17 1 16canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第10次拓展
Open表Board个数:11
最小fn=
5   1   2   4
9   6   3   8
13  15  10  11
0   14  7   12
fn gn hn = 17 1 16canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:false
第11次拓展
Open表Board个数:11
最小fn=
5   1   2   4
9   6   3   8
13  10  11  12
14  15  0   7
fn gn hn = 17 5 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第12次拓展
Open表Board个数:12
最小fn=
5   1   2   4
9   6   3   8
13  10  7   11
0   14  15  12
fn gn hn = 17 5 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:false
第13次拓展
Open表Board个数:12
最小fn=
5   1   2   4
9   6   3   0
13  10  11  8
14  15  7   12
fn gn hn = 18 4 14canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
openTable:add
第14次拓展
Open表Board个数:13
最小fn=
5   1   2   4
9   6   3   8
13  15  10  11
14  7   12  0
fn gn hn = 18 2 16canDown:false
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第15次拓展
Open表Board个数:13
最小fn=
5   1   2   4
9   6   3   8
0   15  10  11
13  14  7   12
fn gn hn = 18 2 16canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:false
第16次拓展
Open表Board个数:14
最小fn=
5   1   2   4
9   6   3   8
13  10  11  12
14  0   15  7
fn gn hn = 18 6 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第17次拓展
Open表Board个数:15
最小fn=
5   1   2   4
9   6   3   8
0   10  7   11
13  14  15  12
fn gn hn = 18 6 12canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:false
第18次拓展
Open表Board个数:16
最小fn=
5   1   2   4
9   6   0   8
13  10  3   11
14  15  7   12
fn gn hn = 19 3 16canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第19次拓展
Open表Board个数:18
最小fn=
5   1   2   4
9   6   3   8
13  10  7   0
14  15  12  11
fn gn hn = 19 5 14canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
openTable:add
第20次拓展
Open表Board个数:19
最小fn=
5   1   2   4
9   6   3   8
13  0   7   11
14  10  15  12
fn gn hn = 19 5 14canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第21次拓展
Open表Board个数:21
最小fn=
5   1   2   4
0   6   3   8
9   15  10  11
13  14  7   12
fn gn hn = 19 3 16canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:false
第22次拓展
Open表Board个数:22
最小fn=
5   1   2   4
9   6   3   8
15  0   10  11
13  14  7   12
fn gn hn = 19 3 16canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第23次拓展
Open表Board个数:24
最小fn=
5   1   2   4
9   6   3   8
15  10  0   11
13  14  7   12
fn gn hn = 18 4 14canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第24次拓展
Open表Board个数:26
最小fn=
5   1   2   4
9   6   3   8
15  10  7   11
13  14  0   12
fn gn hn = 17 5 12canDown:false
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第25次拓展
Open表Board个数:27
最小fn=
5   1   2   4
9   6   3   8
15  10  11  0
13  14  7   12
fn gn hn = 17 5 12canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第26次拓展
Open表Board个数:28
最小fn=
5   1   2   4
9   6   3   8
15  10  11  12
13  14  7   0
fn gn hn = 16 6 10canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第27次拓展
Open表Board个数:28
最小fn=
5   1   2   4
9   6   3   8
15  10  7   11
13  14  12  0
fn gn hn = 18 6 12canDown:false
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第28次拓展
Open表Board个数:28
最小fn=
5   1   2   4
9   6   3   8
13  10  11  12
0   14  15  7
fn gn hn = 19 7 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:false
第29次拓展
Open表Board个数:28
最小fn=
5   1   2   4
0   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 19 7 12canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:false
第30次拓展
Open表Board个数:29
最小fn=
5   1   2   4
9   6   3   8
10  0   7   11
13  14  15  12
fn gn hn = 19 7 12canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第31次拓展
Open表Board个数:31
最小fn=
5   1   2   4
9   6   3   8
15  10  11  12
13  14  0   7
fn gn hn = 19 7 12canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第32次拓展
Open表Board个数:32
最小fn=
5   1   2   4
9   0   3   8
13  6   10  11
14  15  7   12
fn gn hn = 20 2 18canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第33次拓展
Open表Board个数:34
最小fn=
5   1   2   4
9   6   3   8
0   13  10  11
14  15  7   12
fn gn hn = 20 2 18canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:false
第34次拓展
Open表Board个数:35
最小fn=
5   1   2   4
9   6   3   8
13  15  0   11
14  7   10  12
fn gn hn = 20 2 18canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第35次拓展
Open表Board个数:37
最小fn=
5   1   2   4
9   6   3   8
13  15  11  0
14  7   10  12
fn gn hn = 19 3 16canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第36次拓展
Open表Board个数:38
最小fn=
5   1   2   4
9   6   3   8
13  15  11  12
14  7   10  0
fn gn hn = 18 4 14canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第37次拓展
Open表Board个数:38
最小fn=
5   1   2   4
9   6   3   8
13  10  0   12
14  15  11  7
fn gn hn = 20 6 14canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第38次拓展
Open表Board个数:40
最小fn=
5   1   2   4
9   6   8   0
13  10  3   11
14  15  7   12
fn gn hn = 20 4 16canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第39次拓展
Open表Board个数:41
最小fn=
5   1   2   4
9   6   3   8
13  7   0   11
14  10  15  12
fn gn hn = 20 6 14canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第40次拓展
Open表Board个数:43
最小fn=
5   1   2   4
9   6   3   8
13  7   11  0
14  10  15  12
fn gn hn = 19 7 12canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第41次拓展
Open表Board个数:44
最小fn=
5   1   2   4
9   6   3   8
13  7   11  12
14  10  15  0
fn gn hn = 18 8 10canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第42次拓展
Open表Board个数:44
最小fn=
0   1   2   4
5   6   3   8
9   15  10  11
13  14  7   12
fn gn hn = 20 4 16canDown:true
Go Down
canUp:false
canRight:true
Go Right
openTable:add
canLeft:false
第43次拓展
Open表Board个数:44
最小fn=
1   0   2   4
5   6   3   8
9   15  10  11
13  14  7   12
fn gn hn = 19 5 14canDown:true
Go Down
openTable:add
canUp:false
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第44次拓展
Open表Board个数:45
最小fn=
1   2   0   4
5   6   3   8
9   15  10  11
13  14  7   12
fn gn hn = 18 6 12canDown:true
Go Down
openTable:add
canUp:false
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第45次拓展
Open表Board个数:46
最小fn=
1   2   3   4
5   6   0   8
9   15  10  11
13  14  7   12
fn gn hn = 17 7 10canDown:true
Go Down
openTable:add
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第46次拓展
Open表Board个数:48
最小fn=
1   2   3   4
5   6   10  8
9   15  0   11
13  14  7   12
fn gn hn = 18 8 10canDown:true
Go Down
openTable:add
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第47次拓展
Open表Board个数:50
最小fn=
1   2   3   4
5   6   10  8
9   15  7   11
13  14  0   12
fn gn hn = 17 9 8canDown:false
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第48次拓展
Open表Board个数:51
最小fn=
1   2   3   4
5   6   10  8
9   15  11  0
13  14  7   12
fn gn hn = 17 9 8canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第49次拓展
Open表Board个数:52
最小fn=
1   2   3   4
5   6   10  8
9   15  11  12
13  14  7   0
fn gn hn = 16 10 6canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第50次拓展
Open表Board个数:52
最小fn=
1   2   3   4
5   6   8   0
9   15  10  11
13  14  7   12
fn gn hn = 18 8 10canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第51次拓展
Open表Board个数:53
最小fn=
1   2   3   4
5   6   10  8
9   15  7   11
13  14  12  0
fn gn hn = 18 10 8canDown:false
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第52次拓展
Open表Board个数:53
最小fn=
1   2   4   0
5   6   3   8
9   15  10  11
13  14  7   12
fn gn hn = 19 7 12canDown:true
Go Down
openTable:add
canUp:false
canRight:false
canLeft:true
Go Left
第53次拓展
Open表Board个数:53
最小fn=
1   2   3   4
5   6   10  8
9   0   15  11
13  14  7   12
fn gn hn = 19 9 10canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第54次拓展
Open表Board个数:55
最小fn=
1   2   3   4
5   6   10  8
9   15  11  12
13  14  0   7
fn gn hn = 19 11 8canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第55次拓展
Open表Board个数:56
最小fn=
1   2   3   4
5   6   8   11
9   15  10  0
13  14  7   12
fn gn hn = 19 9 10canDown:true
Go Down
openTable:add
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第56次拓展
Open表Board个数:57
最小fn=
1   2   3   4
5   6   8   11
9   15  10  12
13  14  7   0
fn gn hn = 18 10 8canDown:false
canUp:true
Go Up
canRight:false
canLeft:true
Go Left
openTable:add
第57次拓展
Open表Board个数:57
最小fn=
5   1   2   4
6   0   3   8
9   15  10  11
13  14  7   12
fn gn hn = 20 4 16canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第58次拓展
Open表Board个数:59
最小fn=
5   1   2   4
9   6   3   8
15  14  10  11
13  0   7   12
fn gn hn = 20 4 16canDown:false
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第59次拓展
Open表Board个数:60
最小fn=
5   1   2   4
9   6   3   8
15  10  7   11
13  0   14  12
fn gn hn = 20 6 14canDown:false
canUp:true
Go Up
openTable:add
canRight:true
Go Right
canLeft:true
Go Left
openTable:add
第60次拓展
Open表Board个数:61
最小fn=
5   1   2   4
9   6   3   0
15  10  11  8
13  14  7   12
fn gn hn = 20 6 14canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
openTable:add
第61次拓展
Open表Board个数:62
最小fn=
5   1   2   4
9   6   3   8
0   10  11  12
13  14  15  7
fn gn hn = 20 8 12canDown:true
Go Down
canUp:true
Go Up
openTable:add
canRight:true
Go Right
openTable:add
canLeft:false
第62次拓展
Open表Board个数:63
最小fn=
0   1   2   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 20 8 12canDown:true
Go Down
canUp:false
canRight:true
Go Right
openTable:add
canLeft:false
第63次拓展
Open表Board个数:63
最小fn=
1   0   2   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 19 9 10canDown:true
Go Down
openTable:add
canUp:false
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第64次拓展
Open表Board个数:64
最小fn=
1   2   0   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 18 10 8canDown:true
Go Down
openTable:add
canUp:false
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
第65次拓展
Open表Board个数:65
最小fn=
1   2   3   4
5   6   0   8
9   10  7   11
13  14  15  12
fn gn hn = 17 11 6canDown:true
Go Down
openTable:add
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第66次拓展
Open表Board个数:67
最小fn=
1   2   3   4
5   6   7   8
9   10  0   11
13  14  15  12
fn gn hn = 16 12 4canDown:true
Go Down
openTable:add
canUp:true
Go Up
canRight:true
Go Right
openTable:add
canLeft:true
Go Left
openTable:add
第67次拓展
Open表Board个数:69
最小fn=
1   2   3   4
5   6   7   8
9   10  11  0
13  14  15  12
fn gn hn = 15 13 2canDown:true
Go Down
openTable:add
canUp:true
Go Up
openTable:add
canRight:false
canLeft:true
Go Left
第68次拓展
Open表Board个数:70
最小fn=
1   2   3   4
5   6   7   8
9   10  11  12
13  14  15  0
fn gn hn = 14 14 0SUCCESS:
1   2   3   4
5   6   7   8
9   10  11  12
13  14  15  0
fn gn hn = 14 14 0上一步:1 2   3   4
5   6   7   8
9   10  11  0
13  14  15  12
fn gn hn = 15 13 2上一步:1 2   3   4
5   6   7   8
9   10  0   11
13  14  15  12
fn gn hn = 16 12 4上一步:1 2   3   4
5   6   0   8
9   10  7   11
13  14  15  12
fn gn hn = 17 11 6上一步:1 2   0   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 18 10 8上一步:1 0   2   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 19 9 10上一步:0 1   2   4
5   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 20 8 12上一步:5 1   2   4
0   6   3   8
9   10  7   11
13  14  15  12
fn gn hn = 19 7 12上一步:5 1   2   4
9   6   3   8
0   10  7   11
13  14  15  12
fn gn hn = 18 6 12上一步:5 1   2   4
9   6   3   8
13  10  7   11
0   14  15  12
fn gn hn = 17 5 12上一步:5 1   2   4
9   6   3   8
13  10  7   11
14  0   15  12
fn gn hn = 16 4 12上一步:5 1   2   4
9   6   3   8
13  10  7   11
14  15  0   12
fn gn hn = 15 3 12上一步:5 1   2   4
9   6   3   8
13  10  0   11
14  15  7   12
fn gn hn = 16 2 14上一步:5 1   2   4
9   6   3   8
13  0   10  11
14  15  7   12
fn gn hn = 17 1 16上一步:5 1   2   4
9   6   3   8
13  15  10  11
14  0   7   12
fn gn hn = 12 0 12

【人工智能导论】A*算法求解15数码问题 Java相关推荐

  1. 15数码 java_A*算法求解15数码问题

    目录 一.问题描述 二.算法简介 三.算法步骤 四.评估函数 五.参考资料 六.源代码(Java实现) 一.问题描述 利用A*算法进行表1到表2的转换,要求空白块移动次数最少. 转换规则为:空白块只可 ...

  2. A*算法求解15数码问题

    目录 一.问题描述 二.算法简介 三.算法步骤 四.评估函数 五.参考资料 六.源代码(Java实现) 一.问题描述 利用A*算法进行表1到表2的转换,要求空白块移动次数最少. 转换规则为:空白块只可 ...

  3. 【人工智能实验】A*算法求解8数码问题

    目录 实验一 A*算法求解8数码问题 一.实验目的 二.实验原理 三.实验结果 四.实验总结 附录代码 推荐文章 实验一 A*算法求解8数码问题 一.实验目的 熟悉和掌握启发式搜索的定义.估价函数和算 ...

  4. 人工智能导论——A*算法实验

    一.实验目的: 熟悉和掌握启发式搜索的定义.估价函数和算法过程,并利用A*算法求解N数码难题,理解求解流程和搜索顺序. 二.实验原理: A*算法是一种启发式图搜索算法,其特点在于对估价函数的定义上.对 ...

  5. A*算法求解N数码问题(AI实验一)

    1.实验题目 A*算法求解N数码问题,要求程序内,输入给定初始状态和目标状态,输出所需步数,过程状态及时间(程序可直接运行,无需再手动输入). 2.实验目的及要求 熟悉和掌握启发式搜索的定义.估价函数 ...

  6. A*算法解决八数码问题 Java语言实现

    A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...

  7. 人工智能作业 - A*算法程序求解八数码

    文章目录 A*算法 简介 思路 A*伪代码 八数码问题 题目描述 注意事项 实验过程 解决思路 伪代码 二维压缩为一维 检查是否有解 其他 代码实现 h1和h2的对比 关于曼哈顿距离 参考链接 A*算 ...

  8. python解决八数码问题_A*算法解决15数码问题_Python实现

    1问题描述 数码问题常被用来演示如何在状态空间中生成动作序列.一个典型的例子是15数码问题,它是由放在一个4×4的16宫格棋盘中的15个数码(1-15)构成,棋盘中的一个单元是空的,它的邻接单元中的数 ...

  9. 广州大学人工智能导论实验一(八数码问题)

    实验一 八数码问题 一. 实验目的 该课程的教学应贯彻理论与实践相结合的原则,为学生所学到的理论提供实践的场所,通过实验课程中具体问题的求解达到深入了解并掌握的目的. 二. 实验环境 微型计算机,操作 ...

最新文章

  1. $.ajax上传文件或者上传图片
  2. Python操作Zip文件
  3. Insider Dev Tour 2019 | 以技术之力,展现传承魅力
  4. 收藏 | 李飞飞经典CS231N《卷积神经网络视觉识别》第十一讲!
  5. 无向图的深度优先遍历非递归_LeetCode133-克隆图(附详细测试用例构建方法)
  6. unable to locate package gparted
  7. Android - 返回上一个界面finish()方法
  8. ORACLE学习笔记--性能优化3
  9. freemarker中使用@spring.*标签实现国际化
  10. vs2017添加引用出错:对COM组件的调用返回了错误HRESULT E_FAIL
  11. 借助mapshaper的简化来修复geojson的拓扑错误
  12. Permute3 mac最新多种媒体视频格式转换工具
  13. 磊科全功能路由器上网行为管理配置指南 -- 路由器
  14. 腾讯中层裁员10%,互联网资本进入寒流时代
  15. eoLinker API-Shop 常见热门的OCR文字识别API
  16. 金工计算机测试题,金工考试题精选.doc
  17. 秋招面经汇总(算法工程师,计算机视觉工程师,深度学习工程师,机器学习工程师)
  18. 8月重要信息系统保护人员(CIIP-A)认证考试圆满结束
  19. 正则 环视 oracle,环视正则 - travler的个人空间 - OSCHINA - 中文开源技术交流社区...
  20. C++基础-郑莉 11-12章

热门文章

  1. 单击修复计算机英语怎么说,电脑选择语言方式,单击修复计算机
  2. ie 访问 java接口_Java基础面试题 库(1~10)
  3. 使用VLC和live555MediaServer搭建RTSP服务器
  4. 给网游写一个挂吧(四) – 调用游戏函数
  5. IOCP 浅析与实例
  6. 高级数据结构与算法 | AVL树 (高度平衡树)
  7. C++ 如何一次在堆上申请4G的内存?如何设计一个类只能在堆或者栈上创建对象?
  8. Linux 进程控制 :进程创建,进程终止,进程等待,程序替换
  9. python logging日志模块的使用
  10. 干货:数据仓库架构及基础知识