您的位置:首页 > 编程语言 > Go语言

Week4 Assignment - Without Full Score - Princeton-Algorithms-PartI

2014-02-24 13:56 639 查看

题注

第一次跟Princeton的《Algorithm》课没有跟下来的一个核心原因就是这道题无论如何拿不到full score,第一次做的时候分数只有不到85分,因为最后的测试总是有一些test不能通过。经过了大概6个月后,现在再编这个题目,结果还是拿不到full score,不过分数大约提高了10分,只有部分的test不能通过。然而,我自己还是找不到为何通不过的原因,因此先把现在的代码贴出来,和大家分享,也希望朋友们一起帮忙找找错误…

题目

8 Puzzle

Write a program to solve the 8-puzzle problem(and its natural generalizations) using the A* search algorithm.

The problem.The
8-puzzle problemis a puzzle invented and popularized by Noyes Palmer Chapman in the 1870s. It is played on a 3-by-3 grid with 8 square blocks labeled 1 through 8 and a blank square. Your goal is to rearrange the blocks so that they are in order, usingas
few moves as possible. You are permitted to slide blocks horizontally or verticallyinto the blank square. The following shows a sequence of legal moves from an
initial board (left)to the goal board (right).


1 3 1 3 1 2 3 1 2 3 1 2 3
4 2 5 => 4 2 5 => 4 5 => 4 5 => 4 5 6
7 8 6 7 8 6 7 8 6 7 8 6 7 8

initial 1 left 2 up 5 left goal
Best-first search.Now, we describe a solution to the problem that illustrates a general artificial intelligence methodology known as theA* search algorithm.We
define a search node of the game to be a board, the numberof moves made to reach the board, and the previous search node.First, insert the initial search node(the initial board, 0 moves, and a null previous search node) into a priority queue. Then,delete
from the priority queue the search node with the minimum priority,and insert onto the priority queue all neighboring search nodes(those that can be reached in one move from the dequeued search node).Repeat this procedure until the search node dequeued corresponds
to a goal board.The success of this approachhinges on the choice of priority function for a search node. We consider two priority functions:

Hamming priority function.The number of blocks in the wrong position,plus the number of moves made so far to get to the search node.Intutively, a search node with a small number of blocks in the wrong positionis close to the goal, and we prefer
a search node thathave been reached using a small number of moves.
Manhattan priority function.The sum of the Manhattan distances (sum of the vertical and horizontal distance)from the blocks to their goal positions,plus the number of moves made so far to get to the search node.

For example, the Hamming and Manhattan priorities of the initial search nodebelow are 5 and 10, respectively.

8 1 3 1 2 3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 4 5 6 ---------------------- ----------------------
7 6 5 7 8 1 1 0 0 1 1 0 1 1 2 0 0 2 2 0 3

initial goal Hamming = 5 + 0 Manhattan = 10 + 0
We make a key oberservation: To solve the puzzle froma given search node on the priority queue, the total number of moves weneed to make (including those already made) is at least its priority,using either the Hamming or Manhattan priority function.(For
Hamming priority, this is true because each block that is out of placemust move at least once to reach its goal position.For Manhattan priority, this is true because each block must moveits Manhattan distance from its goal position.Note that we do not count
the blank square when computing theHamming or Manhattan priorities.)Consequently, when the goal board is dequeued, wehave discovered not only a sequence of moves from theinitial board to the goal board, but one that makes the fewest number of moves. (Challenge
for the mathematically inclined: prove this fact.)

A critical optimization.Best-first search has one annoying feature:search nodes corresponding to the same boardare enqueued on the priority queue many times.To reduce unnecessary exploration of useless search nodes,when considering the neighbors
of a search node, don't enqueuea neighbor if its board is the same as the board of theprevious search node.


8 1 3 8 1 3 8 1 8 1 3 8 1 3
4 2 4 2 4 2 3 4 2 4 2 5
7 6 5 7 6 5 7 6 5 7 6 5 7 6

previous search node neighbor neighbor neighbor
(disallow)

Game tree.One way to view the computation is as a game tree, where each search nodeis a node in the game tree and the children of a node correspond to itsneighboring search nodes. The root of the game tree is the initial search
node;the internal nodes have already been processed; the leaf nodes are maintainedin a priority queue; at each step, the A* algorithm removes the node with the smallestpriority from the priority queue and processes it (by adding its childrento both the game
tree and the priority queue).



