当前位置: 首页 > news >正文

【Java学习笔记】75 - 算法优化入门 - 马踏棋盘问题

一、意义

1.算法是程序的灵魂,为什么有些程序可以在海量数据计算时,依然保持高速计算?

2.拿老韩实际工作经历来说,在Unix下开发服务器程序,功能是要支持上千万人同时在线,在上线前, 做内测,一切OK,可上线后,服务器就支撑不住了,公司的CTO对代码进行优化,再次上线,坚如磐石。那一瞬间,你就能感受到程序是有灵魂的,就是算法。

3.编程中算法很多,比如八大排序算法(冒泡、选择、插入、快排、归并、希尔、基数、堆排序、查找算法、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法

4.老韩以骑士周游问题为例,让小伙伴体验用算法去优化程序的意义,让大家直观的感受到算法的威力

二、经典算法问题 - 骑士周游问题

1.马踏棋盘算法也被称为骑士周游问题

2.将马随机放在国际象棋的8x 8棋盘Board[0 ~ 7][0 ~ 7]的某个方格中,马按走棋规则(马走日字)进行移动。要求每个方格只进入次,走遍棋盘上全部64个方格

3.游戏演示:https://u.ali213.net/games/horsesun/index.html?game_ code= 403

4.会使用到图的遍历算法(DFS) +贪心算法优化

算法介绍

1.马踏棋盘问题(骑士周游问题)实际上是图的深度优先搜索(DFS)的应用。

2.如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了53个点,如图:走到了第53个,坐标(1,0),发现已经走到尽头,没办法,那就只能回退了,查看其他的路径,就在棋盘上不停的..... ,思路分析+代码实现

3.先用基本方式来解决,然后使用贪心算法(greedyalgorithm) 进行优化。解决马踏棋盘问题,体会到不同的算法对程序效率的影响

4.使用前面的游戏来验证算法是否正确
 

解决步骤和思路分析

1.创建棋盘chessBoard,是二维数组,

2.将当前位置设置为已经访问,然后根据当前位置,计算马儿还能走哪些位置,并放入到个集合中(ArrayList), 最多有8个,每走一步,使用step+1

3.遍历ArrayList中存放的所有位置,看看那个可以走,如果可以走通,就继续,走不通,就回溯

4.判断马儿是否完成了任务,使用step和应该走的步数比较,如果没有达到数量,则表示没有完成任务,将整个棋盘设置为0

注意:马儿走的策略不同,则得到的结果也不一样,效率也不一样.

多想想 很巧妙的思路

public class HorseChessBoard {private static int X = 6; //colprivate static int Y = 6; //rowprivate static int[][] chessBoard = new int[Y][X]; //棋盘private static boolean[] visited = new boolean[X * Y];//记录某个位置是否走过private static boolean finished = false; //记录马儿是否遍历完棋盘public static void main(String[] args) {int row = 2;int col = 2;long start = System.currentTimeMillis();traversalChessBoard(chessBoard,row - 1,col - 1 , 1);long end = System.currentTimeMillis();System.out.println("耗时" + (end - start) + "ms");for(int[] rows : chessBoard){for (int step : rows){ //step表示该位置是马儿走的第几步System.out.print(step + "\t");}System.out.println();}}//编写核心算法 遍历棋盘 如果遍历成功 就把finished设置为true;public static void traversalChessBoard(int[][] chessBoard, int row,int col,int step){//先把step 记录到chessBoardchessBoard[row][col] = step;//把这个位置设置为已访问visited[row * X + col] = true;//这个索引计算能计算行列在一维数组的对应的下标//获取当前位置可以走的下一个位置有哪些ArrayList<Point> ps = next(new Point(col, row));//col - X,row - Y//遍历while (!ps.isEmpty()){//取出一个位置(点) 取出当前这个ps的第一个点Point p = ps.remove(0);if(!visited[p.y * X + p.x]){//如果这个取出点没有走过//递归遍历traversalChessBoard(chessBoard,p.y,p.x,step + 1);}}//当退出while 看看是否遍历成功,如果没有成功,就重置相应的值,然后进行回溯if(step < X * Y && !finished){//重置chessBoard[row][col] = 0;visited[row * X + col] = false;}else{finished = true;}}public static ArrayList<Point> next(Point curPoint){//创建一个ArrayListArrayList<Point> ps = new ArrayList<>();//创建一个Point对象(点/位置),准备放入到psPoint p1 = new Point();//判断在curPoint是否可以走如下位置,如果可以走,就将该点(Point)放入到ps//判断是否可以走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;}
}

 

对代码使用贪心算法,进行优化,提高速度

分析
1.我们现在走的下一个位置,是按照我们的顺时针来挑选位置,因此选择的这个点的下-一个可以走的位置的个数是不确定的.

2.优化思路是:我们应该选择下一个的下一个可以走的位置较少的点,开始走,这样可以减少回溯的此时

3.代码:对我们的ps集合按照可以走的下一个位置的次数进行排序,升序排序.

//写一个方法,对ps的各个位置,可以走的下一个位置的次数进行排序,把可能走的下一个位置从小到大排序public static void sort(ArrayList<Point> ps){ps.sort(new Comparator<Point>() {@Overridepublic int compare(Point o1, Point o2) {return next(o1).size() - next(o2).size();}});}

仅仅只是对该存放的可能点进行最小可能点排序 

相关文章:

【Java学习笔记】75 - 算法优化入门 - 马踏棋盘问题

一、意义 1.算法是程序的灵魂&#xff0c;为什么有些程序可以在海量数据计算时&#xff0c;依然保持高速计算? 2.拿老韩实际工作经历来说&#xff0c;在Unix下开发服务器程序&#xff0c;功能是要支持上千万人同时在线&#xff0c;在上线前&#xff0c; 做内测&#xff0c;一…...

第二十章 多线程

20.2创建线程 20.2.1继承Thread类 Thread类是Java.lang包中的一个类&#xff0c;从这个类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建议Thread实例。 public class ThreadTest extedns Thread{} run方法格式&#xff1a; public void run(){} 20.1让线程循…...

vue2使用npm依赖包导出xlsx文件

1.下载依赖npm i xlsx 2.在根目录utils新建mergeXlxs.js /****/ import { utils, writeFile } from "xlsx";export default function mergeHeader(headers, data, datamerges, defaultTitle) {const ws utils.book_new();utils.sheet_add_aoa(ws, headers);//这里…...

java--多态

1.什么是多态 多态是在继承/实现的情况下的一种现象&#xff0c;表现为&#xff1a;对象多态、行为多态。 2.多态的具体代码体现 编译看左边&#xff0c;运行看右边 3.多态的前提 有继承/实现关系&#xff1b;存在父类引用子类对象&#xff1b;存在方法重写 4.多态的一个注…...

知识图谱06——将pdf中的表格(文字形式)保存至csv中

使用ubuntu22.04&#xff0c;anaconda 由于装环境装了一阵子&#xff0c;不确定装了哪些包了 可能的环境安装 conda install -c conda-forge pymupdf conda install -c conda-forge camelot-py conda install pandas #或者 pip install PyMuPDF pip install camelot-py[all] …...

一文教你使用Swagger---适合新手小白(结合实战)

1.什么是Swagger Swagger----在线自动生成接口文档&#xff0c;是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化RESTful风格的Web服务&#xff0c;可用于接口的文档在线自动生成以及功能测试。 2.Swagger与OpenAPI OpenAPI规范OpenAPI Specification以前叫…...

VC++调试QT源码

环境&#xff1a;vs2017 qt 5.14.2 1&#xff1a;首先我们需要选择我们的源码路径 右键解决方案-》属性-》通用属性-》调试源文件-》在窗口内添加QT下载时的源码**.src文件夹**&#xff0c;这里最好把源码 D:\software\QT\path\5.14.2\Src 源文件里面的Src文件做一个备份出来…...

058-第三代软件开发-文件Model

第三代软件开发-文件Model 文章目录 第三代软件开发-文件Model项目介绍文件Model 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&#xff09;…...

【领域驱动设计 学习目标及大纲】从CRUD到架构设计

从2018年至今&#xff0c;已工作了5年有余&#xff0c;回望这5年的工作历程&#xff0c;虽然一直在学习、一直在积累&#xff0c;但其实都在术的层面上停留&#xff0c;也就是具体的技术点。这5年多的时间里其实也不是没有窥道的想法&#xff1a; 一次是2018年刚工作的时候&am…...

asla四大开源组件应用示例(alsa-lib、alsa-utils、alsa-tools、alsa-plugins)

文章目录 alsa设备文件/dev/snd//sys/class/sound/proc/asoundalsa-lib示例1alsa-utilsalsa-toolsalsa-plugins参考alsa设备文件 /dev/snd/ alsa设备文件目录位于,/dev/snd,如下所示 root@xboard:~#ls /dev/snd -l total 0 drwxr-xr-x 2 root root 60 Nov 6 2023 …...

文档理解的新时代:LayOutLM模型的全方位解读

一、引言 在现代文档处理和信息提取领域&#xff0c;机器学习模型的作用日益凸显。特别是在自然语言处理&#xff08;NLP&#xff09;技术快速发展的背景下&#xff0c;如何让机器更加精准地理解和处理复杂文档成为了一个挑战。文档不仅包含文本信息&#xff0c;还包括布局、图…...

【二叉树】Leetcode 637. 二叉树的层平均值

637.二叉树的层平均值 解题思路 根据层序遍历的模板进行修改&#xff1b;主要的不同是&#xff0c;不需要输出每一层所有节点值&#xff0c;只需要输出平均值&#xff0c;只需要定义一个double双精度浮点数储存每一层数的总和&#xff0c;输出时将总和除以层节点总数即为层平均…...

设计模式-15-Jdk源码中的设计模式

之前我们学习了一些设计模式&#xff0c;今天我们剖析Java JDK 源码中用到的几种常见的设计模式。 1-jdk之工厂模式 在前面讲到工厂模式的时候&#xff0c;大部分工厂类都是以Factory作为后缀来命名&#xff0c;并且工厂类主要负责创建对象这样一件事情。但在实际的项目开发中…...

Vue框架学习笔记——事件scroll和wheel的区别

文章目录 前文提要滚动条滚动事件 scroll鼠标滚动事件 wheel二者不同点 前文提要 本人仅做个人学习记录&#xff0c;如有错误&#xff0c;请多包涵 滚动条滚动事件 scroll scroll事件绑定html页面中的指定滚动条&#xff0c;无论你拖拽滚动条&#xff0c;选中滚动条之后按键盘…...

【LeetCode】每日一题 2023_11_29 无限集中的最小数字(哈希/堆)

文章目录 刷题前唠嗑题目&#xff1a;无限集中的最小数字题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 今天的题目也比较的简单&#xff0c;因为数据量不大&#xff0c;所以什么做法都能过的去 题目&a…...

C/C++ 常用的四种查找算法

在计算机科学中&#xff0c;搜索算法是一种用于在数据集合中查找特定元素的算法。C语言作为一种强大的编程语言&#xff0c;提供了多种搜索算法的实现方式。本文将介绍C语言中的四种常见搜索算法其中包括&#xff08;线性查找&#xff0c;二分法查找&#xff0c;树结构查找&…...

Linux | Ubuntu设置 netstat(网络状态)

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据&#xff0c;一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序&#xff0c;它能提供TCP连接&#xff0c;TCP和UDP监听&#xff0c;进程内存管理的相关报告。 1.netstat的安装 搜…...

成为AI产品经理——模型构建流程(下)

目录 1.模型训练 2.模型验证 3.模型融合 4.模型部署 上节课我们讲了模型设计、特征工程&#xff0c;这节课我们来讲模型构建剩下的三个部分&#xff1a;模型训练、模型验证和模型融合。 1.模型训练 模型训练就是要不断地训练、验证、调优直至让模型达到最优。 那么怎么达…...

TCP Socket API 讲解,以及回显服务器客户端的实现

文章目录 TCPServerSocket APISocket API TCP 客户端服务器的实现 TCP ServerSocket API ServerSocket 是创建TCP服务端 Socket 的 API。 serverSocket构造方法&#xff1a; 方法签名方法说明ServerSocket(int port)创建一个服务端流套接字Socket&#xff0c;并绑定到指定端…...

2023年掌控安全学院CTF暖冬杯——数据流分析

前言&#xff1a;打工仔一枚&#xff0c;第一波上新的3题misc 做完了 再打ISCTF随便记录一下 PS&#xff1a;环境关了&#xff0c;题目描述忘记了&#xff0c;反正就是找flag。 筛选HTTP数据流 导出数据流慢慢看 ctrl F 搜flag 看到一条 有flag.txt 的数据 导出另存.zip 这里…...

安全稀疏矩阵乘法:基于二叉树递归传播的MPC算法优化详解

1. 项目概述&#xff1a;当稀疏矩阵乘法遇上安全多方计算 在分布式机器学习、联合数据分析以及隐私保护推荐系统的构建中&#xff0c;我们常常面临一个核心矛盾&#xff1a;数据的所有权分散在多个互不信任的参与方手中&#xff0c;大家希望共同训练一个模型或进行一次计算&…...

Token CSS高级技巧:如何扩展自定义设计令牌和主题的终极指南

Token CSS高级技巧&#xff1a;如何扩展自定义设计令牌和主题的终极指南 【免费下载链接】tokencss 项目地址: https://gitcode.com/gh_mirrors/to/tokencss Token CSS是一个革命性的设计令牌工具&#xff0c;它让CSS开发变得更加智能和高效。如果你已经掌握了Token CS…...

实战避坑:在Unity里用A*做2D网格寻路,我踩过的性能坑和优化方案都在这了

Unity中A*算法性能优化的实战指南当你在Unity项目中实现了一个基础A寻路系统后&#xff0c;随着游戏单位数量增加或地图规模扩大&#xff0c;性能问题往往会突然出现。帧率下降、卡顿现象频发&#xff0c;这些问题在移动端或需要大量单位同时寻路的RTS、塔防类游戏中尤为明显。…...

从“画箭头”到1亿播放量:机械工程师梁乐平,如何用CAD绘图书写知识传播新篇章?

一、绘图的开始和许多人一样&#xff0c;梁乐平选择了机械类专业&#xff0c;从广东理工学院毕业后&#xff0c;一头扎进了机械设计与绘图的世界。与别人不同的是&#xff0c;他给自己取了一个颇有传统文人气息的字“金泓”。这个细节&#xff0c;隐约透露着他性格中那份既务实…...

函数指针调用的两种语法及其在嵌入式C中的应用

1. 函数指针调用&#xff1a;两种语法背后的故事在嵌入式C开发中&#xff0c;函数指针是实现回调机制、插件架构和动态行为的关键技术。最近有工程师发现&#xff0c;通过函数指针调用函数时存在两种看似不同的语法形式&#xff1a;(*ptr)(); // 传统间接调用语法 ptr(); …...

信息安全工程师-大数据安全核心知识点与备考指南-终章

一、引言大数据是指具备 4V 核心特性的大规模数据集合&#xff0c;其安全是软考信息安全工程师考试中网络安全与应用安全领域的新兴核心考点&#xff0c;在近年考试中分值占比逐年提升至 8%-12%。大数据技术的发展历经三个里程碑阶段&#xff1a;2006 年 Hadoop 框架发布标志着…...

黑白电视的“单眼魔法“:揭秘那个只用亮度讲故事的奇妙世界

一、一个让我"开窍"的雪天故事 我记得小时候有一年冬天&#xff0c;老家下了一场特别大的雪。早晨拉开窗帘的瞬间&#xff0c;我整个人都呆住了——外面的世界变成了一片纯白&#xff0c;屋顶、树枝、田野、远山&#xff0c;全都被雪覆盖。所有的颜色都消失了&#x…...

微信M4A文件打不开怎么办?m4a转MP3只需一招,小白也能操作

很多人会遇到这种情况&#xff1a;别人通过微信发来一段录音、会议音频、课程音频或者采访素材&#xff0c;文件后缀是.m4a&#xff0c;在微信里可能能播放&#xff0c;但保存到手机本地、发到电脑、导入剪辑软件或者复制到U盘后&#xff0c;就可能出现打不开、无法识别、格式不…...

Nodejs后端服务集成Taotoken多模型API的实践路径

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Nodejs后端服务集成Taotoken多模型API的实践路径 对于Node.js后端开发者而言&#xff0c;将大模型能力集成到现有应用中是常见的需…...

ChatGPT多语言支持突然变差?紧急预警:OpenAI 2024 Q2模型更新已悄然降级8种低资源语言推理一致性

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;ChatGPT多语言支持评测 ChatGPT 在全球范围内的实际部署中&#xff0c;多语言能力直接影响其可用性与本地化体验。本章基于 OpenAI 官方 API&#xff08;gpt-3.5-turbo 和 gpt-4-turbo&#xff09;的实测数据…...