iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java学习笔记之马踏棋盘算法
  • 549
分享到

java学习笔记之马踏棋盘算法

2024-04-02 19:04:59 549人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

马踏棋盘或骑士周游问题 1、马踏棋盘算法也被称为骑士周游问题2、将马随机放在国际象棋的 8×8 棋盘 Board[0~7][0~7]的某个方格中,马按走棋规则(马走日字)

马踏棋盘或骑士周游问题

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

思路

会使用到深度优先思想和类似迷宫问题的寻路策略问题,和八皇后问题也有相似。

1、用一个二维数组建立整张棋盘。用另外一个二维数组保存棋盘的每一个位置是否走过
2、马在棋盘上有一个初始位置,将这个位置设为已走过,并将步数设为1.
3、获得在这个位置上,马下一步能走的位置集合
4、遍历集合里的所有位置,如果那个位置没走过,下一步(步数+1)就走它(递归
5、设置递归结束的标志.用一个布尔变量标志游戏是否成功。当游戏成功时,步数应该等于棋盘格子数。假如某一次,马走完了所有能走的下一步位置,步数还小于棋盘格子数并且还没成功,说明这个位置不能成功的完成游戏,就把这个位置恢复原样(棋盘设为0,设为未走过),接下来的递归会重新去寻找合适的路。如果步数等于棋盘总格子数,说明游戏成功,把标志的布尔变量设为true,这样在层层返回时就不会再进入上面的条件,递归就会逐渐结束而不会深入下去。

涉及到的方法:

根据此时的位置,判断马接下来能走的位置集合。
x的值代表列而y的值代表行
马是按照日字走的,所有当它在中间时最多有8种位置可以走,一 一判断那个位置是否超过棋盘边界。
每种可能都是if,而不是if-else if,因为要获得所有的可能性,而不是找出一个
假如list时一定要新建一个坐标,不能使用同一个,不然值就会互相影响


    public static ArrayList<Point> findWay(Point current) {
        ArrayList<Point> res = new ArrayList<>();
        //可以走的坐标
        Point p = new Point();
        //5
        if ((p.x = current.x - 2) >= 0 && (p.y = current.y - 1) >= 0) {
            res.add(new Point(p));
        }
        //6
        if ((p.x = current.x - 1) >= 0 && (p.y = current.y - 2) >= 0) {
            res.add(new Point(p));
        }
        //7
        if ((p.x = current.x + 1) < X && (p.y = current.y - 2) >= 0) {
            res.add(new Point(p));
        }
        //0
        if ((p.x = current.x + 2) < X && (p.y = current.y - 1) >= 0) {
            res.add(new Point(p));
        }
        //1
        if ((p.x = current.x + 2) < X && (p.y = current.y + 1) < Y) {
            res.add(new Point(p));
        }
        //2
        if ((p.x = current.x + 1) < X && (p.y = current.y + 2) < Y) {
            res.add(new Point(p));
        }
        //3
        if ((p.x = current.x - 1) >= 0 && (p.y = current.y + 2) < Y) {
            res.add(new Point(p));
        }
        //4
        if ((p.x = current.x - 2) >= 0 && (p.y = current.y + 1) < Y) {
            res.add(new Point(p));
        }
        return res;
    }

马塔棋盘

不能单纯以step < X * Y来判断是否完成游戏,因为递归回溯时步数也会回溯,所以要设置一个变量

 
    public static void traversalChessboard(int[][] chess, int row, int col, int step) {
        //先走一步
        chess[row][col] = step;
        visit[row][col] = true;
        //下一步能走的地
        ArrayList<Point> way = findWay(new Point(col, row));
        while (!way.isEmpty()) {
            //取出一个能走的地方
            Point point = way.remove(0);
            //走下一步
            if (!visit[point.y][point.x]) {
                traversalChessboard(chess, point.y, point.x, step + 1);
            }

        }
        //判断是否完成游戏,如果没完成就要回溯
        if (step < X * Y && !finshed) {
            chess[row][col] = 0;
            visit[row][col] = false;
        }else {
            finshed=true;
        }
    }

优化

这样计算效率比较低,算法比较慢。实际上当我们获得下一步可以走的位置数组时是按照固定的56701234顺序排列的,但是这样效率不高,我们在考虑到走下一步时,应该先走对应下一步的可能性最少的那一步,比如如果7的下一步有3种可能,而5的下一步有6种可能,那先7后5的效率会更高。

所以我们可以使用贪心算法对获得的这个步数集合根据他们下一步的可能性进行由小到大的排序


    public static void sort(ArrayList<Point> ps){
        ps.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
                int way1 = findWay(o1).size();
                int way2 = findWay(o2).size();
                if(way1<way2){
                    return -1;
                }else if(way1==way2){
                    return 0;
                }else {
                    return 1;
                }
            }
        });
}

