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 puzzle4;
//读取文件内容加载DisjointPattern数据库
static {
puzzle3 = new DisjointPatternDatabase(3, 2,4);
//puzzle3.read("resources/db3.txt");

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

@ -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
* PuzzledisjointPattern
* @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);

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

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

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

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

Loading…
Cancel
Save