编程作业四

问题简介

借助优先队列,实现解决八数码(8puzzle)问题的 A* 算法。

八数码问题就是下面这样,移动方块重排数字,最后使其有序,希望找到最少的移动次数。

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

A* 算法是一种最优搜索(Best-first search),评价(或启发或优先级,反正就那意思)函数依实际问题而设计,搜索拓展节点时选最优,这里介绍了两个:

Hamming priority function. 定义为:不在正确位置上的方块数目加上目前移动的次数。直观上来说,在错误位置上的方块数目少,也就越接近目标,而且我们也希望移动次数少。

Manhattan priority function. 定义为:错误方块到正确位置需要的曼哈顿距离(水平加垂直格子数)之和加上目前移动的次数。

举例来说:

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

一个重要的优化的是避免往优先队列里放入太多重复的情况,具体来说就是拓展节点时丢弃先前转换来的情况:

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

predecessor search node neighbor neighbor neighbor

(disallow)

这样做不能保证完全不出现重复的情况,不过也已经好很多了,再用 SET 什么的保证完全不重复反而可能会带来更大的开销(Checklist 如是说)。

第二个优化是把汉明距离和曼哈顿距离存下来,不用需要的时候再重新算一遍。另外,存在没有解的情况,课程说这种情况随便交换两个数字后就是可解的(证明不清楚,感兴趣的或许可以参考:proof)。所以,为了处理无解的情况,我们还要同步进行另一个 A* 搜索,二者有一对数字相反,后者找到了解,那前者就是无解的。

任务摘要

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 that is obtained by exchanging any pair of blocks

public boolean equals(Object y) // does this board equal y?

public Iterable neighbors() // all neighboring boards

public String toString() // string representation of this board (in the output format specified below)

public static void main(String[] args) // unit tests (not graded)

}

Also, create 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 unsolvable

public Iterable solution() // sequence of boards in a shortest solution; null if unsolvable

public static void main(String[] args) // solve a slider puzzle (given below)

}

问题分析

时隔好久(上次提交是去年四月份。。。),再看原来通过的代码,好像没什么好讲的东西,不大记得当初碰到了什么问题。两个类绝大部分的计算,都在构造时进行,Board() 算了汉明距离和曼哈顿距离存好,Solver() 交替跑了两个 A*。

Board 里的 twin() 方法算一个自己发挥的部分:

public Board twin() {

int[][] copy = new int[n][n];

for (int i = 0; i < n; i++) {

for (int j = 0; j < n; j++) {

copy[i][j] = tiles[i][j];

}

}

if (copy[0][0] == 0) swap(copy, 0, 1, 1, 1);

else if (copy[0][1] == 0) swap(copy, 0, 0, 1, 0);

else swap(copy, 0, 0, 0, 1);

Board twinBoard = new Board(copy);

return twinBoard;

}

要求交换两个非零数字,如果前面两个不是零我就直接交换前两,要是确定有一个为零,那再随便交换两个(反正只有一个零)。

另外提下 equals() 方法,Checklist 里也有回答:

How do I implement equals()? Java has some arcane rules for implementing equals(), discussed on p. 103 of Algorithms, 4th edition. Note that the argument to equals() is required to be Object. You can also inspect Date.java or Transaction.java for online examples.

于是乎,这是书上的相关内容:

如果该对象的引用和参数对象的引用相同,返回 true。这项测试在成立时能够免去其他所有工作。

如果参数为空(null),根据约定返回 false(还可以避免在下面的代码中使用空引用)。

如果两个对象的类不同,返回 false。要得到一个对象的类,可以使用 getClass() 方法。请注意我们会使用 == 来判断 Class 类型的对象是否相等,因为同一种类型的所有对象的 getClass() 方法一定能够返回相同的引用。

将参数对象的类型从 Object 转换到相应的类型(因为前一项测试已经通过,这种转换必然成功)。

如果任意示例变量的值不相同,返回 false。这个不同的类需要不同的考虑。

最后附上我的 equals():

// does this board equal other?

public boolean equals(Object other) {

if (other == this) return true;

if (other == null) return false;

if (other.getClass() != this.getClass()) return false;

Board that = (Board) other;

if (that.n != this.n) return false;

for (int i = 0; i < n; i++) {

for (int j = 0; j < n; j++) {

if (that.tiles[i][j] != this.tiles[i][j]) {

return false;

}

}

}

return true;

}

Solver 里面不用你写优先队列,写个比较器丢到课程提供的就好。另外,关于还原路径,搜索节点里加个 preNode 就可以从目标一路回到初始。具体可以看:Solver.java,不提。

测试结果

时间不重要,转换班次才让我再次提交,上次提交记录是去年四月份,原来博客欠这么久了。。

