C#,人工智能,机器人,路径规划,A*(AStar Algorithm)算法、源代码及计算数据可视化

Peter Hart 

Nils Nilsson 

Bertram Raphael 

参考:

C#,人工智能(AI)机器人路径规划(Path Planning)的ARA*(Anytime Replanning A* Algorithm)算法与源程序icon-default.png?t=N7T8https://blog.csdn.net/beijinghorn/article/details/125464754

一、A*算法概述

A*算法最初由斯坦福研究院(Stanford Institute)的 Peter Hart,Nils Nilsson,Bertram Raphael 发表于1968年,属于Dijkstra算法的拓展之一。

论文原文icon-default.png?t=N7T8https://www.cs.auckland.ac.nz/courses/compsci709s2c/resources/Mike.d/astarNilsson.pdf

A*算法是常用的路径规划、最短路径搜索、图遍历算法。

借助於启发函数,A*同时拥有较好的性能与准确度,因而备受人工智能、机器人研究者们的欢迎。

除了 A* ,现在发展了 D*,D*Lite。。。诸多改进的算法,后续都会给出 C# 源代码。

A* 的算法不复杂,属于入门级别的。

二、计算结果的动画演示

三、A* 源代码

1、节点信息 NodeInfo

#define ANIMATEusing System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;namespace Legalsoft.Truffer.Algorithm
{/// <summary>/// 节点信息/// </summary>public class NodeInfo{/// <summary>/// 前一节点/// </summary>public NodeInfo Last { get; set; } = null;/// <summary>/// 邻接距离(权值)/// </summary>public int ManhattanWeight { get; set; } = 0;/// <summary>/// 曼哈顿距离(权值)/// </summary>public int RemoteWeight { get; set; } = 0;/// <summary>/// 综合距离(权值)/// </summary>public int TotalWeight { get; set; } = 0;/// <summary>/// 行号/// </summary>public int Column { get; set; } = 0;/// <summary>/// 列号/// </summary>public int Row { get; set; } = 0;/// <summary>/// 是否为墙(节点)?/// </summary>public bool IsWall { get; set; } = false;/// <summary>/// 是否被加入到了close中/// </summary>public bool InClose { get; set; } = false;/// <summary>/// 开口节点?/// </summary>public bool InOpen { get; set; } = false;/// <summary>/// 路过?/// </summary>public bool Visited { get; set; } = false;/// <summary>/// 构造函数/// </summary>/// <param name="y">行号</param>/// <param name="x">列号</param>/// <param name="iswall"></param>public NodeInfo(int y, int x, bool iswall){Row = y;Column = x;IsWall = iswall;}}
}

2、地图信息MapInfo

#define ANIMATEusing System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;namespace Legalsoft.Truffer.Algorithm
{/// <summary>/// 地图信息(墙1与空0)/// </summary>public class MapInfo{/// <summary>/// 行数/// </summary>public int Row { get; set; } = 0;/// <summary>/// 列数/// </summary>public int Column { get; set; } = 0;/// <summary>/// 所有节点/// </summary>public NodeInfo[,] Nodes { get; set; } = null;/// <summary>/// 从文本创建地图/// </summary>/// <param name="buf"></param>public void FromBuffer(string buf){buf = buf.Replace("\r", "").Trim();string[] xlines = buf.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);Nodes = new NodeInfo[xlines.Length, xlines[0].Trim().Length];Row = Nodes.GetLength(0);Column = Nodes.GetLength(1);int y = 0;foreach (string xu in xlines){for (int x = 0; x < xu.Trim().Length; x++){NodeInfo node = new NodeInfo(y, x, Int32.Parse(xu.Trim().Substring(x, 1)) > 0);Nodes[y, x] = node;}y++;}}/// <summary>/// 从文件创建地图/// </summary>/// <param name="filename"></param>/// <exception cref="Exception"></exception>public void FromFile(string filename){try{string buf = File.ReadAllText(filename);FromBuffer(buf);}catch (Exception ex){throw new Exception("");}}/// <summary>/// this重载/// </summary>/// <param name="y"></param>/// <param name="x"></param>/// <returns></returns>public NodeInfo this[int y, int x]{set { Nodes[y, x] = value; }get { return Nodes[y, x]; }}/// <summary>/// 第一个节点/// </summary>public NodeInfo First{get { return Nodes[0, 0]; }}/// <summary>/// 最后一个节点/// </summary>public NodeInfo Last{get { return Nodes[Row - 1, Column - 1]; }}/// <summary>/// 清除路径/// </summary>public void ClearPath(){for (int i = 0; i < Row; i++){for (int j = 0; j < Column; j++){this[i, j].Visited = false;}}}}
}

