当前位置: 首页 > 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 这里…...

图灵奖得主杨立昆公开“手撕”Meta 内部环境:“LLM 吸光了房间里的空气”,物理世界才是 AGI 的终局

来源&#xff1a;AI 科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;编译&#xff1a;王启隆Sora 死后&#xff0c;生成式视频路线已到头。2026 年 3 月&#xff0c;在新德里的 AI Alliance Global Leadership Reception 上&#xff0c;Christopher Nguyen 邀请到杨…...

OmX与边缘计算:打造高效边缘设备的AI助手完整指南

OmX与边缘计算&#xff1a;打造高效边缘设备的AI助手完整指南 【免费下载链接】oh-my-codex OmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more. 项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex OmX&#x…...

Pexpect异常处理完全手册:EOF、TIMEOUT等错误的解决之道

Pexpect异常处理完全手册&#xff1a;EOF、TIMEOUT等错误的解决之道 【免费下载链接】pexpect A Python module for controlling interactive programs in a pseudo-terminal 项目地址: https://gitcode.com/gh_mirrors/pe/pexpect Pexpect是一个功能强大的Python模块&a…...

OpenClaw多模型切换:Qwen3.5-9B-AWQ-4bit与文本模型协同工作

OpenClaw多模型切换&#xff1a;Qwen3.5-9B-AWQ-4bit与文本模型协同工作 1. 为什么需要多模型协同 去年我在尝试用OpenClaw自动化处理工作文档时&#xff0c;发现一个尴尬的问题&#xff1a;当我需要同时处理图片和文本内容时&#xff0c;要么被迫用昂贵的多模态模型处理所有…...

红外遥控技术原理与工程实践

1. 红外遥控技术基础解析 红外遥控技术自20世纪80年代开始普及&#xff0c;如今已成为家电控制领域最成熟可靠的解决方案之一。作为一名电子工程师&#xff0c;我在多个智能家居项目中都深度应用过红外控制模块。红外技术的核心优势在于其简单可靠的物理层实现和标准化的通信协…...

创意随笔:智能转录便携终端

创意随笔&#xff5c;智能转录便携终端 项目构想 核心亮点 以独立麦克风拾音为核心入口&#xff0c;实现全链路闭环实时翻译 从收音、ASR 识别、翻译、TTS 合成到语音播放/耳机输出&#xff0c;全程不依赖手机或电脑算力&#xff0c;自成一套完整翻译系统&#xff0c;真正做到端…...

折腾光纤模型的手记

comsol仿真-W型光子晶体光纤色散与损耗分析效果展示最近在实验室被导师催着搞光子晶体光纤的仿真&#xff0c;W型结构这种带双包层设计的玩意儿确实有点意思。作为COMSOL萌新&#xff0c;边啃说明书边试错&#xff0c;折腾一周终于把色散曲线和损耗谱给整明白了。先说建模这个重…...

BD663474车载LCD驱动芯片技术解析与CARIAD集成实践

1. BD663474驱动芯片技术解析&#xff1a;面向CARIAD车载显示系统的TFT-LCD底层控制实现BD663474是ROHM半导体推出的一款专为汽车级TFT-LCD面板设计的源极驱动&#xff08;Source Driver&#xff09;与栅极驱动&#xff08;Gate Driver&#xff09;集成控制器&#xff0c;广泛应…...

如何从视频中高效提取幻灯片:智能工具应用指南

如何从视频中高效提取幻灯片&#xff1a;智能工具应用指南 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 你是否曾遇到这样的困扰&#xff1a;参加线上会议后想整理演示文稿&#x…...

Kafka消费者组性能调优实战:从瓶颈识别到极致优化

前言“Kafka性能调优&#xff0c;20%是调整配置&#xff0c;80%是理解你的工作负载。”这是无数生产环境事故总结出来的血泪教训。在生产实践中&#xff0c;很多团队遇到消费性能问题时&#xff0c;第一反应是“加机器、加分区、调参数”&#xff0c;结果往往事倍功半&#xff…...