8 puzzle java_Programming Assignment 4: 8 Puzzle相关推荐

  1. Programming Assignment 4: 8 puzzle

    8 puzzle 使用A*搜索算法解决8-puzzle问题. Board.java Board类用来表示一个 n∗n n ∗ n n*n的网格,其中有 n2−1 n 2 − 1 n^2-1个方块,每个 ...

  2. html puzzle游戏,Blockly培训案例-puzzle游戏的制作(一)

    去年的两期培训,发现老师们对blockly-games兴趣较高,而且参训老师在返校之后,很多都使用blockly-games进行了教学尝试.而设计这个案例的原因一是老师们对blockly-games较 ...

  3. puzzle java_Java AI为NxN Puzzle找到解决方案

    首先,有很多代码,因为我真的不知道我的问题在哪里,我道歉! 我正在制作一个解决不同尺寸拼图的程序,例如(3x3,0-8)零表示一个空白图块,目标是移动空白图块直到达到目标状态 . 目前我正在使用深度优 ...

  4. leetcode 1178. Number of Valid Words for Each Puzzle | 1178. 猜字谜(bitmask位运算)

    题目 https://leetcode.com/problems/number-of-valid-words-for-each-puzzle/ 题解 看了答案,堪称力扣最详细的答案,从时间复杂度的角度 ...

  5. 【UVA - 227】Puzzle (模拟,水题)

    题干: Puzzle  A children's puzzle that was popular 30 years ago consisted of a 5x5 frame which contain ...

  6. 自动拼图android github,GitHub - zero0011/Puzzle: 拼图游戏 , 可自动实现 拼图操作

    拼图游戏 启动 前端 npm i npm run dev 后端 cd server npm i nodemon app.js 实现功能有 普通的拼图功能 自动拼图功能(难点) 游戏聊天室的设计 效果大 ...

  7. usaco training 4.4.1 Shuttle Puzzle 题解

    Shuttle Puzzle题解 Traditional The Shuttle Puzzle of size 3 consists of 3 white marbles, 3 black marbl ...

  8. Solve Slide Puzzle with Hill Climbing Search Algorithm

    Hill climbing search algorithm is one of the simplest algorithm which falls under local search and o ...

  9. 《Design of Computer Programs》学习笔记(2 - 1)Back of the Envelope - Lesson 2

    Back of the Envelope envelope n.信封(金山词霸) Lesson 2 视频链接: Lesson 2 - Udacity 1. 练习:Zebra Puzzle zebra ...

最新文章

  1. [DONE]ReferenceError: WebSocket is not defined pomelo
  2. ASP.NET2.0服务器控件之类型化样式属性
  3. 如何将usb摄像头连接到虚拟机vmware ubuntu系统上?
  4. More than one file was found with OS independent path 'lib/arm64-v8a/libsqlite.so'
  5. 一方包,二方包,三方包的区别
  6. 启动SecureCRT出现ImportError: No module named _sysconfigdata_nd
  7. [原]逆向iOS SDK -- _UIImageAtPath 的实现(SDK 5.1)
  8. linux安装两个jdk_jdk在linux上安装过程
  9. java游戏有牧师_JAVA内部类是怎么玩儿的
  10. 文都计算机考研辅导班哪个好,考研辅导班哪个好,海文还是文都?
  11. 解决win10 蓝牙设备只能配对无法连接 ,并且删除设备无效的问题
  12. [Wireshark]交换机设置镜像端口并使用Wireshark抓包异常流量分析病毒种类
  13. 【网络攻防】常见的网络攻防技术——黑客攻防(通俗易懂版)
  14. java 泛型去重_泛型,list集合去重
  15. 索尼电视总出现Android,索尼BRAVIA电视推送更新:升级安卓8.0,修复众多问题
  16. ZYNQ LWIP实现任意长度数据接收发送
  17. 软件验收测试之α测试和β测试分别是什么?
  18. 4.2 存储器读写指令的发射与执行2
  19. windows 7 32bit安装 python3.5.0 安装错误 0x80240017 -未指定错误
  20. HTML 媒体(Media)

热门文章

  1. 二分类Logistic回归模型
  2. 什么是Java?java是用来做什么的?
  3. 2021年重庆高考成绩排名查询,2021重庆市地区高考成绩排名查询,重庆市高考各高中成绩喜报榜单...
  4. 陌陌双11报告:近半的95后通过社交软件脱单
  5. 近期数学建模竞赛汇总,一定要收藏!
  6. 大数据之hive 阿善看到
  7. DELL T110 安装windows server 2003
  8. atlbase.h 和 streams.h
  9. create and alter table
  10. 双目立体视觉(一) 基本原理和步骤