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 ANIMATE

using 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 ANIMATE

using 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 ANIMATE

using 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Apache Doris (六十四): Flink Doris Connector - (1)-源码编译

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. Flink与Doris版本兼容

【大数据】Flink 详解(八):SQL 篇 Ⅰ

《Flink 详解》系列&#xff08;已完结&#xff09;&#xff0c;共包含以下 10 10 10 篇文章&#xff1a; 【大数据】Flink 详解&#xff08;一&#xff09;&#xff1a;基础篇【大数据】Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅰ【大数据】Flink 详解&…

基于Java+SSM+MYSQL的助农特色农产品销售系统详细设计和实现【附源码】

基于JavaSSM助农特色农产品销售系统详细设计和实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定…

笔试面试题——继承和多态

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、什么是多态&#xff1f;二、什么是重载、重写(覆盖)、重定义(隐藏)&#xff1f;三、 inli…

使用 Python 创造你自己的计算机游戏(游戏编程快速上手)第四版:第十九章到第二十一章

十九、碰撞检测 原文&#xff1a;inventwithpython.com/invent4thed/chapter19.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 碰撞检测涉及确定屏幕上的两个物体何时相互接触&#xff08;即发生碰撞&#xff09;。碰撞检测对于游戏非常有用。例如&#xff0c;如…

《动手学深度学习》学习笔记 第9章 现代循环神经网络

本系列为《动手学深度学习》学习笔记 书籍链接&#xff1a;动手学深度学习 笔记是从第四章开始&#xff0c;前面三章为基础知识&#xff0c;有需要的可以自己去看看 关于本系列笔记&#xff1a; 书里为了让读者更好的理解&#xff0c;有大篇幅的描述性的文字&#xff0c;内容很…

成功 BOM 流程的五个基本要素

您应该以确保 BOM 流程的方式实现和启用它们&#xff1a; 准确的 当前的 完全的 清除 可行的 追求准确性 为下游提供准确数据 制造商使用其 BOM 来通知下游操作他们需要执行什么。不言而喻&#xff0c;向其他团队和员工提供准确的信息至关重要&#xff1b;否则&…

transbigdata笔记:栅格参数优化

在transbigdata中&#xff0c;栅格参数有如下几个 params(lonStart,latStart,deltaLon,deltaLat,theta) 如何选择合适的栅格参数是很重要的事情&#xff0c;这会对最终的分析结果产生很大的影响。 怎么选择参数&#xff0c;和数据以及分析的目的息息相关&#xff0c;transbi…

25考研英语复习计划

Hello各位小伙伴大家好&#xff0c;今天要给大家分享的是英语备考计划&#xff0c;大家可以作为参考&#xff0c;制定适合自己的备考计划。 【英一/二】 英语分为英一、英二&#xff0c;一般学硕英一&#xff0c;专硕英二。 英一要比英二难度大。 【复习计划】 1-2月&#xf…

383. 观光(dp思想运用,Dijkstra)

383. 观光 - AcWing题库 “您的个人假期”旅行社组织了一次比荷卢经济联盟的巴士之旅。 比荷卢经济联盟有很多公交线路。 每天公共汽车都会从一座城市开往另一座城市。 沿途汽车可能会在一些城市&#xff08;零或更多&#xff09;停靠。 旅行社计划旅途从 S 城市出发&…

1.C语言基础知识

这里写目录标题 1.第一个C语言程序2.注释3.标识符4.关键字5.数据类型6.变量7.常量8.运算符9.输入输出输入输出 1.第一个C语言程序 C语言的编程框架 #include <stdio.h> int main() {/* 我的第一个 C 程序 */printf("Hello, World! \n");return 0; }2.注释 单行…

信管网2023年上半年信息系统项目管理师论文真题

链接 信息系统项目管理师真题题库 - 信管网 上午综合知识、下午案例分析和下午论文三部分 可以单个试题查看 可以在线考试 在线考试又分&#xff1a;考试模式、练习模式和机考模式

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(6)解散部门

指路&#xff08;1&#xff09;&#xff08;2&#xff09;&#xff08;3&#xff09;&#xff08;4&#xff09;&#xff08;5&#xff09;&#x1f447; 黑马程序员JavaWeb开发|案例&#xff1a;tlias智能学习辅助系统&#xff08;1&#xff09;准备工作、部门管理_tlias智能…

【Qt】Qt配置

需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云<--/-->阿里云<--/-->华为云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 一、Qt SDK下载 二、配置环境变量 三、新建工程(QWidget) 四、QWidg…

今年第一个互联网医疗IPO,健康之路靠医药零售“再上一层楼”?

提起互联网医疗&#xff0c;大家最先想到的或许是阿里健康、京东健康、丁香医生等“名号响亮”的公司。事实上&#xff0c;健康之路开辟互联网医疗之路的时间比这些巨头们更早。据悉&#xff0c;2001年&#xff0c;健康之路就将互联网和医院资源结合&#xff0c;是第一批开展线…

Halcon基于灰度值的模板匹配

Halcon基于灰度值的模板匹配 基于灰度值的模板匹配是最经典的模板匹配算法&#xff0c;也是最早提出来的模板匹配算法。这种算法的根本思想是&#xff0c;计算模板图像与检测图像之间的像素灰度差值的绝对值总和&#xff08;SAD方法&#xff09;或者平方差总和&#xff08;SSD…

【C语言基础考研向】04整型进制转换

整型常量的不同进制表示 计算机中只能存储二进制数&#xff0c;即0和1&#xff0c;(而在对应的物理硬件上则是高、低电平。为了更方便地观察内存中的二进制数情况&#xff0c;除我们正常使用的十进制数外&#xff0c;计算机还提供了十六进制数和八进制数。 下面介绍不同进制数的…

【从0上手cornerstone3D】如何加载nifti格式的文件

在线演示 支持加载的文件格式 .nii .nii.gz 代码实现 npm install cornerstonejs/nifti-volume-loader// ------------- 核心代码 Start------------------- // 注册一个nifti格式的加载器 volumeLoader.registerVolumeLoader("nifti",cornerstoneNiftiImageVolu…

集合框架(二)

List集合 特点、特有方法 List集合因为支持索引&#xff0c;所以多了很多于索引相关的方法&#xff0c;当然&#xff0c;Collection的功能List也都继承了。 方法名称说明void add&#xff08;int index&#xff0c;E element&#xff09;在此集合中的指定位置插入指定的元素…

HTML---Jquery选择器

文章目录 目录 文章目录 本章目标 一.Jquery选择器概述 二.Jquery选择器分类 基本选择器 层次选择器 属性选择器 三.基本过滤选择器 练习 本章目标 会使用基本选择器获取元素会使用层次选择器获取元素会使用属性选择器获取元素会使用过滤选择器获取元素 …