zoukankan      html  css  js  c++  java
  • 算法导论第四版学习——习题四8 Puzzle

    题目正文:

    http://coursera.cs.princeton.edu/algs4/assignments/8puzzle.html

    作业难点:

    1、如何验证Puzzle是否可解?题目中有提示,如果相邻两个格子交换后得到的“Twin Puzzle”进行求解,如果Twin有解那么原始Puzzle就无解。

    作业技巧:

    1、checklist提到把Twin Puzzle和Puzzle放在一个Priority Queue中,其实就是在设计自己的Node数据结构的时候加一个boolean类型标识是否twin就好了

    2、别忘了Equal的实现要素,首先是否为空、其次是否类型一致、再其次维度是否一致、最后逐个比较。

    代码参考:

    (这是我自己亲测100分的答案,不代表写得最好,请在自己实在完成不了的时候再看,不然的话做这个题目的意义一点都没有)

      1 import edu.princeton.cs.algs4.In;
      2 import edu.princeton.cs.algs4.StdOut;
      3 
      4 import java.util.Stack;
      5 
      6 
      7 public class Board {
      8     private int ngrid;
      9     private char[] board;
     10     private int hammingCache;
     11     private int manhattanCache;
     12 
     13     public Board(int[][] blocks) {
     14         ngrid = blocks.length;
     15 
     16         if (ngrid < 2) {
     17             throw new NullPointerException();
     18         }
     19 
     20         board = new char[ngrid * ngrid];
     21         hammingCache = 0;
     22         manhattanCache = 0;
     23 
     24         for (int i = 0; i < ngrid; i++) {
     25             for (int j = 0; j < ngrid; j++) {
     26                 int currentValue = blocks[i][j];
     27                 board[(i * ngrid) + j] = (char) currentValue;
     28 
     29                 if (currentValue != 0) {
     30                     if (currentValue != ((i * ngrid) + j + 1)) {
     31                         hammingCache++;
     32                     }
     33 
     34                     int col = (currentValue - 1) % ngrid;
     35                     int row = (currentValue - col - 1) / ngrid;
     36                     // StdOut.println("v:"+currentValue+"r:"+row+"c:"+col);
     37                     manhattanCache += (((col > j) ? (col - j) : (j - col)) +
     38                     ((row > i) ? (row - i) : (i - row)));
     39                 }
     40             }
     41         }
     42     }
     43 
     44     public int dimension() // board dimension n
     45      {
     46         return ngrid;
     47     }
     48 
     49     public int hamming() // number of blocks out of place
     50      {
     51         return hammingCache;
     52     }
     53 
     54     public int manhattan() // sum of Manhattan distances between blocks and goal
     55      {
     56         return manhattanCache;
     57     }
     58 
     59     public boolean isGoal() // is this board the goal board?
     60      {
     61         return hammingCache == 0;
     62     }
     63 
     64     public Board twin() // a board that is obtained by exchanging any pair of blocks
     65      {
     66         int[][] twin = new int[ngrid][ngrid];
     67 
     68         for (int i = 0; i < ngrid; i++) {
     69             for (int j = 0; j < ngrid; j++) {
     70                 twin[i][j] = (int) board[(i * ngrid) + j];
     71             }
     72         }
     73 
     74         if ((twin[0][0] == 0) || (twin[0][1] == 0)) {
     75             swap(twin, 1, 0, 1, 1);
     76         } else {
     77             swap(twin, 0, 0, 0, 1);
     78         }
     79 
     80         return new Board(twin);
     81     }
     82 
     83     public boolean equals(Object y) // does this board equal y?
     84      {
     85         if (y == this) {
     86             return true;
     87         }
     88 
     89         if (y == null) {
     90             return false;
     91         }
     92 
     93         if (y.getClass() != this.getClass()) {
     94             return false;
     95         }
     96 
     97         Board that = (Board) y;
     98         if (that.dimension() != ngrid) return false;
     99         for (int i = 0; i < (ngrid * ngrid); i++) {
    100             if (this.board[i] != that.board[i]) {
    101                 return false;
    102             }
    103         }
    104 
    105         return true;
    106     }
    107 
    108     public Iterable<Board> neighbors() // all neighboring boards
    109      {
    110         int blankRow = 0;
    111         int blankCol = 0;
    112         Stack<Board> neighbours = new Stack<Board>();
    113 
    114         int[][] clone = new int[ngrid][ngrid];
    115 
    116         for (int i = 0; i < ngrid; i++) {
    117             for (int j = 0; j < ngrid; j++) {
    118                 clone[i][j] = (int) board[(i * ngrid) + j];
    119 
    120                 if (clone[i][j] == 0) {
    121                     blankRow = i;
    122                     blankCol = j;
    123                 }
    124             }
    125         }
    126 
    127         if (blankCol != 0) {
    128             swap(clone, blankRow, blankCol - 1, blankRow, blankCol);
    129             neighbours.push(new Board(clone));
    130             swap(clone, blankRow, blankCol - 1, blankRow, blankCol);
    131         }
    132 
    133         if (blankCol != (ngrid - 1)) {
    134             swap(clone, blankRow, blankCol + 1, blankRow, blankCol);
    135             neighbours.push(new Board(clone));
    136             swap(clone, blankRow, blankCol + 1, blankRow, blankCol);
    137         }
    138 
    139         if (blankRow != 0) {
    140             swap(clone, blankRow - 1, blankCol, blankRow, blankCol);
    141             neighbours.push(new Board(clone));
    142             swap(clone, blankRow - 1, blankCol, blankRow, blankCol);
    143         }
    144 
    145         if (blankRow != (ngrid - 1)) {
    146             swap(clone, blankRow + 1, blankCol, blankRow, blankCol);
    147             neighbours.push(new Board(clone));
    148         }
    149 
    150         return neighbours;
    151     }
    152 
    153     private void swap(int[][] array, int i, int j, int a, int b) {
    154         int temp = array[i][j];
    155         array[i][j] = array[a][b];
    156         array[a][b] = temp;
    157     }
    158 
    159     public String toString() // string representation of this board (in the output format specified below)
    160      {
    161         StringBuilder s = new StringBuilder();
    162         s.append(ngrid + "
    ");
    163         for (int i = 0; i < ngrid; i++) {
    164             for (int j = 0; j < ngrid; j++) {
    165                 s.append(String.format("%2d ", (int) board[(i * ngrid) + j]));
    166             }
    167 
    168             s.append("
    ");
    169         }
    170 
    171         return s.toString();
    172     }
    173 
    174     public static void main(String[] args) // unit tests (not graded)
    175      {
    176         // read in the board specified in the filename
    177         In in = new In(args[0]);
    178         int n = in.readInt();
    179         int[][] tiles = new int[n][n];
    180 
    181         for (int i = 0; i < n; i++) {
    182             for (int j = 0; j < n; j++) {
    183                 tiles[i][j] = in.readInt();
    184             }
    185         }
    186 
    187         // solve the slider puzzle
    188         Board initial = new Board(tiles);
    189         StdOut.printf("hamming:%d manhattan:%d 
    ", initial.hamming(),
    190             initial.manhattan());
    191         StdOut.println("dim:" + initial.dimension());
    192         StdOut.println(initial.toString());
    193         StdOut.println("goal:" + initial.isGoal());
    194         StdOut.println("twin:
    " + initial.twin().toString());
    195 
    196         StdOut.println("neighbours:");
    197 
    198         for (Board s : initial.neighbors()) {
    199             StdOut.println(s.toString());
    200         }
    201     }
    202 }
    Board
      1 import edu.princeton.cs.algs4.In;
      2 import edu.princeton.cs.algs4.MinPQ;
      3 import edu.princeton.cs.algs4.StdOut;
      4 
      5 import java.util.Stack;
      6 
      7 
      8 public class Solver {
      9     private boolean solvable;
     10     private GameNode originLast;
     11 
     12     public Solver(Board initial) // find a solution to the initial board (using the A* algorithm)
     13      {
     14         if (initial == null) {
     15             throw new NullPointerException();
     16         }
     17 
     18         solvable = true;
     19 
     20         MinPQ<GameNode> queue = new MinPQ<GameNode>();
     21 
     22         queue.insert(new GameNode(initial, null, 0, false));
     23         queue.insert(new GameNode(initial.twin(), null, 0, true));
     24 
     25         while (!queue.isEmpty()) {
     26             GameNode processed = queue.delMin();
     27 
     28             if (!processed.isTwin) {
     29                 originLast = processed;
     30             }
     31 
     32             if (processed.boardValue.isGoal()) {
     33                 if (processed.isTwin) {
     34                     solvable = false;
     35                 }
     36 
     37                 break;
     38             }
     39 
     40             for (Board neighbor : processed.boardValue.neighbors()) {
     41                 if ((processed.prev == null) ||
     42                         !processed.prev.boardValue.equals(neighbor)) {
     43                     queue.insert(new GameNode(neighbor, processed,
     44                             processed.moves + 1, processed.isTwin));
     45                 }
     46             }
     47         }
     48     }
     49 
     50     public boolean isSolvable() // is the initial board solvable?
     51      {
     52         return solvable;
     53     }
     54 
     55     public int moves() // min number of moves to solve initial board; -1 if unsolvable
     56      {
     57         if (isSolvable()) {
     58             return originLast.moves;
     59         } else {
     60             return -1;
     61         }
     62     }
     63 
     64     public Iterable<Board> solution() // sequence of boards in a shortest solution; null if unsolvable
     65      {
     66         if (!isSolvable()) {
     67             return null;
     68         }
     69 
     70         Stack<Board> solutions = new Stack<Board>();
     71         GameNode current = originLast;
     72 
     73         while (current.prev != null) {
     74             solutions.push(current.boardValue);
     75             current = current.prev;
     76         }
     77 
     78         solutions.push(current.boardValue);
     79 
     80         Stack<Board> solutions2 = new Stack<Board>();
     81 
     82         while (!solutions.empty()) {
     83             solutions2.push(solutions.pop());
     84         }
     85 
     86         return solutions2;
     87     }
     88 
     89     public static void main(String[] args) {
     90         // create initial board from file
     91         In in = new In(args[0]);
     92         int n = in.readInt();
     93         int[][] blocks = new int[n][n];
     94 
     95         for (int i = 0; i < n; i++)
     96             for (int j = 0; j < n; j++)
     97                 blocks[i][j] = in.readInt();
     98 
     99         Board initial = new Board(blocks);
    100 
    101         // solve the puzzle
    102         Solver solver = new Solver(initial);
    103 
    104         // print solution to standard output
    105         if (!solver.isSolvable()) {
    106             StdOut.println("No solution possible");
    107         } else {
    108             StdOut.println("Minimum number of moves = " + solver.moves());
    109 
    110             for (Board board : solver.solution())
    111                 StdOut.println(board);
    112         }
    113     }
    114 
    115     private class GameNode implements Comparable<GameNode> {
    116         private Board boardValue;
    117         private GameNode prev;
    118         private int moves;
    119         private boolean isTwin;
    120 
    121         public GameNode(Board current, GameNode prev, int moves, boolean isTwin) {
    122             this.boardValue = current;
    123             this.prev = prev;
    124             this.moves = moves;
    125             this.isTwin = isTwin;
    126         }
    127 
    128         public int compareTo(GameNode that) {
    129             int priority1 = this.boardValue.manhattan() + this.moves;
    130             int priority2 = that.boardValue.manhattan() + that.moves;
    131 
    132             if (priority1 == priority2) {
    133                 return 0;
    134             } else if (priority1 > priority2) {
    135                 return 1;
    136             } else {
    137                 return -1;
    138             }
    139         }
    140     }
    141 }
    Solver
  • 相关阅读:
    特殊类
    Statement和PrepareStatement有什么区别?
    关于${pageContext.request.contextPath }对于工程中的那个目录
    IDEA JSP中报错cannot resolve method println的解决方案
    关于${pageContext.request.contextPath}的理解
    IDEA中引用不到HttpServlet的解决方案
    Serializable接口的意义和用法
    idea Cannot resolve method (最新2020解决办法)
    IDEA Artifacts:Error during artifact deployment问题解决(狂神SSM整合里,报404错误方案)
    IDEA设置自动导入包方法
  • 原文地址:https://www.cnblogs.com/enigmaxp/p/5913488.html
Copyright © 2011-2022 走看看