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

news2024/11/24 19:27:10

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

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

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

相关文章

python的介绍,带入,安装

文章目录 一、python的起源二、为什么学python二、python的安装 一、python的起源 二、为什么学python 学习Python有许多好处&#xff1a; 易于学习&#xff1a;Python有一个非常直观易懂的语法&#xff0c;可以让新手更容易上手。 适用于很多领域&#xff1a;从web开发&#…

主流人工智能AI工具测评

主流人工智能AI工具测评 主流的人工智能AI工具ChatGPT ——OpenAI研发CHAT_BISON——Google研发Qwen通义千问 ——阿里云研发文心一言——百度研发 根据10个问题分析人工智能的回答女朋友生气了怎么哄千元机性价比推荐小米13 和 vivo iQOO 11s哪个好计算机专业毕业论文护士年终…

人为什么可以通过平面镜看到自己,不能通过墙壁反射看到自己?

问题描述&#xff1a;人为什么可以通过平面镜看到自己&#xff0c;不能通过墙壁反射看到自己&#xff1f; 问题解答&#xff1a; 这涉及光的反射和镜面反射的不同。平面镜是一种镜面反射的例子&#xff0c;它具有非常光滑的表面&#xff0c;能够使光线以相等且相反的角度反射…

Spring MVC学习之——RequestMapping注解

RequestMapping注解 作用 用于建立请求URL和处理请求方法之间的对应关系。 属性 value&#xff1a;指定请求的实际地址&#xff0c;可以是一个字符串或者一个字符串列表。 value可以不写&#xff0c;直接在括号中写&#xff0c;默认就是value值 RequestMapping(value“/hel…

stgcn下环境的配置:Windows miniconda python3.6 cuda11.8 cudnn8.9.2 torch4.9

配环境是个很玄学的事情&#xff0c;请一定按照顺序执行&#xff0c;本文档主要解决了的stgcn下环境的配置问题。 1.miniconda比较好安装&#xff0c;记得安装完了之后更改一下环境变量 参考&#xff1a;https://blog.csdn.net/Oxford1151/article/details/130326163 2.在终端…

我帮企业找市场|福田供应链企业走进佛山,刮起“两业融合”新旋风!

前言&#xff1a; 2023年以来&#xff0c;福田区锚定高质量发展首要任务&#xff0c;鼓实劲、出实招、求实效&#xff0c;继推出“万名干部助企行”“我帮企业找市场”“我帮企业找资金”等系列服务举措后&#xff0c;坚持系统、全面完善产业支持政策&#xff0c;打造产业发展最…

Unity3D代码混淆方案详解

背景 Unity引擎使用Mono运行时&#xff0c;而C#语言易受反编译影响&#xff0c;存在代码泄露风险。本文通过《QQ乐团》项目实践&#xff0c;提出一种适用于Unity引擎的代码混淆方案&#xff0c;以保护代码逻辑。 引言 在Unity引擎下&#xff0c;为了防止代码被轻易反编译&a…

定义公共样式css

index.less 文件 // 全局按钮颜色 btn_background: #005298; btn_border-color: #6fa18d;// 默认的 btn_border-color-highlight: #0598d3;// 高亮边框 btn_border-color-success: #36be7e;// 成功边框 btn_font_color: #fff;// 边框颜色 背景色 文字颜色 .btn_public(btn_bo…

什么是区块链?

区块链 区块链 &#xff08;英语&#xff1a;blockchain&#xff09;是借由 密码学 与 共识机制 等技术建立&#xff0c;存储数据的 保证不可篡改和不可伪造的 分布式技术。 什么是区块 区块 就是将一批数据打包在一起&#xff0c;并且给打包出来的区块编号。第一个区块的编…

【Qt】Qt配置

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

SpringBoot之拦截器与过滤器解读

目录 一、SpringBoot 拦截器 过滤器 二、实现HandleInterceptor接口 三、继承HandleInterceptorAdapter类 四、实现RequestInterceptor接口 五、粉丝福利 一、SpringBoot 拦截器 过滤器 1、过滤器和拦截器触发时机不一样&#xff0c;过滤器是在请求进入容器后&#xff0c;…

