普林斯顿算法课第四周作业
来源:互联网 发布:监控淘宝均价软件 编辑:程序博客网 时间:2024/05/23 19:40
8 Puzzle
作业地址:http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html
----------------------------------------------------------------------------------------------------------
第四周作业 8 Puzzle
8 puzzle 是一个经典的拼图问题
将九宫格内乱序的8个数字按顺序整理好,一次只能移动一个数字到空位当中。
作业中提供的思路是Best-first search(最好优先搜索)
首先定义一个Search Node,记录初始到达当前状态的移动次数和上一个状态。
通过不断从优先级队列中取出Search Node 去寻找下一级的状态,并在其中找到最符合优先级的结果。
而要确定优先级就要使用以下两个方法:
Hamming priority function:表示不在目标位置的数目
Manhattan priority function:所有方块距离目标位置之和。
8 puzzle 是一个经典的拼图问题
将九宫格内乱序的8个数字按顺序整理好,一次只能移动一个数字到空位当中。
作业中提供的思路是Best-first search(最好优先搜索)
首先定义一个Search Node,记录初始到达当前状态的移动次数和上一个状态。
通过不断从优先级队列中取出Search Node 去寻找下一级的状态,并在其中找到最符合优先级的结果。
而要确定优先级就要使用以下两个方法:
Hamming priority function:表示不在目标位置的数目
Manhattan priority function:所有方块距离目标位置之和。
然后是需要注意的几个问题:
1.A critical optimization
防止重复状态的出现,需要进行判断
2.Game Tree 将状态以搜索树的方式储存,每一个节点对应一个状态。在每一步中,用A*算法
删除优先级队列中权值最小的那个节点。
3.Detecting infeasible puzzles
有一些初始状态是不可能得到目的状态的。题目中给我们的方法是,将同行的两个数进行交换,
如果其中一个得到目标解,那么另外一个则不可能。
最后有一些方法可能使用不当,很多都超时了
代码如下:
Board.java
import java.util.Arrays;import java.util.Comparator;public class Board {private final int[][] blocks;private final int N;// construct a board from an N-by-N array of blocks// (where blocks[i][j] = block in row i, column j) public Board(int[][] blocks){ N = blocks.length; this.blocks = new int[N][]; for (int i=0; i<N; i++){ this.blocks[i] = Arrays.copyOf(blocks[i], N); } } // board dimension N public int dimension(){ return this.N; } // number of blocks out of place public int hamming(){ int i_hamming = 0; for (int i=0; i<N; i++){ for (int j=0; j<N && i+j < 2*N - 2; j++){ if (blocks[i][j] != i*N + j + 1){ i_hamming++; } } } return i_hamming; } // sum of Manhattan distances between blocks and goal public int manhattan(){ int i_manhattan = 0; for (int i=0; i<N; i++){ for (int j=0; j<N; j++){ if (blocks[i][j] != 0){ i_manhattan += Math.abs((blocks[i][j] - 1) % N - j) + Math.abs((blocks[i][j] - 1) / N - i); } } } return i_manhattan; } // is this board the goal board? public boolean isGoal(){ return this.hamming() == 0; } // a board obtained by exchanging two adjacent blocks in the same row public Board twin(){ int[][] twinBoard = new int[N][N];for (int i=0; i<N; i++){for (int j=0; j<N; j++){twinBoard[i][j] = blocks[i][j];}} if (blocks[0][0] != 0 && blocks[0][1] != 0){ int temp = twinBoard[0][0]; twinBoard[0][0] = twinBoard[0][1]; twinBoard[0][1] = temp; }else{ int temp = twinBoard[1][0]; twinBoard[1][0] = twinBoard[1][1]; twinBoard[1][1] = temp; } return new Board(twinBoard); } // does this board equal y? public boolean equals(Object y){ if (y == this) return true; if (y == null) return false; if (y.getClass() != this.getClass()){ return false; } Board thatBoard = (Board)y; if (this.N != thatBoard.N){ return false; } int[][] arr_thatBoard = thatBoard.blocks; for (int i=0; i<N; i++){ for (int j=0; j<N; j++){ if (blocks[i][j] != arr_thatBoard[i][j]){ return false; } } } return true; } // all neighboring boards public Iterable<Board> neighbors(){ int blank_i = N; int blank_j = N; for (int i=0; i<N; i++){ for (int j=0; j<N; j++){ if (blocks[i][j] == 0){ //this is where the blank is blank_i = i; blank_j = j; } } } MinPQ<Board> q = new MinPQ<Board>(new Comparator<Board>() { public int compare(Board o1, Board o2) { if (o1.manhattan() < o2.manhattan()) return -1; else if (o1.manhattan() == o2.manhattan()) return 0; else return 1; } }); if (blank_j - 1 >= 0){ int[][] arr_temp = getCopy(); arr_temp[blank_i][blank_j] = arr_temp[blank_i][blank_j - 1]; arr_temp[blank_i][blank_j - 1] = 0; q.insert(new Board(arr_temp));// arr_temp = blocks.clone(); } if (blank_j + 1 < N){ int[][] arr_temp = getCopy(); arr_temp[blank_i][blank_j] = arr_temp[blank_i][blank_j + 1]; arr_temp[blank_i][blank_j + 1] = 0; q.insert(new Board(arr_temp));// arr_temp = blocks.clone(); } if (blank_i - 1 >= 0){ int[][] arr_temp = getCopy(); arr_temp[blank_i][blank_j] = arr_temp[blank_i - 1][blank_j]; arr_temp[blank_i - 1][blank_j] = 0; q.insert(new Board(arr_temp));// arr_temp = blocks.clone(); } if (blank_i + 1 < N){ int[][] arr_temp = getCopy(); arr_temp[blank_i][blank_j] = arr_temp[blank_i + 1][blank_j]; arr_temp[blank_i + 1][blank_j] = 0; q.insert(new Board(arr_temp));// arr_temp = blocks.clone(); } return q; } // string representation of the board (in the output format specified below) public String toString() { StringBuilder s = new StringBuilder(); s.append(N + "\n"); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { s.append(String.format("%2d ", blocks[i][j])); } s.append("\n"); } return s.toString(); } private int[][] getCopy(){ int[][] result = new int[N][]; for (int i=0; i<N; i++){ result[i] = Arrays.copyOf(blocks[i], N); } return result; } public static void main(String[] args) { // create initial board from file In in = new In(args[0]); int N = in.readInt(); int[][] blocks = new int[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) blocks[i][j] = in.readInt(); Board initial = new Board(blocks); StdOut.println(initial); StdOut.println(initial.hamming()); }}
Solver.java
import java.util.Comparator;public class Solver {private boolean isSolve = false;private int move = -1;private class SearchNode implements Comparable<SearchNode>{private final Board board;private final int move;private final int priority;private final SearchNode parent;private final boolean isTwin;public SearchNode(Board board, int move, SearchNode parent, boolean isTwin){this.board = board;this.move = move;this.priority = board.manhattan() + move;this.parent = parent;this.isTwin = isTwin;}@Overridepublic int compareTo(SearchNode that) {if (this.board.equals(that.board)) return 0;if (this.priority < that.priority) return -1;else return 1;}}private MinPQ<SearchNode> minPQ = new MinPQ<SearchNode>(new Comparator<SearchNode>() { public int compare(SearchNode o1, SearchNode o2) { if (o1.priority < o2.priority) return -1; else if (o1.priority == o2.priority) return 0; else return 1; } });private Stack<Board> solutionQueue = new Stack<Board>();// find a solution to the initial board (using the A* algorithm) public Solver(Board initial){ Board initialTwin = initial.twin(); SearchNode initSearchNode = new SearchNode(initial, 0, null, false); SearchNode initSearchNodeTwin = new SearchNode(initialTwin, 0, null, true); minPQ.insert(initSearchNode); minPQ.insert(initSearchNodeTwin); solve(); } private void solve(){ while(true){ //solve for original SearchNode searchNode = minPQ.delMin(); if (searchNode.board.isGoal()){ if (searchNode.isTwin){ this.isSolve = false; this.move = -1; } else { this.isSolve = true; this.move = searchNode.move; this.solutionQueue.push(searchNode.board); while(searchNode.parent != null){ searchNode = searchNode.parent; this.solutionQueue.push(searchNode.board); } } break; }else{ for (Board neiborBoard: searchNode.board.neighbors()){ SearchNode neiborNode = new SearchNode(neiborBoard, searchNode.move+1, searchNode, searchNode.isTwin); if (searchNode.parent == null){ minPQ.insert(neiborNode); } else if (!searchNode.parent.board.equals(neiborNode.board)){ minPQ.insert(neiborNode); } } } } } // is the initial board solvable? public boolean isSolvable(){ return this.isSolve; } // min number of moves to solve initial board; -1 if no solution public int moves(){ return this.move; } // sequence of boards in a shortest solution; null if no solution public Iterable<Board> solution(){ if (this.isSolve){ return this.solutionQueue; }else{ return null; } } public static void main(String[] args) { // create initial board from file In in = new In(args[0]); int N = in.readInt(); int[][] blocks = new int[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) blocks[i][j] = in.readInt(); Board initial = new Board(blocks); // solve the puzzle Solver solver = new Solver(initial); // print solution to standard output if (!solver.isSolvable()) StdOut.println("No solution possible"); else { StdOut.println("Minimum number of moves = " + solver.moves()); for (Board board : solver.solution()) StdOut.println(board); } }}
0 0
- 普林斯顿算法课第四周作业
- 普林斯顿算法课第一周作业
- 算法第四周作业
- 第四周算法作业
- 普林斯顿算法课第五周作业
- 普林斯顿算法课第二周作业
- 普林斯顿算法课第三周作业
- 算法课第四周作业 | Course Schedule
- 第四周作业 算法概论
- 算法第四周作业01
- 算法第四周作业02
- Coursera普林斯顿大学算法课-编程作业1: Percolation
- 算法作业_7(2017.3.16第四周)
- 算法作业_8(2017.3.19第四周)
- 普林斯顿公开课:算法第0章,课程介绍
- 第四周作业
- 第四周作业 1
- 第四周作业 4
- 鼠标拖动效果
- Camera 图像处理原理及实例分析
- hybris学习过程-----Preparation
- web.config详解(配置文件节点说明)
- 【Android】Merge讲解与实例
- 普林斯顿算法课第四周作业
- 这些二级域名管用吗
- 222222
- Axure有哪些好处?产品经理选择Axure的十个理由!
- JBOSS系列(五)--集群--基础配置(2)
- JNI环境搭建
- Google Json之GSON学习笔记
- 动态生成Gallery控件组合实现无限循环自动播放广告图片效果总结
- 二维码的生成细节和原理