Detecting infeasible puzzles.Not all initial boards can lead to the goal board such as the one below.

 1  2  3
4 5 6
8 7

infeasible

To detect such situations,use the fact that boardsare divided into two equivalence classes with respect to reachability:(i) those that lead to the goal board and (ii) those thatlead to the goal board if we modify the initial board byswapping any pair of adjacent
(non-blank) blocks in the same row.(Difficult challenge for the mathematically inclined: prove this fact.)To apply the fact,run the A* algorithm simultaneously on two puzzle instances—one with theinitial board and one with the initial board modified byswapping
a pair of adjacent blocks in the same row. Exactly one ofthe two will lead to the goal board.
Board and Solver data types.Organize your program by creating an immutable data type
Board with the following API:

public class Board {
public Board(int[][] blocks)           // construct a board from an N-by-N array of blocks
// (where blocks[i][j] = block in row i, column j)
public int dimension()                 // board dimension N
public int hamming()                   // number of blocks out of place
public int manhattan()                 // sum of Manhattan distances between blocks and goal
public boolean isGoal()                // is this board the goal board?
public Board twin()                    // a board obtained by exchanging two adjacent blocks in the same row
public boolean equals(Object y)        // does this board equal y?
public Iterable<Board> neighbors()     // all neighboring boards
public String toString()               // string representation of the board (in the output format specified below)
}


and an immutable data type Solver with the following API:

public class Solver {
public Solver(Board initial)            // find a solution to the initial board (using the A* algorithm)
public boolean isSolvable()             // is the initial board solvable?
public int moves()                      // min number of moves to solve initial board; -1 if no solution
public Iterable<Board> solution()       // sequence of boards in a shortest solution; null if no solution
public static void main(String[] args)  // solve a slider puzzle (given below)
}


To implement the A* algorithm, you must use the MinPQ data type from
algs4.jarfor the priority queues.

Solver test client.Use the following test client to read a puzzle from a file(specified as a command-line argument) and print the solution to standard output.

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

;
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);
}
}


Input and output formats.The input and output format for a board is the board dimension
N followed bythe N-by-Ninitial board, using 0 to represent the blank square.As an example,

% more puzzle04.txt
3
0 1 3
4 2 5
7 8 6

% java Solver puzzle04.txt
Minimum number of moves = 4

3
0 1 3
4 2 5
7 8 6

3
1 0 3
4 2 5
7 8 6

3
1 2 3
4 0 5
7 8 6

3
1 2 3
4 5 0
7 8 6

3
1 2 3
4 5 6
7 8 0

% more puzzle-unsolvable3x3.txt
3
1 2 3
4 5 6
8 7 0

% java Solver puzzle3x3-unsolvable.txt
No solution possible
Your program should work correctly for arbitrary N-by-N boards(for any 2 ≤
N < 128), even if it is too slow to solve some of them in a reasonable amount of time.

分析

首先我们需要解决一个问题:这个题目是不是一个多项式时间内可以解决的问题?也就是说,这是不是一个P问题呢?答案是否定的,网站上已经给出了答案以及原因,详情如下:

Is there an efficient way to solve the 8-puzzle and its generalizations?Finding a shortest solution to an
N-by-N slider puzzle isNP-hard,so it's unlikely that an efficient solution exists.

如果这是一个NP-hard问题,我们只有两种思路:一种是找出概率解,也就是说在多项式时间内做出一个解,这个解有很大的概率是正确的;另一种就是用搜索树等方法来搜索到精确解,但是搜索解本身可能是一个时间复杂度或者空间复杂度为指数复杂度的算法。

Princeton的《Algorithm》给出了一个使用A*搜索的方式来进行解决。其思路和Coursera中另一个公开课《Generic Game Playing》的搜索树算法很像,大致思路是:对于每一个中间解,计算一个这个解是“正确的”大概期望,按照每一个中间解的期望对搜索树进行排序,优先搜索期望大的解。在本题中,所谓的“期望”就是Hamming priority和Manhattan priority。对搜索树排序的方法就是Week4中的优先队列。