3、核心代码 AStar Kernal

#define ANIMATEusing System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;namespace Legalsoft.Truffer.Algorithm
{public class AStar{/// <summary>/// 开放列表/// </summary>private List<NodeInfo> openList { get; set; } = new List<NodeInfo>();/// <summary>/// 当前访问的节点/// </summary>private NodeInfo curNode { get; set; } = null;/// <summary>/// 起始节点/// </summary>private NodeInfo startNode { get; set; } = null;/// <summary>/// 终止节点/// </summary>private NodeInfo endNode { get; set; } = null;/// <summary>/// 地图/// </summary>public MapInfo map { get; set; } = new MapInfo();/// <summary>/// 构造函数/// </summary>public AStar(){}/// <summary>/// 节点加入列表,并计算相关权值/// </summary>/// <param name="node"></param>private void AddToList(NodeInfo node){if (node.IsWall) return;if (node.InClose) return;if (node.InOpen) return;openList.Add(node);node.InOpen = true;node.ManhattanWeight = curNode.ManhattanWeight + WeightOf(node, curNode);node.RemoteWeight = WeightOf(node, endNode);node.TotalWeight = node.ManhattanWeight + node.RemoteWeight;node.Last = curNode;}/// <summary>/// 路径规划A*算法(最短路径A*算法)/// 默认左上角(0,0)为起点;右下角为终点;/// </summary>/// <param name="start">起点</param>/// <param name="end">终点</param>public void Tracing(NodeInfo start = null, NodeInfo end = null){List<int[]> steps = new List<int[]>() {new int[2] {  1, 1 },new int[2] {  0, 1 },new int[2] {  1, 0 },new int[2] {  0,-1 },new int[2] { -1, 0 },new int[2] {  1,-1 },new int[2] { -1, 1 },new int[2] { -1,-1 },};startNode = (start == null) ? map.First : start;endNode = (end == null) ? map.Last : end;// 将起点加入到开放列表中openList.Add(startNode);while (true){openList.Sort(SortByCost);curNode = openList[0];openList.Remove(curNode);curNode.InOpen = false;curNode.InClose = true;// 终点?if (curNode == endNode){return;}MarkPath();map.ClearPath();}}/// <summary>/// 节点1到节点2的Weight/// </summary>/// <param name="a">节点1</param>/// <param name="b">节点2</param>/// <returns></returns>private int WeightOf(NodeInfo a, NodeInfo b){// 直行步长double straightDistance = 1.0;// 斜行步长double diagonalDistance = 1.414;int deltaX = Math.Abs(a.Column - b.Column);int deltaY = Math.Abs(a.Row - b.Row);if (deltaX == deltaY){return (int)(deltaX * diagonalDistance);}else if (deltaX < deltaY){return (int)(deltaX * diagonalDistance + (deltaY - deltaX) * straightDistance);}else{return (int)(deltaY * diagonalDistance + (deltaX - deltaY) * straightDistance);}}/// <summary>/// 排序的委托函数/// </summary>/// <param name="a">节点1</param>/// <param name="b">节点2</param>/// <returns></returns>private int SortByCost(NodeInfo a, NodeInfo b){if (a.TotalWeight.CompareTo(b.TotalWeight) != 0){return (a.TotalWeight.CompareTo(b.TotalWeight));}else if (a.RemoteWeight.CompareTo(b.RemoteWeight) != 0){return (a.RemoteWeight.CompareTo(b.RemoteWeight));}else{return 1;}}/// <summary>/// 标记当前获取的路径/// </summary>public void MarkPath(){NodeInfo cd = curNode;while (cd != null){if (cd == startNode){break;}cd.Visited = true;cd = cd.Last;}}}
}

--------------------------------------------------------------------------------

POWER BY TRUFFER.CN

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【vscode】6、调试 shell

文章目录 经常在 IDE 下使用 高级语言后&#xff0c;往往并不习惯 shell 编程&#xff0c;因为没有酷炫的界面。但现在 vscode 可以很方便的调试 shell 脚本。 配置方法如下&#xff1a; vscode 下载 Bash Debug 插件 mac 升级 bash 版本&#xff08;因为此 vscode 插件需要 b…

Javaweb之SpringBootWeb案例分页插件的详细解析

3.1.2 分页插件 3.1.2.1 介绍 前面我们已经完了基础的分页查询&#xff0c;大家会发现&#xff1a;分页查询功能编写起来比较繁琐。 在Mapper接口中定义两个方法执行两条不同的SQL语句&#xff1a; 查询总记录数 指定页码的数据列表 在Service当中&#xff0c;调用Mapper接…

unity 2021 发布安卓版本,谷歌限流国内,报错CommandInvokationFailure: Gradle build failed

在使用 Unity 2022 打包安卓项目时&#xff0c;遇到 gradle 无法访问或下载超级慢最终超时出错的问题解决 解决方案&#xff1a; 1. 在 Build Settings 左下角打开 Player Settings&#xff0c;在 Android 平台图标选项卡下找到 Publishing Settings 区域 勾选 2. 从国内…

修改iview的表格table展开的默认icon和样式

修改前 修改后 修改内容 .title_label_list .ivu-icon-ios-add{font-size: 26px;color: #888888; } .title_label_list .ivu-icon-ios-add:hover{color: #11AAAA; } .title_label_list .ivu-icon-ios-add:before {content: "\F341"; } .title_label_list .ivu-icon-…

1.17 day4 IO网络编程

用udp实现tftp下载和上传功能 #include <myhead.h> #define PORT 69 #define IP "192.168.122.24" int shangchuan(int sfd,struct sockaddr_in sin,socklen_t socklen) {int cfd-1;if((cfdopen("./01udpk.c",O_RDONLY))-1){perror("open erro…

安卓手机变iOS!

Launcher iOS 16 - 安卓手机秒变iOS Launcher iOS 16 是一款iOS启动器&#xff0c;可以将安卓手机桌面变成iOS样子&#xff0c;还有iOS的开机动画和景深效果&#xff01; 下载链接&#xff1a;【Launcher iOS 16】 ​

css保留格式文本换行

也可以用富文本保留文本格式 恰逢场景需要且能使代码简洁故用css实现 white-space:xxx; white-space: pre-line; 连续的空白符会被合并。在遇到换行符或者<br>元素&#xff0c;或者需要为了填充「行框盒子(line boxes)」时会换行。 white-space: pre; 连续的空白符会被…

【C++】入门C++前想要了解的小知识

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 目录 1. 前言2. 什么是C3. C的发展史4. C的重要性4.1 语言的使用广泛度4.2 在工作领域中4.3 在校招领域中 5. 如何学习C5.1 看看别人怎么学习的5.2 自己怎么学 1. 前言 今天开…

嵌入式软件面试之程序在存储器中的分布

Hi, 大家好&#xff0c;今天阿目分享的是一个嵌入式软件面试的常见问题&#xff0c;内存分布或者说程序在内存中的布局&#xff0c;我们写的程序是按照怎么的准则放在内存中的&#xff1f; 一般有操作系统的嵌入式设备&#xff0c;都会有一个Bootloader, 它负责在上电后初始化…

k8s之对外服务ingress

一、service 1、service作用 ①集群内部&#xff1a;不断跟踪pod的变化&#xff0c;不断更新endpoint中的pod对象&#xff0c;基于pod的IP地址不断变化的一种服务发现机制&#xff08;endpoint存储最终对外提供服务的IP地址和端口&#xff09; ②集群外部&#xff1a;类似负…

【Java数据结构】03-二叉树,树和森林

4 二叉树、树和森林 重点章节&#xff0c;在选择&#xff0c;填空&#xff0c;综合中都有考察到。 4.1 掌握二叉树、树和森林的定义以及它们之间的异同点 1. 二叉树&#xff08;Binary Tree&#xff09; 定义&#xff1a; 二叉树是一种特殊的树结构&#xff0c;其中每个节点…

【Filament】材质系统

1 前言 本文主要介绍 Filament 的材质系统&#xff0c;官方介绍详见 → Filament Materials Guide。材质系统中会涉及到一些空间和变换的知识点&#xff0c;可以参考&#xff1a;【Unity3D】空间和变换、【Unity3D】Shader常量、变量、结构体、函数、【OpenGL ES】MVP矩阵变换、…