对Comparetor.compare(o1, o2)方法的返回值,如果返回的值小于零,则不交换两个o1和o2的位置;如果返回的值大于零,则交换o1和o2的位置。 注意,不论在compare(o1, o2)中是如何实现的(第一种实现方式是 o1-02, 第二种实现方式是 o2 - o1),都遵循上述原则,即返回值小于零,则交换o1和o2的位置;返回值大于零,则不交换o1和o2的位置。 所以,如果采用第一种实现方式,即 o1 - o2, 那么将是升序排序。因为在原始排序中o1在o2的前边,如果o1小于o2,那么o1 - o2小于零,即返回值是小于零,但是小于零是不会交换o1和o2的位置的,所以o1依然排在o2的前边,是升序;如果o1大于o2,那么o1 - o2大于零,即返回值是大于零,大于零是要交换o1和o2的位置的,所以要改变原始排序中o1和o2的位置,那么依然是升序

最终代码

package alGorithm;

import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;


public class HorseChessboard {
    static int X;//列
    static int Y;//行
    static boolean[][] visit;
    static boolean finshed;

    public static void main(String[] args) {
        X = 8;
        Y = 8;
        visit = new boolean[X][Y];
        finshed = false;
        int[][] chess = new int[X][Y];
        long s = System.currentTimeMillis();

        traversalChessboard(chess, 2, 0, 1);
        long e=System.currentTimeMillis();
        System.out.println(e-s);

        for (int i = 0; i < chess.length; i++) {
            System.out.println(Arrays.toString(chess[i]));
        }

    }

    
    public static void traversalChessboard(int[][] chess, int row, int col, int step) {
        //先走一步
        chess[row][col] = step;
        visit[row][col] = true;
        //下一步能走的地
        ArrayList<Point> way = findWay(new Point(col, row));
        sort(way);
        while (!way.isEmpty()) {
            //取出一个能走的地方
            Point point = way.remove(0);
            //走下一步
            if (!visit[point.y][point.x]) {
                traversalChessboard(chess, point.y, point.x, step + 1);
            }

        }
        if (step < X * Y && !finshed) {
            chess[row][col] = 0;
            visit[row][col] = false;
        }else {
            finshed=true;
        }
    }

    
    public static ArrayList<Point> findWay(Point current) {
        ArrayList<Point> res = new ArrayList<>();
        //可以走的坐标
        Point p = new Point();
        //5
        if ((p.x = current.x - 2) >= 0 && (p.y = current.y - 1) >= 0) {
            res.add(new Point(p));
        }
        //6
        if ((p.x = current.x - 1) >= 0 && (p.y = current.y - 2) >= 0) {
            res.add(new Point(p));
        }
        //7
        if ((p.x = current.x + 1) < X && (p.y = current.y - 2) >= 0) {
            res.add(new Point(p));
        }
        //0
        if ((p.x = current.x + 2) < X && (p.y = current.y - 1) >= 0) {
            res.add(new Point(p));
        }
        //1
        if ((p.x = current.x + 2) < X && (p.y = current.y + 1) < Y) {
            res.add(new Point(p));
        }
        //2
        if ((p.x = current.x + 1) < X && (p.y = current.y + 2) < Y) {
            res.add(new Point(p));
        }
        //3
        if ((p.x = current.x - 1) >= 0 && (p.y = current.y + 2) < Y) {
            res.add(new Point(p));
        }
        //4
        if ((p.x = current.x - 2) >= 0 && (p.y = current.y + 1) < Y) {
            res.add(new Point(p));
        }
        return res;
    }

    
    public static void sort(ArrayList<Point> ps){
        ps.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
                int way1 = findWay(o1).size();
                int way2 = findWay(o2).size();
                if(way1<way2){
                    return -1;
                }else if(way1==way2){
                    return 0;
                }else {
                    return 1;
                }
            }
        });
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: java学习笔记之马踏棋盘算法