python系列28:fastapi部署应用

1. 介绍与安装 FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;类似flask&#xff0c;Django&#xff0c;webpy 在部署时可能需要用到下面的库&#xff1a; Uvicorn 或者 Hypercorn负责ASGI 服务器。 Starlette 负责 web 部分…

C语言从入门到实战——动态内存管理

动态内存管理 前言一、 为什么要有动态内存分配二、 malloc和free2.1 malloc2.2 free 三、calloc和realloc3.1 calloc3.2 realloc 四、常见的动态内存的错误4.1 对NULL指针的解引用操作4.2 对动态开辟空间的越界访问4.3 对非动态开辟内存使用free释放4.4 使用free释放一块动态开…

自动化测试总结

1.什么是自动化测试 以程序测试程序&#xff0c;以代码代替思维&#xff0c;以脚本的运行代替手工测试。自动化的测试涵盖了&#xff1a;功能&#xff08;黑盒&#xff09;自动化测试&#xff0c;功能&#xff08;白盒&#xff09;自动化测试&#xff0c;性能测试&#xff0c;…

Mac版VsCode快捷键大全

1 对应关系 标志 键名 ⌘ command ⇧ shift ↩ 回车 ↑ 上 ↓ 下 ⌃ control ⌥ option 高亮标记的是常用的快捷键。 2 编辑 按键 功能 ⇧ ⌥ 鼠标左键 ( Left) 按住鼠标左键下拉可以批量将鼠标键放在指定位置 ⇧ ⌥ ↑ 向上复制整行或者整段 ⇧ ⌥ ↓ 向下复制整行或…

掌上单片机实验室 – 低分辨率编码器测速方式完善(24)

一、背景 本以为“掌上单片机实验室”这一主题已告一段落&#xff0c;可最近在测试一批新做的“轮式驱动单元”时&#xff0c;发现原来的测速算法存在问题。 起因是&#xff1a;由于轮式驱动单元的连线较长&#xff0c;PCB体积也小&#xff0c;导致脉冲信号有干扰&#xff0c;加…

组件v-model(.sync)记录使用(vue3)

示例&#xff08;演示地址&#xff09; 以下是Vue3中使用v-model实现组件的双向数据绑定的示例代码&#xff1a; 首先&#xff0c;让我们来了解一下Vue3中v-model的用法。在Vue3中&#xff0c;v-model 指令可以用于自定义组件上&#xff0c;用于实现组件的双向数据绑定。与Vue2…

一键式Excel分词统计工具:如何轻松打包Python脚本为EXE

一键式Excel分词统计工具&#xff1a;如何轻松打包Python脚本为EXE 写在最前面需求分析直接用Python打包为什么大&#xff1f;为什么要使用conda环境&#xff1f; 将Python脚本打包为一个独立的应用程序1. 编写Python脚本&#xff1a;初步功能实现2. 初步图形用户界面&#xff…

基于Python flask的猫眼电影票房数据分析可视化系统,可以定制可视化

技术方案 猫眼电影票房数据分析可视化系统是基于Python Flask框架开发的一款用于分析和展示猫眼电影票房数据的Web应用程序。该系统利用Flask提供了一个简单而强大的后端框架&#xff0c;结合Request库进行网络爬虫获取猫眼电影票房数据&#xff0c;并使用Pyecharts进行可视化…

【AI的未来 - AI Agent系列】【MetaGPT】4.1 细说我在ActionNode实战中踩的那些坑

文章目录 1. MetaGPT 0.5.2 版本的坑1.1 坑一&#xff1a;cannot import name "ActionNode" from "metagpt.actions.action"1.2 坑二&#xff1a;simple_fill 没有参数 schema1.3 坑三&#xff1a;ActionNode一直在循环执行&#xff0c; 2. 升级成 MetaGP…