上述算法一定能够搜索到正确的解,因为搜索树最极限的情况也就是把所有的可能移动方法都搜索一遍嘛,所以在最糟糕情况下,算法的时间复杂度和空间复杂度都将会是指数级的。

但是,能否搜索到解还有一个情况,就是能否判断8 Puzzle的这个实例是否确实存在解。但是,是否存在解这个确定问题也是一个NP-hard问题,至今没有一个多项式时间算法能在多项式空间复杂度内回答一个8 Puzzle实例是否存在解。针对此问题,《Algorithm》给出了一种判断方法。8 Puzzle问题可分为两类:给定实例存在解,或给定实例的“Twin”实例存在解。因此,整个算法要求构造一个给定实例的Twin实例,然后同时在两个实例中运行搜索算法:如果给定实例找到了解,那么就输出解;如果Twin实例找到了解,那么说明给定实例不存在解,输出null。

算法本身并不复杂,最小优先队列也可以直接使用,我自己实现的算法时间也很快(对于测试的实例,都在2s以内给出搜索解)。但是,我的实现中,空间复杂度比正确答案的空间复杂度大得多!至今我还没有找到这个问题的答案,需要朋友们的帮助了…

我算法的测试分数如下:



我算法的测试结果如下(只有这一部分的Test有部分不通过的情况):

Timing Solver
*-----------------------------------------------------------
Running 17 total tests.

Timing tests use your implementation of Board.java and Solver.java. Maximum allowed time per puzzle is 15 seconds.

delMin()
filename   N    seconds    insert()          + delMax()         max PQ size
---------------------------------------------------------------------------------------------
=> passed  puzzle20.txt   3     0.09       4339                2270                2071
=> FAILED  puzzle21.txt   3     0.15      23546               12303               11245   (1.2x)
=> passed  puzzle22.txt   3     0.04      11521                6024                5499
=> passed  puzzle23.txt   3     0.10      29234               15271               13965
=> passed  puzzle24.txt   3     0.08      27638               14519               13121
=> passed  puzzle25.txt   3     0.07      51689               27040               24651
=> FAILED  puzzle26.txt   3     0.05      49313               25768               23547   (1.1x)
=> passed  puzzle27.txt   3     0.05      72743               38270               34475
=> passed  puzzle28.txt   3     0.07      85413               44668               40747
=> FAILED  puzzle29.txt   3     0.07      96664   (1.2x)      50729               45937   (1.4x)
=> passed  puzzle30.txt   3     0.15     185300               97305               87997
=> passed  puzzle31.txt   3     0.14     176268               92405               83865
=> FAILED  puzzle34.txt   4     1.74    1335836              660941   (1.1x)     674897
=> passed  puzzle37.txt   4     1.01     621008              307365              313645
=> passed  puzzle39.txt   4     0.58     534206              265519              268689
=> passed  puzzle41.txt   5     0.53     226458              108667              117793
=> passed  puzzle44.txt   5     0.65     505048              244981              260069
==> 13/17 tests passed

Total: 13/17 tests passed!

================================================================


根据公开课讨论组中大家的结果,大致的测试结果应该如下:

******************************************************************************
*  timing
******************************************************************************

Timing Solver
*-----------------------------------------------------------
Running 17 total tests.

Timing tests use your implementation of Board.java and Solver.java. Maximum allowed time per puzzle is 15 seconds.

delMin()
filename   N    seconds    insert()          + delMax()         max PQ size
---------------------------------------------------------------------------------------------
=> passed  puzzle20.txt   3     0.05       1365                 815                 551
=> passed  puzzle21.txt   3     0.06       4292                2547                1746
=> passed  puzzle22.txt   3     0.02       2813                1657                1157
=> passed  puzzle23.txt   3     0.04       5444                3217                2228
=> passed  puzzle24.txt   3     0.04       6976                4239                2738
=> passed  puzzle25.txt   3     0.05      11150                6623                4528
=> passed  puzzle26.txt   3     0.02       5423                3267                2157
=> passed  puzzle27.txt   3     0.05      13608                8237                5372
=> passed  puzzle28.txt   3     0.11      21749               13011                8739
=> passed  puzzle29.txt   3     0.04      14954                9129                5826
=> passed  puzzle30.txt   3     0.07      34304               20881               13424
=> passed  puzzle31.txt   3     0.09      42868               25935               16934
=> passed  puzzle34.txt   4     0.45     143570               69305               74266
=> passed  puzzle37.txt   4     1.00     301184              144475              156710
=> passed  puzzle39.txt   4     1.04     221457              108175              113283
=> passed  puzzle41.txt   5     0.17      64715               27757               36959
=> passed  puzzle44.txt   5     0.94     317910              141547              176364
==> 17/17 tests passed

