1.概述
马踏棋盘算法也被称为骑士周游问题
2.问题描述
将象棋马随机放在国际象棋的 8×8 棋盘(二维数组[0~7][0~7])的某个方格中,马按走棋规则(马走日字)进行移动,要求每个方格只进入一次,走遍棋盘上全部 64 个方格
3.解题方法
求解问题的方法有2种:
(1)使用 图的深度优先搜索(DFS) 回溯 进行求解
(2)使用 贪心算法 确定 贪心策略 优化方法(1) 进行求解
4.深度优先搜索
4.1使用深度优先搜索求解的基本思路
(1)创建一个棋盘类,封装相关属性与方法,包括如下
// 棋盘的行数
private int row;
// 棋盘的列数
private int column;
// 二维数组表示棋盘,记录象棋马进入二维数组中某个方格的顺序
private int[][] chessBoardArray;
// 棋盘中的某一个方格是否被象棋马进入过
// true 被进入过、false 未被进入过
private boolean[][] visited;
// 当前方格在棋盘中被象棋马进入的顺序,初始化为0,还未开始马踏棋盘
private int stepOrder;
// 是否成功走遍棋盘中的所有方格,初始化为false,未成功
private boolean success;
(2)开始求解马踏棋盘,标记象棋马当前进入的位置为已被访问状态,即 visited[row][column] = true ,标记当前位置是象棋马第几步走到该位置的,即 stepOrder++ ,获取象棋马当前位置的下一次可走路径(可走方格)的集合,即 ArrayList<Point> nextPathList = getNextPath(new Point(row, column))
(3)遍历 nextPathList 集合,如果遍历到的路径不可以走通,则继续遍历集合 nextPathList 中的下一个路径,如果遍历到的路径可以走通,则以遍历到路径做为新的起点递归执行马踏棋盘算法(深度优先搜索 的体现)
(4)判断象棋马是否走遍了棋盘中的所有方格且每个方格只进入一次,使用 stepOrder 与 棋盘的大小(row*column)进行比较,如果不相等则表示还未完成,则将象棋马当前进入的位置重置为 0 ,表示象棋马可以通过其他路径进入该方格,顺序未定,即 chessBoardArray[row][column] = 0 , stepOrder-- ,将象棋马当前进入的位置标记为为被访问,即 visited[row][column] = false , 如果象棋马是否走遍了棋盘中的所有方格且每个方格只进入一次,则 success = true, 算法执行完毕
5.贪心算法 优化
不用 贪心算法 优化,8*8 的棋盘,算法执行完毕耗时在