一,基本介绍

1)马踏棋盘算法也称为骑士周游问题
2)将马随机放在国际象棋的8 × 8棋盘Board[0~7] [0~7]的某个方格中,马按走棋规则(马走日字)进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格

二,基本思路

1)马踏棋盘问题(骑士周游世界问题)实际上是图的深度优先搜索(DFS)的应用;
2)如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了第53个,发现已经走到了尽头,没办法,那就只能回退了,查看其他的路径,就在棋盘上不停回溯…效率很低;
3)因此需要使用贪心算法(greedyalgorithm)进行优化。我们直接使用贪心算法,优化思路来解决马踏棋盘问题

三,思路分析

1)创建棋盘chessBoard,是一个二维数组;
2)将当前位置设置为已经访问,然后根据当前位置,计算马儿还能走哪些位置,并放入到一个集合中(ArrayList),最多有8个位置;
3)遍历ArrayList中存在的所有位置,看看哪个可以走通;如果走通,继续,走不通,就回溯;
4)判断马儿是否完成任务了任务step和应该走的步数比较
注意:马儿的不同走法(策略),会得到不同的结果,效率也会有影响(优化)
使用贪心算法对原来算法优化
1)我们获取当前位置,可以走下一个位置的集合
//获取当前位置,可以走的下一个位置集合
2)我们需要对ps中所有的point的下一步的所有集合的数目,进行非递减排序(1,1,2,3,4,4,5),就ok

四,代码实现

package com.algorithm.horse;import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;public class HorseChessboard {private static int x; //棋盘的列数private static int y; //棋盘行数//创建一个数组,标记棋盘的各个位置是否被访问过private static boolean visited[];//使用一个属性,标记是否棋盘的所有位置都被访问private static boolean finished; //如果为true,表示成功public static void main(String[] args) {//测试x = 8;y = 8;int row = 1; //马儿初始位置的行,从1开始编号int column = 1; //马儿初始化位置的列,从1开始编号//创建棋盘int[][] chessboard = new int[x][y];visited = new boolean[x * y]; //初始化值都是false//测试一下消耗long start = System.currentTimeMillis();traversalChessboard(chessboard,row - 1,column - 1,1);long end = System.currentTimeMillis();System.out.println("共耗时:" + (end - start) + "ms");//输出棋盘的最后情况for (int[] rows : chessboard) {for (int step : rows) {System.out.print(step + "\t");}System.out.println();}}/*** 完成马踏棋盘问题的算法* @param chessboard 棋盘* @param row 马儿当前位置的行,从0开始* @param column 马儿当前位置的列,从0开始* @param step 是第几步,初始位置就是第一步*/private static void traversalChessboard(int[][] chessboard,int row,int column,int step) {chessboard[row][column] = step;visited[row * x + column] = true; //该位置已经访问//获取当前位置可以走的下一个位置的集合ArrayList<Point> ps = next(new Point(column, row));//对ps进行排序,排序的规则就是对ps的所有的Point对象的下一步位置的数目,进行排序sort(ps); //改进所在//遍历pswhile (!ps.isEmpty()) {Point p = ps.remove(0); //取出下一个可以走的点//判断该店是否已经访问if (!visited[p.y * x + p.x]) { //说明还没有访问过traversalChessboard(chessboard,p.y,p.x,step + 1);}}//判断马儿是否完成任务,使用step和应该走的步数比较//如果没有达到数量,则表示没有完成任务,将整个棋盘置为0//1.棋盘到目前位置,仍然没有走完//2.棋盘处于一个回溯过程if (step < x * y && !finished) {chessboard[row][column] = 0;visited[row * x + column] = false;} else {finished = true;}}/*** 根据当前位置,计算马儿还能走哪些位置,并放入到一个集合中(ArrayList),最多有8个位置;* @param curPoint* @return*/public static ArrayList<Point> next(Point curPoint) {//创建一个ArrayListArrayList<Point> ps = new ArrayList<Point>();//创建一个PointPoint p1 = new Point();//判断马儿可不可以走5这个位置 (即左上角,见上图)if ((p1.x = curPoint.x - 2) >=0 && (p1.y = curPoint.y - 1) >= 0) {ps.add(new Point(p1));}//判断马儿可不可以走6这个位置if ((p1.x = curPoint.x - 1) >=0 && (p1.y = curPoint.y - 2) >= 0) {ps.add(new Point(p1));}//判断马儿可不可以走7这个位置if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y - 2) >= 0) {ps.add(new Point(p1));}//判断马儿可不可以走0这个位置if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y - 1) >= 0) {ps.add(new Point(p1));}//判断马儿可不可以走1这个位置if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y + 1) < y) {ps.add(new Point(p1));}//判断马儿可不可以走2这个位置if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y + 2) < y) {ps.add(new Point(p1));}//判断马儿可不可以走3这个位置if ((p1.x = curPoint.x - 1) >=0 && (p1.y = curPoint.y + 2) < y) {ps.add(new Point(p1));}//判断马儿可不可以走4这个位置if ((p1.x = curPoint.x - 2) >=0 && (p1.y = curPoint.y + 1) < y) {ps.add(new Point(p1));}return ps;}//根据当前这一步的所有下一步的选择位置,进行非递减排序public static void sort(ArrayList<Point> ps) {ps.sort(new Comparator<Point>() {@Overridepublic int compare(Point o1, Point o2) {//获取到o1点的下一步的所有位置个数int count1 = next(o1).size();int count2 = next(o2).size();if (count1 < count2) {return -1;} else if (count1 == count2) {return 0;} else {return 1;}}});}
}