本文链接: https://www.lsjlt.com/news/139139.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java学习笔记之马踏棋盘算法
    马踏棋盘或骑士周游问题 1、马踏棋盘算法也被称为骑士周游问题2、将马随机放在国际象棋的 8×8 棋盘 Board[0~7][0~7]的某个方格中,马按走棋规则(马走日字)...
    99+
    2024-04-02
  • Java实现马踏棋盘算法
    本文实例为大家分享了Java实现马踏棋盘的具体代码,供大家参考,具体内容如下 马在某个点最多可能有8种走法,用递归和回溯实现。 注:代码中,查找下一个可走坐标是从右下第一个开始的,也...
    99+
    2024-04-02
  • java数据结构与算法之马踏棋盘
    本文实例为大家分享了java数据结构与算法之马踏棋盘的具体代码,供大家参考,具体内容如下 马踏棋盘算法也被称为骑士周游问题将马随机放在过期象棋的8x8棋盘的某个方格中,马按走棋规则进...
    99+
    2024-04-02
  • java数据结构和算法之马踏棋盘算法
    本文实例为大家分享了java实现算法之马踏棋盘的具体代码,供大家参考,具体内容如下 一、马踏棋盘算法介绍 马踏棋盘算法也被称为骑士周游问题将马随机放在国际象棋的8×8棋盘...
    99+
    2024-04-02
  • java实现马踏棋盘的算法
    本文实例为大家分享了java实现马踏棋盘的具体代码,供大家参考,具体内容如下 马踏棋盘算法介绍 8X8棋盘,马走日字,要求每个方格只进入一次,走遍棋盘上全部64个方格。 代码: p...
    99+
    2024-04-02
  • java怎么实现马踏棋盘算法
    本篇内容介绍了“java怎么实现马踏棋盘算法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!马踏棋盘或骑士周游问题马踏棋盘算法也被称为骑士周游...
    99+
    2023-06-29
  • C++算法设计之马踏棋盘的实现
    本文实例为大家分享了C++算法设计之马踏棋盘的具体代码,供大家参考,具体内容如下 (一)马踏棋盘经典算法描述:   (1)马踏棋盘是经典的程序设计问题之一,主要的解决方案有...
    99+
    2024-04-02
  • C/C++实现马踏棋盘算法
    本文实例为大家分享了C/C++实现马踏棋盘的具体代码,供大家参考,具体内容如下 问题描述:将马随机放在国际象棋的8×8棋盘Board[0~7][0~7]的某个方格中,马按...
    99+
    2024-04-02
  • 基于Java实现马踏棋盘游戏算法
    马踏棋盘很好实现,但有时运行起来特别慢,还可能出不来结果,最常用的就是深度优先遍历+回溯,相信大家都学过数据结构,对图的深度遍历都有了解,下面就是代码的实现,如果对代码理解有困难,可...
    99+
    2024-04-02
  • C++贪心算法实现马踏棋盘
    本文实例为大家分享了C++贪心算法实现马踏棋盘的具体代码,供大家参考,具体内容如下 算法实现流程: 步骤1:初始化马的位置(结构体horse {x, y}) 步骤2:确定马从当前点...
    99+
    2024-04-02
  • java实现马踏棋盘算法(骑士周游问题)
    骑士周游问题 在8x8的国际棋盘上,按照马走日的规则,验证是否能够走遍棋盘。 解题思路 1、创建棋盘 chessBoard,是一个二维数组。2、将当前位置设置为已经访问,然后根据当...
    99+
    2024-04-02
  • C#学习笔记之飞行棋项目
    本文实例为大家分享了C#控制台实现飞行棋项目的具体代码,供大家参考,具体内容如下 飞行棋游戏介绍 此次编程实现的飞行棋和我们小时候玩的有些不一样,规则大致类似,但是我在学习过程中的飞...
    99+
    2024-04-02
  • 算法学习笔记2023.1
    为什么要学算法 因为算法无处不在 算法可以性能优化 c++ 面试问题 #includeusing namespace std;void selectSort( int arr[], int n){ for(i...
    99+
    2023-10-12
    学习 笔记
  • Java实现马踏棋盘游戏算法的代码怎么写
    这篇文章主要介绍“Java实现马踏棋盘游戏算法的代码怎么写”,在日常操作中,相信很多人在Java实现马踏棋盘游戏算法的代码怎么写问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java实现马踏棋盘游戏算法的代码...
    99+
    2023-06-29
  • 如何使用C/C++实现马踏棋盘算法
    这篇文章主要介绍如何使用C/C++实现马踏棋盘算法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下问题描述:将马随机放在国际象棋的8&times;8棋盘Board[0~7][0~7]的某个方格中,马...
    99+
    2023-06-29
  • Java学习笔记之Maven篇
    目录一、maven能做什么?1.1 两大应用1.2 maven 的核心二、maven结构:2.1 maven工程标准目录结构2.2 配置系统变量2.3 常用命令三、应用:idea集成...
    99+
    2024-04-02
  • C++基于栈的深搜算法实现马踏棋盘
    马踏棋盘(基于栈的深搜算法实现) 简单来说,从任意指定方格出发,为马寻找一条走遍棋盘每一格并且只经过一次的一条路径,这就是马踏棋盘的简单描述。 话不多说,代码如下,要是有什么不懂的地...
    99+
    2024-04-02
  • Matplotlib学习笔记之plt.xticks()用法
    目录前言函数功能函数语法函数参数例子参考总结前言 在学习ML的过程中,遇到plt.xticks()的使用,在网上看别人写的教程,看得有点头晕,最后看官方文档和一个例子才明白了其用法。...
    99+
    2024-04-02
  • HTML语法学习笔记:记录您的学习之旅
    HTML 简介 超文本标记语言 (HTML) 是互联网上网页的基础。它是一种标记语言,用于定义网页的结构和内容。学习 HTML 语法对于成为一名成功的网络开发者至关重要。 HTML 元素 HTML 中的基础构建块是元素。它们由一对尖括号...
    99+
    2024-03-09
    HTML、语法、学习、教程、网络开发
  • Java学习笔记之Pattern类的用法详解
    Pattern类是Java中正则表达式的主要类之一,它提供了一系列方法来操作正则表达式。正则表达式是一种用来匹配字符串的强大工具,它...
    99+
    2023-09-02
    java
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作