【Java数据结构与算法】骑士周游问题
骑士周游问题说明
-
马踏棋盘算法也被称为 骑士周游问题
-
将马随机放在国际象棋的 8×8 棋盘 Board
[0~7][0~7]
的某个方格中,马按走棋规则 (马走日字) 进行移动。要求每个方格只进入一次,走遍棋盘上全部 64 个方格。 -
如图所示
骑士周游问题思路图解
思路分析
-
马踏棋盘问题(骑士周游问题)实际上是图的深度优先搜索(DFS)的应用。
-
如果使用回溯(深度优先搜索)来解决,假如马儿踏了53个点,如下图:走到了第53个,坐标(1,0),发
现已经走到尽头,没办法,那就只能回退了,查看其他的路径,就在棋盘上不停的回溯。 -
分析使用回溯算法存在的问题,并使用贪心算法(greedyalgorithm)进行优化。
步骤分析
回溯算法步骤分析
-
创建棋盘chessBoard,定义为一个二维数组。
-
将当前位置设置为已经访问,然后根据当前位置,计算马还能走哪些位置,并放入到
一个集合中(ArrayList),最多有8个位置,每走一步,就使用step+1
。 -
遍历ArrayList中存放的所有位置,看看哪个可以走通,如果走通就继续,否则进行回溯。
-
判断马儿是否完成了任务,使用step和应该走的步数比较,如果没有达到数量,则表
示没有完成任务,将整个棋盘置0。 -
注意:马不同的走法(策略) ,会得到不同的结果,效率也会有影响。(需要进行优化)
-
马进行移动的代码举例:
1
2
3
4
5
6// 创建一个Point
Point p1 = new Point();
// 表示:马可以走到上图5的位置
if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y - 1) >= 0) {
ps.add(new Point(p1));
}
骑士周游回溯算法代码实现-移动方法
代码
1 | package com.algorithm.horse; |
骑士周游回溯算法代码实现-算法实现
代码
1 | package com.algorithm.horse; |
运行结果
可以看到运算花费时间将近22秒,需要进行优化;
1 | ~骑士周游启动~ |
骑士周游使用贪心算法优化
贪心算法优化步骤分析
-
我们获取当前位置,可以走的下一个位置的集合。
1
2// 获取当前位置可以走的下一个位置的集合
ArrayList<Point> ps = next(new Point(column,row)); -
我们需要对ps里的所有Point的下一步的全部集合的数目, 进行非递减排序。
1
2
3
48,7,6,5,3,2,1 // 递减排序
1,2,3,4,5,6,9, // 递增排序
1,2,2,3,3,3,5,6 // 非递减,在递增过程中允许重复
9,7,6,6,5,5,3,3,1 // 非递增,在递减过程中允许重复
代码实现
代码
1 | package com.algorithm.horse; |
运行结果
可以看到优化后速度非常快!
注意:更换策略意味着走法会有变法,结果也会不同;
1 | ~骑士周游启动~ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hey,Joker!
评论
ValineTwikoo