五,运行结果

没优化前

优化后

【数据结构与算法】马踏棋盘(骑士周游世界)算法相关推荐

  1. 数据结构——马踏棋盘题解(贪心算法)

    本文转自: https://blog.csdn.net/qq_41596568/article/details/83060317 数据结构--马踏棋盘题解(贪心算法) 使用循环建立棋盘与权值棋盘(权值 ...

  2. 数据结构——马踏棋盘题解(贪心算法)(C语言)

    数据结构--马踏棋盘题解(贪心算法) 使用循环建立棋盘与权值棋盘(权值为该位置可走的位置数量) 将当前步数写入棋盘数组中 开始探测下一步该走的位置, 分别测试八个方向 对可走位置进行查询权值,将权值最 ...

  3. 马踏棋盘的问题——贪心算法

    [贪心算法] 其实马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法. 在每个结点对其子结点进行选取时,优先选择 '出口'最小的进行搜索,'出口'的意思 ...

  4. 数据结构(七)——Dijkasta 、Flyod、马踏棋盘算法

    Dijkstra 算法 应用场景-最短路径问题 有 7 个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从 G 点出发,需要分别把邮件分别送到A, B, C , D, E, F 六 ...

  5. 【算法】马踏棋盘算法 骑士走周游算法

    文章目录 1.概述 2.贪心优化 1.概述 马踏棋盘算法和八皇后问题很相似:[算法]八皇后问题 骑士周游问题的解决步骤和思路 创建棋盘chessBoard,是一个二维数组 将当前位置设置为已经访问,然 ...

  6. 马踏棋盘算法(骑士周游问题)

    要求: 国家棋盘为8*8的方格棋盘,将"马"放在任意指定方格中.最终让马走遍64个方格. 关于象棋中马的走法 如下图所示: 下面是代码: #include <stdio.h& ...

  7. 数据结构与算法|马踏棋盘算法(小甲鱼)C语言代码的算法分析

    马踏棋盘算法(骑士周游问题)的算法分析 C语言代码部分来自小甲鱼的<数据结构与算法> 文章目录 马踏棋盘算法(骑士周游问题)的算法分析 一.C语言代码实现 二.代码分析与算法思路 题目要求 ...

  8. 骑士周游(马踏棋盘)问题

    1,马踏棋盘算法介绍 马踏棋盘问题也被称为骑士周游问题 将马随机放在国际象棋的8*8的棋盘中的某个格子里,马按照走棋规则(日子)进行移动.要求每个方格只进入一次,走遍64个方格 2,马踏棋盘算法思路分 ...

  9. Java对马踏棋盘问题(骑士周游问题)的实现

    14.10.2 马踏棋盘游戏代码实现 马踏棋盘问题(骑士周游问题)实际上是图的深度优先搜索(DFS)的应用. 如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了 53 个点,如图:走到了第 53 个 ...

最新文章

  1. 台式计算机系统重新安装软件,有人教我重装电脑程序的吗,谢谢了
  2. 数据中心机房布线设计方案
  3. idea2019运行php项目,新版IntelliJ phpstrom IDEA 2019.2版本的使用方法
  4. linux PROC文件系统详解
  5. 2021牛客暑期多校训练营4 B - Sample Game 期望dp\生成函数
  6. LeetCode 239. 滑动窗口最大值(双端队列+单调栈)
  7. Ubuntu 放弃支持 32 位应用程序实属乌龙
  8. 解决编译错误: 非法字符: '\ufeff' 解决方案|错误: 需要class, interface或enum
  9. UVA11152 Safe Salutations【计算几何】
  10. intel h61 linux驱动下载,IntelIntel DH61AG BIOS 0022.BI主板驱动官方正式版下载,适用于dos-驱动精灵...
  11. 阿里云购买域名到建站的全流程怎么做?
  12. 连续均匀聚苯乙烯纳米微球造孔剂/氨基化聚苯乙烯微球/羧基功能化马来酸酉干(MA)聚苯乙烯微球
  13. iOS 10诸如相机、相册、通讯录、麦克风、定位权限设置,防止奔溃或上架被拒
  14. 助力危化运输升级 欧曼一体化解决方案再写山东危化安全运输新篇
  15. python打印皮卡丘步骤_编程作战丨如何利用python绘制可爱皮卡丘?
  16. 我是个28岁的IT,我现在慌得一比
  17. css彩色波浪动画,纯css实现波浪动画【转】
  18. 浏览器地址栏字符串转化
  19. indexOf()使用详解
  20. OPENCV针对图像EXIF旋转问题

热门文章

  1. 域控禁用计算机网络,域控禁用usb接口 域控制器如何禁用usb端口的方法
  2. 用matlab画钥匙,Matlab在锁具装箱问题中的应用.ppt
  3. PC设置局域网打印机
  4. C语言的链表和数组-诺禾
  5. cppcheck的安装及基本使用
  6. html5需要很高的电脑配置,上古卷轴5需要什么配置要求 配置要求高吗
  7. 监督学习、无监督学习、半监督学习
  8. PQMagic 错误提示
  9. 坏账损失及应纳税影响会计处理
  10. matlab 向量场线积分