|
|
|
@ -38,7 +38,7 @@ public class PuzzleState extends State {
|
|
|
|
|
private int misPlaced = 0;
|
|
|
|
|
//哈希值
|
|
|
|
|
private int hash = 0;
|
|
|
|
|
//分组状态数
|
|
|
|
|
//分组状态码,确定每个分组对应唯一值
|
|
|
|
|
private int[] stateCode = null;
|
|
|
|
|
|
|
|
|
|
//zobrist哈希随机值
|
|
|
|
@ -106,6 +106,13 @@ public class PuzzleState extends State {
|
|
|
|
|
return zobrist[i][j][val];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化目标状态到默认状态的曼哈顿距离
|
|
|
|
|
* 初始化zobrist哈希随机值
|
|
|
|
|
* 根据Puzzle阶数确定disjointPattern数据库
|
|
|
|
|
* @param size
|
|
|
|
|
* @param goal
|
|
|
|
|
*/
|
|
|
|
|
public static void init(int size, PuzzleState goal) {
|
|
|
|
|
Random r = new Random();
|
|
|
|
|
goalManhattan = new int[size][size][2];
|
|
|
|
@ -170,8 +177,12 @@ public class PuzzleState extends State {
|
|
|
|
|
nextState.board[this.blank[0] * size + this.blank[1]] = this.board[nextState.blank[0] * size + nextState.blank[1]];
|
|
|
|
|
nextState.board[nextState.blank[0] * size + nextState.blank[1]] = 0;
|
|
|
|
|
|
|
|
|
|
// 根据父状态和移动的位将牌计算子状态的哈希值、曼哈顿距离、不在位将牌和分组状态码
|
|
|
|
|
// 根据使用的不用方法,只调用其对应的计算
|
|
|
|
|
nextState.hash = nextHash(this, nextState);
|
|
|
|
|
nextState.manhattan = this.manhattan - nextManhattan(this, nextState);
|
|
|
|
|
//nextState.misPlaced = this.misPlaced - nextMispalced(this, nextState);
|
|
|
|
|
|
|
|
|
|
nextState.stateCode = this.stateCode.clone();
|
|
|
|
|
//int val = (getBoardAtAnother(this, nextState) - 1);
|
|
|
|
|
int val = (getBoardAtAnother(this, nextState));
|
|
|
|
@ -187,6 +198,7 @@ public class PuzzleState extends State {
|
|
|
|
|
@Override
|
|
|
|
|
public Iterable<? extends Action> actions() {
|
|
|
|
|
ArrayList<Action> actions = new ArrayList<Action>();
|
|
|
|
|
//遍历所有方向
|
|
|
|
|
for (int d = 0; d < 4; d++)
|
|
|
|
|
actions.add(new PuzzleAction(d));
|
|
|
|
|
return actions;
|
|
|
|
@ -197,6 +209,7 @@ public class PuzzleState extends State {
|
|
|
|
|
* @return 1:奇 0:偶
|
|
|
|
|
*/
|
|
|
|
|
public int parity() {
|
|
|
|
|
// 根据Puzzle奇偶阶数分类讨论
|
|
|
|
|
int n = (size % 2 == 0) ? blank[0] + 1 : 0;
|
|
|
|
|
for (int i = 0; i < size * size; i++) {
|
|
|
|
|
for (int j = 0; j < i; j++) {
|
|
|
|
@ -220,7 +233,7 @@ public class PuzzleState extends State {
|
|
|
|
|
return true;
|
|
|
|
|
if (obj instanceof PuzzleState) {
|
|
|
|
|
PuzzleState another = (PuzzleState) obj;
|
|
|
|
|
//两个Node对象的状态相同,则认为是相同的
|
|
|
|
|
//两个PuzzleState对象的状态相同,则认为是相同的
|
|
|
|
|
return this.hashCode() == obj.hashCode();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
@ -237,6 +250,9 @@ public class PuzzleState extends State {
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return zobrist哈希计算
|
|
|
|
|
*/
|
|
|
|
|
private int getHash() {
|
|
|
|
|
int hash = 0;
|
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
@ -249,6 +265,9 @@ public class PuzzleState extends State {
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 单个位将牌移动改变的哈希值
|
|
|
|
|
*/
|
|
|
|
|
private int nextHash(PuzzleState parent, PuzzleState child) {
|
|
|
|
|
int hash = parent.hashCode();
|
|
|
|
|
hash ^= getZobristAt(child.getBlank(0), child.getBlank(1), getBoardAtAnother(parent, child));
|
|
|
|
@ -274,6 +293,9 @@ public class PuzzleState extends State {
|
|
|
|
|
return predictors.get(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 获取曼哈顿距离,若已经通过优化则直接返回该值,若无则进行计算
|
|
|
|
|
*/
|
|
|
|
|
private int getManhattan(PuzzleState goal) {
|
|
|
|
|
if (manhattan == 0)
|
|
|
|
|
manhattan = manhattan(goal);
|
|
|
|
@ -346,6 +368,9 @@ public class PuzzleState extends State {
|
|
|
|
|
- Math.abs(goalManhattan[x][y][0] - parent.getBlank(0)) - Math.abs(goalManhattan[x][y][1] - parent.getBlank(1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 被移动的位将牌改变的不在位将牌数
|
|
|
|
|
*/
|
|
|
|
|
private int nextMispalced(PuzzleState parent, PuzzleState child) {
|
|
|
|
|
int row = (getBoardAtAnother(parent, child) - 1) / size;
|
|
|
|
|
int col = (getBoardAtAnother(parent, child) - 1) % size;
|
|
|
|
@ -368,6 +393,7 @@ public class PuzzleState extends State {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disjoint pattern heuristic
|
|
|
|
|
* 计算每个分组的状态码以获取每个分组到目的状态的路径损耗
|
|
|
|
|
*/
|
|
|
|
|
private int disjointPattern() {
|
|
|
|
|
int disjointPattern = 0;
|
|
|
|
@ -378,6 +404,9 @@ public class PuzzleState extends State {
|
|
|
|
|
return disjointPattern;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 计算每个组的状态码
|
|
|
|
|
*/
|
|
|
|
|
private int[] getStateCode() {
|
|
|
|
|
int[] stateCode = new int[db.classes];
|
|
|
|
|
//System.out.println("classes: " + db.classes);
|
|
|
|
@ -391,6 +420,9 @@ public class PuzzleState extends State {
|
|
|
|
|
// ", val = " + i * (int) Math.pow(size * size, (board[i] - 1) % db.n));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return 移动位将牌改变的对应分组的状态码
|
|
|
|
|
*/
|
|
|
|
|
private int nextStateCode(PuzzleState parent, PuzzleState child, int val) {
|
|
|
|
|
//return (child.getBlank(0) * size + child.getBlank(1)) * (int) Math.pow(size * size, val % db.n)
|
|
|
|
|
// - (parent.getBlank(0) * size + parent.getBlank(1)) * (int) Math.pow(size * size, val % db.n);
|
|
|
|
|