diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java index 6ca1988..8e73766 100644 --- a/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java @@ -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"); diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzlePoint.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzlePoint.java index 1c68b46..e9e9069 100644 --- a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzlePoint.java +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzlePoint.java @@ -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; diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java index 8543bb3..f15c41c 100644 --- a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java @@ -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 actions() { ArrayList actions = new ArrayList(); + //遍历所有方向 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); diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/SubPuzzleState.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/SubPuzzleState.java index e3a2be0..6811271 100644 --- a/SearchFramework1.0.1/src/g04/problem/npuzzle/SubPuzzleState.java +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/SubPuzzleState.java @@ -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; } + /** + * 执行位移操作,并将新状态的pathcost设置父状态pathcost+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++) { diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternBuilder.java b/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternBuilder.java index d14763c..fc7bf73 100644 --- a/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternBuilder.java +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternBuilder.java @@ -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; diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternDatabase.java b/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternDatabase.java index 4c26457..3a8e018 100644 --- a/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternDatabase.java +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/DisjointPatternDatabase.java @@ -11,7 +11,9 @@ public class DisjointPatternDatabase { public int classes; public int[][] cost; + // 位将牌在分组内的优先级,用于计算状态码 public int[] positions; + // 位将牌所属分组 public int[] subsets; //zobrist哈希随机值 diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java b/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java index a1f062f..097f2fd 100644 --- a/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java @@ -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(); } }