master
jokingww 4 years ago
parent 44d9d432d9
commit f77e8da42e

@ -12,6 +12,7 @@ public class Puzzle extends Problem {
public static DisjointPatternDatabase puzzle3; public static DisjointPatternDatabase puzzle3;
public static DisjointPatternDatabase puzzle4; public static DisjointPatternDatabase puzzle4;
//读取文件内容加载DisjointPattern数据库
static { static {
puzzle3 = new DisjointPatternDatabase(3, 2,4); puzzle3 = new DisjointPatternDatabase(3, 2,4);
//puzzle3.read("resources/db3.txt"); //puzzle3.read("resources/db3.txt");

@ -1,10 +1,19 @@
package g04.problem.npuzzle; package g04.problem.npuzzle;
/**
* Puzzle
*
*/
public class PuzzlePoint { public class PuzzlePoint {
// 行列坐标和位将牌值
private int row; private int row;
private int col; private int col;
private int val; private int val;
/**
*
*/
public PuzzlePoint(int row, int col, int val) { public PuzzlePoint(int row, int col, int val) {
this.row = row; this.row = row;
this.col = col; this.col = col;

@ -38,7 +38,7 @@ public class PuzzleState extends State {
private int misPlaced = 0; private int misPlaced = 0;
//哈希值 //哈希值
private int hash = 0; private int hash = 0;
//分组状态 //分组状态码,确定每个分组对应唯一值
private int[] stateCode = null; private int[] stateCode = null;
//zobrist哈希随机值 //zobrist哈希随机值
@ -106,6 +106,13 @@ public class PuzzleState extends State {
return zobrist[i][j][val]; return zobrist[i][j][val];
} }
/**
*
* zobrist
* PuzzledisjointPattern
* @param size
* @param goal
*/
public static void init(int size, PuzzleState goal) { public static void init(int size, PuzzleState goal) {
Random r = new Random(); Random r = new Random();
goalManhattan = new int[size][size][2]; 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[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.board[nextState.blank[0] * size + nextState.blank[1]] = 0;
// 根据父状态和移动的位将牌计算子状态的哈希值、曼哈顿距离、不在位将牌和分组状态码
// 根据使用的不用方法,只调用其对应的计算
nextState.hash = nextHash(this, nextState); nextState.hash = nextHash(this, nextState);
nextState.manhattan = this.manhattan - nextManhattan(this, nextState); nextState.manhattan = this.manhattan - nextManhattan(this, nextState);
//nextState.misPlaced = this.misPlaced - nextMispalced(this, nextState);
nextState.stateCode = this.stateCode.clone(); nextState.stateCode = this.stateCode.clone();
//int val = (getBoardAtAnother(this, nextState) - 1); //int val = (getBoardAtAnother(this, nextState) - 1);
int val = (getBoardAtAnother(this, nextState)); int val = (getBoardAtAnother(this, nextState));
@ -187,6 +198,7 @@ public class PuzzleState extends State {
@Override @Override
public Iterable<? extends Action> actions() { public Iterable<? extends Action> actions() {
ArrayList<Action> actions = new ArrayList<Action>(); ArrayList<Action> actions = new ArrayList<Action>();
//遍历所有方向
for (int d = 0; d < 4; d++) for (int d = 0; d < 4; d++)
actions.add(new PuzzleAction(d)); actions.add(new PuzzleAction(d));
return actions; return actions;
@ -197,6 +209,7 @@ public class PuzzleState extends State {
* @return 1: 0: * @return 1: 0:
*/ */
public int parity() { public int parity() {
// 根据Puzzle奇偶阶数分类讨论
int n = (size % 2 == 0) ? blank[0] + 1 : 0; int n = (size % 2 == 0) ? blank[0] + 1 : 0;
for (int i = 0; i < size * size; i++) { for (int i = 0; i < size * size; i++) {
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
@ -220,7 +233,7 @@ public class PuzzleState extends State {
return true; return true;
if (obj instanceof PuzzleState) { if (obj instanceof PuzzleState) {
PuzzleState another = (PuzzleState) obj; PuzzleState another = (PuzzleState) obj;
//两个Node对象的状态相同则认为是相同的 //两个PuzzleState对象的状态相同则认为是相同的
return this.hashCode() == obj.hashCode(); return this.hashCode() == obj.hashCode();
} }
return false; return false;
@ -237,6 +250,9 @@ public class PuzzleState extends State {
return hash; return hash;
} }
/**
* @return zobrist
*/
private int getHash() { private int getHash() {
int hash = 0; int hash = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@ -249,6 +265,9 @@ public class PuzzleState extends State {
return hash; return hash;
} }
/**
* @return
*/
private int nextHash(PuzzleState parent, PuzzleState child) { private int nextHash(PuzzleState parent, PuzzleState child) {
int hash = parent.hashCode(); int hash = parent.hashCode();
hash ^= getZobristAt(child.getBlank(0), child.getBlank(1), getBoardAtAnother(parent, child)); 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 predictors.get(type);
} }
/**
* @return
*/
private int getManhattan(PuzzleState goal) { private int getManhattan(PuzzleState goal) {
if (manhattan == 0) if (manhattan == 0)
manhattan = manhattan(goal); 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)); - 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) { private int nextMispalced(PuzzleState parent, PuzzleState child) {
int row = (getBoardAtAnother(parent, child) - 1) / size; int row = (getBoardAtAnother(parent, child) - 1) / size;
int col = (getBoardAtAnother(parent, child) - 1) % size; int col = (getBoardAtAnother(parent, child) - 1) % size;
@ -368,6 +393,7 @@ public class PuzzleState extends State {
/** /**
* Disjoint pattern heuristic * Disjoint pattern heuristic
*
*/ */
private int disjointPattern() { private int disjointPattern() {
int disjointPattern = 0; int disjointPattern = 0;
@ -378,6 +404,9 @@ public class PuzzleState extends State {
return disjointPattern; return disjointPattern;
} }
/**
* @return
*/
private int[] getStateCode() { private int[] getStateCode() {
int[] stateCode = new int[db.classes]; int[] stateCode = new int[db.classes];
//System.out.println("classes: " + 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)); // ", val = " + i * (int) Math.pow(size * size, (board[i] - 1) % db.n));
} }
/**
* @return
*/
private int nextStateCode(PuzzleState parent, PuzzleState child, int val) { 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) //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); // - (parent.getBlank(0) * size + parent.getBlank(1)) * (int) Math.pow(size * size, val % db.n);

@ -12,7 +12,9 @@ public class SubPuzzleState {
private int n; private int n;
private int size; private int size;
private PuzzlePoint[] points; private PuzzlePoint[] points;
private int heuristic = 0; private int heuristic = 0;
// 到目标状态的路径损耗
private int cost = 0; private int cost = 0;
private SubPuzzleState parent = null; private SubPuzzleState parent = null;
@ -21,6 +23,9 @@ public class SubPuzzleState {
{0, 1}, {1, 0}, {0, -1}, {-1, 0} {0, 1}, {1, 0}, {0, -1}, {-1, 0}
}; };
/**
*
*/
public SubPuzzleState(int size, int n, int maxN, PuzzlePoint[] points) { public SubPuzzleState(int size, int n, int maxN, PuzzlePoint[] points) {
this.n = n; this.n = n;
this.size = size; this.size = size;
@ -108,6 +113,10 @@ public class SubPuzzleState {
return false; return false;
} }
/**
* pathcostpathcost+1
* @return
*/
public SubPuzzleState move(int i, int d) { public SubPuzzleState move(int i, int d) {
SubPuzzleState state = new SubPuzzleState(this); SubPuzzleState state = new SubPuzzleState(this);
int x = state.points[i].getRow() + next[d][0]; int x = state.points[i].getRow() + next[d][0];
@ -119,6 +128,9 @@ public class SubPuzzleState {
return state; return state;
} }
/**
* @return + 线
*/
public int heuristic() { public int heuristic() {
int heuristic = 0; int heuristic = 0;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {

@ -101,6 +101,10 @@ public class DisjointPatternBuilder {
} }
} }
/**
*
* @param state
*/
public void printPath(SubPuzzleState state) { public void printPath(SubPuzzleState state) {
System.out.println("--------------------"); System.out.println("--------------------");
while (state.getParent() != null) { while (state.getParent() != null) {
@ -141,6 +145,12 @@ public class DisjointPatternBuilder {
} }
} }
*/ */
/**
*
* @param cost
* @param filename
*/
public void save(int[] cost, String filename) { public void save(int[] cost, String filename) {
//创建字符输出流 //创建字符输出流
FileWriter writeFile = null; FileWriter writeFile = null;

@ -11,7 +11,9 @@ public class DisjointPatternDatabase {
public int classes; public int classes;
public int[][] cost; public int[][] cost;
// 位将牌在分组内的优先级,用于计算状态码
public int[] positions; public int[] positions;
// 位将牌所属分组
public int[] subsets; public int[] subsets;
//zobrist哈希随机值 //zobrist哈希随机值

@ -42,12 +42,6 @@ public class IDAStarSearch implements Searcher {
Node root = problem.root(predictor); Node root = problem.root(predictor);
cutoff = root.evaluation(); cutoff = root.evaluation();
//System.out.println(predictor.heuristics(problem.getInitialState(), problem.getGoal()));
/*
if (1 == 1)
return null;
*/
while (cutoff < maxIteratorDepth) { while (cutoff < maxIteratorDepth) {
openStack.push(root); openStack.push(root);
newCutoff = cutoff; newCutoff = cutoff;
@ -68,6 +62,7 @@ public class IDAStarSearch implements Searcher {
openStack.push(child); openStack.push(child);
} }
} else { } else {
//记录大于当前cutoff的最小值
newCutoff = (newCutoff > cutoff) ? (Math.min(child.evaluation(), newCutoff)) : child.evaluation(); newCutoff = (newCutoff > cutoff) ? (Math.min(child.evaluation(), newCutoff)) : child.evaluation();
} }
} }

Loading…
Cancel
Save