【Java】A *算法的应用

代码和测试图片下载地址:

https://download.csdn.net/download/r77683962/90089371

这个地图里黑色部分是不能通过的,白色部分是可以通过的,这个算法没问题,有点感觉效率不太高。。。。。

效果:

源代码PathFind.java(代码其实来源于网上,出处找不到了。。。不好意思)
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.logging.Logger;class Coord
{public int x;public int y;public Coord(int x, int y){this.x = x;this.y = y;}@Overridepublic boolean equals(Object obj){if (obj == null) return false;if (obj instanceof Coord){Coord c = (Coord) obj;return x == c.x && y == c.y;}return false;}
}class Node implements Comparable<Node>
{public Coord coord; // 坐标public Node parent; // 父结点public int G; // G:是个准确的值,是起点到当前结点的代价public int H; // H:是个估值,当前结点到目的结点的估计代价public Node(int x, int y){this.coord = new Coord(x, y);}public Node(Coord coord, Node parent, int g, int h){this.coord = coord;this.parent = parent;G = g;H = h;}@Overridepublic int compareTo(Node o){if (o == null) return -1;if (G + H > o.G + o.H)return 1;else if (G + H < o.G + o.H) return -1;return 0;}
}class MapInfo
{public int[][] maps; // 二维数组的地图public int width; // 地图的宽public int height; // 地图的高public Node start; // 起始结点public Node end; // 最终结点public MapInfo(int[][] maps, int width, int height, Node start, Node end){this.maps = maps;this.width = width;this.height = height;this.start = start;this.end = end;}
}public class PathFind extends JFrame {public final static int BAR = 1; // 障碍值public final static int PATH = 2; // 路径public final static int DIRECT_VALUE = 10; // 横竖移动代价public final static int OBLIQUE_VALUE = 14; // 斜移动代价Queue<Node> openList = new PriorityQueue<Node>(); // 优先队列(升序)List<Node> closeList = new ArrayList<Node>();Graphics graphics;static public BufferedImage bufferedImage;int startx;int starty ;int endx ;int endy ;// for input start and end pointint mouseinput;//for pathFindStartint step = 5;// for addNeighborNodeInOpenint increment = 5;Color drawFoundPathColor = new Color(255,0,0);Color drawLineColor = new Color(0,0,255);Color drawFindingColor = new Color(0,255,0);int size = 5;int width;int height;int[][] data;private Image buffer;  // 双缓冲图像private Graphics bufferGraphics;  // 双缓冲图像的绘图上下文static int neihborsCount = 0;static int neihborsCount2 = 0;//打印日志工具,可以看到打印时当前类,方法,行,比便方便,sout不能看到这些信息不太方便Logger logger = MyLogger.getLogger();PathFind(){try {//5984 x 4452bufferedImage = ImageIO.read(new File("src/Map_zoom_out_5.jpg"));} catch (IOException e) {throw new RuntimeException(e);}width = bufferedImage.getWidth();height = bufferedImage.getHeight();// 设置尺寸setSize(width, height);// 窗口居中setLocationRelativeTo(null);// 关闭事件setDefaultCloseOperation(3);// 用户不能调整窗口大小setResizable(true);// 标题setTitle("A Star");// 窗口可见setVisible(true);graphics = getGraphics();buffer = createImage(bufferedImage.getWidth(), bufferedImage.getHeight());bufferGraphics = buffer.getGraphics();data = new int[height][width];resetBuffer();//zoom();addMouseListener(new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {logger.info(e.getX() + ", " + e.getY());if (mouseinput == 0){resetBuffer();startx = e.getX();starty = e.getY();bufferGraphics.setColor(new Color(0, 255, 0));bufferGraphics.fillRect(startx, starty, size, size);graphics.drawImage(buffer, 0, 0, width, height, null);mouseinput = 1;}else{mouseinput = 0;endx = e.getX();endy = e.getY();bufferGraphics.setColor(new Color(0, 255, 0));bufferGraphics.fillRect(startx, starty, size, size);bufferGraphics.fillRect(endx, endy, size, size);bufferGraphics.setColor(drawLineColor);bufferGraphics.drawLine(startx, starty, endx, endy);logger.info("start: " + data[starty][startx] + ", end: " + data[endy][endx]);graphics.drawImage(buffer, 0, 0, width, height, null);if (data[starty][startx] == 1 || data[endy][endx] == 1){//logger.info("data == 1");return;}for (int i = 0; i < height; i++) {StringBuilder s1 = new StringBuilder();for (int j = 0; j < width; j++) {s1.append(data[i][j]);}// logger.info(s.toString());}increment = 5;System.out.println("width: " + width + " height: " + height);// start find pathpathFindStart(new MapInfo(data, width, height, new Node(startx / step * step,starty / step * step),new Node(endx / step * step,endy / step * step)));startx = 0;starty = 0;endx = 0;endy = 0;}}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}});bufferGraphics.drawImage(bufferedImage,0,0,null);//1831 x 840//startx = 400;//starty = 400;//endx = 1400;//endy = 700;}void resetBuffer(){StringBuilder s = new StringBuilder();for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {s = new StringBuilder();final int rgb = bufferedImage.getRGB(j, i);//logger.info(" == " + rgb);//logger.info(i + " " + j + " " + data[i][j]);if (rgb == -1)  //不能走的区域{data[i][j] = 0;bufferGraphics.setColor(new Color(255, 255, 255));}else //可以走的区域{//logger.info("== -16777216");data[i][j] = 1;bufferGraphics.setColor(new Color(0, 0, 0));}bufferGraphics.drawLine(j, i, j, i);}}graphics.drawImage(buffer, 0, 0, width, height, null);}// zoom outvoid zoom(){logger.info("zoom");int zoomOutTimes = 5;BufferedImage bufferedImage1 = new BufferedImage(width / zoomOutTimes + 1, height / zoomOutTimes + 1, java.awt.image.BufferedImage.TYPE_INT_RGB);int i, j;for (i = 0; i < height / zoomOutTimes ; i++){for (j = 0; j < width / zoomOutTimes; j++){int temp = 0;for (int k = 0; k < zoomOutTimes; k++) {for (int l = 0; l < zoomOutTimes; l++) {if (i * zoomOutTimes + k > height || j * zoomOutTimes + l > width){continue;}temp += data[i * zoomOutTimes + k][j * zoomOutTimes + l];}}//logger.info(String.valueOf(temp));if (temp > 20){bufferedImage1.setRGB(j,i,0);}else{bufferedImage1.setRGB(j,i,0xffffff);}}//bufferGraphics2.drawLine(j, i, j, i);}//graphics.drawImage(buffer2, 0, 0, windowWidth, windowHeight, null);try {//5984 x 4452final boolean write = ImageIO.write(bufferedImage1, "jpg", new File("img/Map_zoom_out_" + zoomOutTimes+ ".jpg"));logger.info(String.valueOf(write));} catch (IOException e) {throw new RuntimeException(e);}logger.info("String.valueOf(write)");}@Overridepublic void repaint(long time, int x, int y, int width, int height) {super.repaint(time, x, y, width, height);graphics.drawImage(buffer, 0, 0, width, height + 200, null);}/*** 判断结点是否是最终结点*/private boolean isEndNode(Coord end,Coord coord){return coord != null && end.equals(coord);}/*** 判断结点能否放入Open列表*/private boolean canAddNodeToOpen(MapInfo mapInfo,int x, int y){// 是否在地图中if (x < 0 || x >= mapInfo.width || y < 0 || y >= mapInfo.height)return false;//logger.info("canAddNodeToOpen: " + x + ", " + y + ": " + mapInfo.maps[y][x]);// 判断是否是不可通过的结点if (mapInfo.maps[y][x] == 1) return false;// 判断结点是否存在close表if (isCoordInClose(x, y)) return false;return true;}/*** 判断坐标是否在close表中*/private boolean isCoordInClose(Coord coord){return coord!=null&&isCoordInClose(coord.x, coord.y);}/*** 判断坐标是否在close表中*/private boolean isCoordInClose(int x, int y){if (closeList.isEmpty())return false;for (Node node : closeList){if (node.coord.x == x && node.coord.y == y){return true;}}return false;}private int calcH(Coord end,Coord coord){return Math.abs(end.x - coord.x) + Math.abs(end.y - coord.y);}private Node findNodeInOpen(Coord coord){//logger.info("");if (coord == null || openList.isEmpty()) return null;for (Node node : openList){if (node.coord.equals(coord)){return node;}}return null;}/*** 添加所有邻结点到open表*/private void addNeighborNodeInOpen(MapInfo mapInfo,Node current){int x = current.coord.x;int y = current.coord.y;bufferGraphics.setColor(drawFindingColor);bufferGraphics.drawLine(x, y, x+3, y+3);//logger.info("x: " + x + " y: " + y);graphics.drawImage(buffer, 0, 0, width, height, null);//logger.info("addNeighborNodeInOpen: " + x + ", " + y + ": " + mapInfo.maps[y][x]);// 左addNeighborNodeInOpen(mapInfo,current, x - increment, y, DIRECT_VALUE);// 上addNeighborNodeInOpen(mapInfo,current, x, y - increment, DIRECT_VALUE);// 右addNeighborNodeInOpen(mapInfo,current, x + increment, y, DIRECT_VALUE);// 下addNeighborNodeInOpen(mapInfo,current, x, y + increment, DIRECT_VALUE);// 左上addNeighborNodeInOpen(mapInfo,current, x - increment, y - increment, OBLIQUE_VALUE);// 右上addNeighborNodeInOpen(mapInfo,current, x + increment, y - increment, OBLIQUE_VALUE);// 右下addNeighborNodeInOpen(mapInfo,current, x + increment, y + increment, OBLIQUE_VALUE);// 左下addNeighborNodeInOpen(mapInfo,current, x - increment, y + increment, OBLIQUE_VALUE);}/*** 添加一个邻结点到open表*/private void addNeighborNodeInOpen(MapInfo mapInfo,Node current, int x, int y, int value){neihborsCount2++;//logger.info("addNeighborNodeInOpen: " + x + ", " + y);if (canAddNodeToOpen(mapInfo, x, y)){neihborsCount++;//logger.info("neihborsCount2: " + neihborsCount2 + "neihborsCount: " + neihborsCount);Node end=mapInfo.end;Coord coord = new Coord(x, y);int G = current.G + value; // 计算邻结点的G值Node child = findNodeInOpen(coord);if (child == null){int H=calcH(end.coord,coord); // 计算H值if(isEndNode(end.coord,coord)){child=end;child.parent=current;child.G=G;child.H=H;}else{child = new Node(coord, current, G, H);}openList.add(child);}else if (child.G > G){child.G = G;child.parent = current;// 重新调整堆openList.add(child);}}// logger.info("");}private void drawFoundPath(int[][] maps, Node end){if(end==null||maps==null) return;// logger.info("总代价:" + end.G);while (end != null){Coord c = end.coord;maps[c.y][c.x] = PATH;//logger.info(end.coord.x + " " + end.coord.y);int x = c.x;int y = c.y;bufferGraphics.setColor(drawFoundPathColor);bufferGraphics.fillRect(x, y, 3, 3);graphics.drawImage(buffer, 0, 0, width, height, null);end = end.parent;}}public void pathFindStart(MapInfo mapInfo){if(mapInfo == null){return;}// cleanopenList.clear();closeList.clear();// 开始搜索openList.add(mapInfo.start);moveNodes(mapInfo);}/*** 移动当前结点*/private void moveNodes(MapInfo mapInfo){while (!openList.isEmpty()){//logger.info("while");Node current = openList.poll();closeList.add(current);addNeighborNodeInOpen(mapInfo,current);if (isCoordInClose(mapInfo.end.coord)) // bug修正{drawFoundPath(mapInfo.maps, mapInfo.end);break;}}}public static void main(String[] args) {new PathFind();}
}
MyLogger.java 
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.*;/*** 可以自已定义日志打印格式,这样看起来比较方便些**/
class MyFormatter extends Formatter
{@Overridepublic String format(LogRecord arg0){//创建StringBuilder对象来存放后续需要打印的日志内容StringBuilder builder = new StringBuilder();//获取时间SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");Date now = new Date();String dateStr = simpleDateFormat.format(now);builder.append("[");builder.append(dateStr);builder.append(" ");//拼接日志级别builder.append(arg0.getLevel()).append(" ");builder.append(arg0.getSourceClassName()).append(" ");//拼接方法名builder.append(arg0.getSourceMethodName()).append(" ");StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();String line = stackTrace[8].toString();String lineNumber = line.substring(line.indexOf(":") + 1, line.length() - 1);//拼接方法名builder.append(lineNumber).append("] ");//拼接日志内容builder.append(arg0.getMessage());//日志换行builder.append("\r\n");return builder.toString();}
}public class MyLogger {static Logger logger;static  {logger = Logger.getLogger(MyLogger.class.getName());logger.setUseParentHandlers(false);//如果需要将日志文件写到文件系统中,需要创建一个FileHandler对象Handler consoleHandler = new ConsoleHandler();//创建日志格式文件:本次采用自定义的FormatterconsoleHandler.setFormatter(new MyFormatter());//将FileHandler对象添加到Logger对象中logger.addHandler(consoleHandler);}public static Logger getLogger() {return logger;}public static void main(String[] args) throws SecurityException, IOException {//Logger logger = Logger.getLogger(MyLogger.class.toString());//logger.info("123");StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();System.out.println(stackTrace.length);for (StackTraceElement s: stackTrace) {System.out.println(s.toString());}/*Logger myLogger = MyLogger.getLogger();myLogger.info("1123");-----------------------------------
©著作权归作者所有:来自51CTO博客作者mob64ca12e86bd4的原创作品,请联系作者获取转载授权,否则将追究法律责任java logger打印错误行号https://blog.51cto.com/u_16213398/7623080myLogger.info("11");*/}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/35902.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

日本IT|企业需要什么样的技术?

日本IT企业所需的技术非常多样化&#xff0c;涵盖了多个领域和方面。以下是一些日本IT企业通常所需的主要技术&#xff1a; 一、编程语言与工具 编程语言&#xff1a;Java、Python、C、C#、PHP等是日本IT企业常用的编程语言。这些语言在软件开发、数据分析、网络应用等方面都…

刘铁猛C#入门 030 泛型,partial类,枚举,结构

泛型(generic)无处不在 为什么需要泛型&#xff1a;避免成员膨胀或者类型膨胀 正交性&#xff1a;泛型类型(类/接口/委托/......)泛型成员(属性/方法/字段/....类型方法的参数推断 泛型接口/类的 类型参数不只有一个泛型与委托、lambda表达式实现泛型接口类时 &#xff0c;实现…

视频加密的好处与加密方法分析2024

视频内容的多样化不止局限于电视、电影&#xff0c;在日常培训学习中也是必不可少的。那么对于做知识付费的人来说&#xff0c;视频内容的安全性就尤为重要。视频加密也就i随之兴起&#xff0c;为视频内容安全多了一层保障&#xff0c;那么主要体现下那几个方面呢&#xff1f;可…

鸿蒙UI开发——亮/暗色模式适配

1、概 述 系统存在深浅色两种显示模式&#xff0c;为了给用户更好的使用体验&#xff0c;应用最好适配暗色和亮色两种模式。从应用与系统配置关联的角度来看&#xff0c;适配暗色和亮色模式可以分为下面两种情况&#xff1a; 应用跟随系统的深浅色模式&#xff1b; 应用主动设…

三菱伺服JET产品线(选型说明)

伺服放大器功能提升 伺服放大器MELSERVO-JET系列为进一步优化了独家控制引擎的高性能伺服放大器。 可通过与支持CC-LinK IE TSN的运动控制器的同步通信,进行高 速、高精度的运动控制。 除了旋转型伺服电机以外,还支持线性伺服电机。MR-JET-G-N1支持EtherCAT。 旋转型伺服电机 …

HarmonyNext如何判断上下分屏

鸿蒙系统支持上下分屏&#xff0c;可以同时使用两个应用&#xff0c;比如&#xff1a; 有时候我们需要在分屏的时候处理相关逻辑&#xff0c;那到底该如何处理了&#xff0c; 首先在UIAbility下的onWindowStageCreate中进行监听 //监听窗口变化let windowClass: window.Window…

寄存器点灯

1.keil创建工程。&#xff08;不再概述&#xff09; 2.需要添加启动文件。所以添加库文件中的第二个。 3.启动顺序。上电后先初始化堆栈指针&#xff0c;再运行该汇编&#xff0c;最后跳入main函数&#xff0c;系统初始化是初始化时钟的&#xff0c;暂时不需要&#xff0c;屏蔽…

tomcat 运行加载机制解析

tomcat 运行加载机制 从tomcat jar包的加载顺序&#xff1a; tomcat的具体运行加载 可以从 start、setclasspath、catalina文件中看出来&#xff1a; start.bat执行 去找bin目录下的catalina.bat,catalina 或去找 bin\setenv.bat以获取标准环境变量&#xff0c;然后去找bin\…

OLED显示图片,文字

显示图片 1.这是随便一张的图片&#xff0c;自己可以随便截图一张 2.单击图片&#xff0c;右边选择编辑 3.如下操作 4.然后&#xff0c;这个水平和垂直的值的设置要根据你所使用的屏幕有多少个像素点&#xff0c;我当前使用的是0.96寸OLED屏幕&#xff0c;也就是12864&#x…

猿辅导持续布局AI赋能教育领域,助推教育行业数字化转型

近日&#xff0c;由人民网主办的“AI之夜”活动在北京隆重举行。“AI之夜”活动旨在展示中国在人工智能领域的最新成果和创新应用&#xff0c;推动行业的交流与合作。活动现场&#xff0c;来自不同领域的专家们通过主题演讲、圆桌讨论和案例分享等形式&#xff0c;全面呈现了中…

Zotero版本兼容问题,无法安装插件“%s”

1.问题&#xff1a;zotero-better-notes与zotero版本不兼容 安装插件zotero-better-notes时&#xff0c;出现插件安装失败提示&#xff1a;无法安装插件“%S"。他可能无法与该版本的Zotero兼容 zotero-better-notes&#xff1a;是一款论文阅读笔记插件&#xff0c;之前一…

Profinet IO从站数据 转 opc ua项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 准备工作 4 使用PRONETA软件获取PROFINET IO从站的配置信息 5 设置网关采集PROFINETIO从站设备数据 6 启动OPC UA协议转发采集的数据 7 选择槽号和数据地址 8 选择子槽号 9 案例总结 1 案例说明 设置网关采集ProfinetIO从站设…

android studio 读写文件操作(应用场景二)

android studio版本&#xff1a;2023.3.1 patch2 例程&#xff1a;readtextviewIDsaveandread 本例程是个过渡例程&#xff0c;如果单是实现下图的目的有更简单的方法&#xff0c;但这个方法是下一步工作的基础&#xff0c;所以一定要做。 例程功能&#xff1a;将两个textvi…

基于SSM框架企业人事管理系统的设计与实现

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 操作系统…

百度智能云 CHPC: 使用 BtuneAK对基因测序软件进行加速

背景 本文主要介绍在 CHPC 平台使用 BtuneAK 自动化加速组件&#xff0c;可以直接对BWA、FastQC、Picard、Trimmomatic等业务端到端时长加速。 Btune 简单介绍 BtunePK介绍 BtunePK 是百度自研的一款性能分析和调优工具&#xff0c;兼容Intel、AMD、ARM三个CPU平台&#xff0…

Power BI - 批量导入数据

1.简单介绍 假定已经使用Power Automate Desktop(微软的RPA产品&#xff0c;是Power Platform平台的其中一个产品)从福布斯中文网获取了各地区的2024年的财富数据如下&#xff0c; 现在想批量导入数据到Power BI中&#xff0c;分析一下各地区的产业以及财富情况 2.具体说明 …

实现跨平台 SSH 连接:从 macOS 到 Windows WSL 的完整解决方案20241203

&#x1f310; 实现跨平台 SSH 连接&#xff1a;从 macOS 到 Windows WSL 的完整解决方案 ✨ 引言 随着跨平台开发的普及&#xff0c;开发者经常需要在多系统环境中切换和协作。尤其是在 macOS 和 Windows 混合使用的开发环境中&#xff0c;通过 SSH 远程访问和管理 Windows …

【css】基础(二)

本专栏内容为&#xff1a;前端专栏 记录学习前端&#xff0c;分为若干个子专栏&#xff0c;html js css vue等 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;css专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &a…

2024通信工程师-中级-互联网技术备考经验

考试简介 全国通信专业技术人员职业水平考试&#xff0c;是由国家人力资源和社会保障部、工业和信息化部领导下的国家级考试。根据原人事部、信息产业部文件&#xff08;国人部发[2006]10号&#xff09;&#xff0c;通信专业技术人员职业水平评价&#xff0c;纳入全国专业技术人…

智能文档解析综述:结构化信息提取的技术、挑战与前景

综述论文&#xff1a;https://arxiv.org/abs/2410.21169 摘要 文档解析对于将非结构化和半结构化文档&#xff08;如合同、学术论文和发票&#xff09;转换为结构化、机器可读的数据至关重要。通过从非结构化输入中提取可靠的结构化数据&#xff0c;文档解析为众多应用提供了极…