Total: 17/17 tests passed!

================================================================

我个人怀疑可能是如下原因里面的几个或者几个:

(1)我的equals方法可能有bug,因此优先队列中增加了很多重复的搜索节点,但是我确实没有发现bug具体在哪里。

(2)我的Board类中,neighbor方法可能有内存管理的bug。一些等价的或者删除的搜索节点并没有被删除。

(3)搜索算法本身有问题。

(4)其他。

我自己已经在讨论组中发了帖子询问了这个问题,帖子如下:

Hi, all:

    My answer passed almost all the tests except 4: puzzle21.txt, puzzle 26.txt, puzzle 29.txt, and puzzle 34.txt. The reason why these tests fail is not the time exceeding exceptions, but the memory exceeding exceptions and I have no idea why such happened...

    Here are part of the assignment results:

Timing Solver
*-----------------------------------------------------------
Running 17 total tests.

Timing tests use your implementation of Board.java and Solver.java. Maximum allowed time per puzzle is 15 seconds.

delMin()
filename   N    seconds    insert()          + delMax()         max PQ size
---------------------------------------------------------------------------------------------
=> passed  puzzle20.txt   3     0.09       4339                2270                2071
=> FAILED  puzzle21.txt   3     0.15      23546               12303               11245   (1.2x)
=> passed  puzzle22.txt   3     0.04      11521                6024                5499
=> passed  puzzle23.txt   3     0.10      29234               15271               13965
=> passed  puzzle24.txt   3     0.08      27638               14519               13121
=> passed  puzzle25.txt   3     0.07      51689               27040               24651
=> FAILED  puzzle26.txt   3     0.05      49313               25768               23547   (1.1x)
=> passed  puzzle27.txt   3     0.05      72743               38270               34475
=> passed  puzzle28.txt   3     0.07      85413               44668               40747
=> FAILED  puzzle29.txt   3     0.07      96664   (1.2x)      50729               45937   (1.4x)
=> passed  puzzle30.txt   3     0.15     185300               97305               87997
=> passed  puzzle31.txt   3     0.14     176268               92405               83865
=> FAILED  puzzle34.txt   4     1.74    1335836              660941   (1.1x)     674897
=> passed  puzzle37.txt   4     1.01     621008              307365              313645
=> passed  puzzle39.txt   4     0.58     534206              265519              268689
=> passed  puzzle41.txt   5     0.53     226458              108667              117793
=> passed  puzzle44.txt   5     0.65     505048              244981              260069
==> 13/17 tests passed

Total: 13/17 tests passed!


     I noticed the critical optimization and I am sure I correctly added it in my solution. Some code segments are shown here:

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.compareTo(neiborNode) != 0){

                        minPQ.insert(neiborNode);

                    }

                }

    Do I miss something else for this problem? I personally appreciate your attention about this problem and trying to help me solve it.

但是至今还没有得到合理的回复… 还请大家帮助了,相信CSDN社区是万能的,嗯嗯~

代码(Without Full Score)

Board.java

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
[];
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

;
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
[];
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

;
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
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;
}

@Override
public 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 ; 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); } }}

另外,给出一个测试类PuzzleChecker.java
public class PuzzleChecker {

public static void main(String[] args) {

String filename = "8puzzle/puzzle44.txt";
// read in the board specified in the filename
In in = new In(filename);
int N = in.readInt();
int[][] tiles = new int

;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
tiles[i][j] = in.readInt();
}
}

// solve the slider puzzle
Board initial = new Board(tiles);
Solver solver = new Solver(initial);
System.out.println(filename + ": " + solver.moves());
}
}

测试实例下载链接为:http://coursera.cs.princeton.edu/algs4/testing/8puzzle-testing.zip,解压缩后,将文件夹放置在workspace中建立的工程目录下,然后运行测试类即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Algorithm Coursera Java