阳光算法(改进版):面向密集小障碍物复杂环境的路径规划方法与严谨的O(n)时间复杂度证明

阳光算法(改进版):面向密集小障碍物复杂环境的路径规划方法与严谨的O(n)时间复杂度证明

        阳光算法是一种全新的基于采样的平面路径规划方法,该方法的主要思路是通过模仿阳光照射的自然现象搜索到采集地形或障碍物边缘的切点从而快速构建出可行性路径,非常适合于解决迷宫等复杂地形下的全局路径规划问题。该方法在简洁的同时拥有极高的搜索效率,其计算复杂度经证明也比现有的RRT系列算法更低,关于该方法的详细介绍可以参考https://blog.ZEEKLOG.net/seabiscuit1993/article/details/147731476, 本文不再赘述。尽管阳光算法相较于传统路径规划方法具备显著优势,但其在部分环节仍存在严谨性与完备性方面的不足。本文针对传统的阳光算法中存在的问题做出了两个关键性改进,并通过进一步的分析和仿真实验对比,验证了所提改进方案的优越性和有效性。该改进算法已发表在如下期刊。

Yingjie Deng et al 2026 Meas. Sci. Technol. 37 096303,doi:10.1088/1361-6501/ae49b1

        首先是地图搜索完备性的问题。阳光算法对于地图的探索主要通过

FindTangent(\cdot)

寻找地形或者障碍图的边缘切点,具体是通过模拟阳光照射的现象,以路径节点

x_{sun}

为中心发射等角度间隔的太阳光线的方式来进行采样,之后对采样点进行筛选就可以获得符合条件的路径切点,如图1所示。这种采样方法对于连续不间断的地形或者障碍物边缘效果很好,但是对于密集小障碍物环境却很不理想,这是因为用于搜索的射线间的角度间隔固定,随着射线的逐渐延长,两条射线间的弧长也在逐渐增大,最终两个切点间的距离也会逐渐增加,如图2所示。这会直接导致密集环境中障碍物边缘切点的大量丢失,从而影响算法对于最短可行性路径的搜索。

图1   左图为360°照射采样,右图为切点采样

        针对等角度间隔采样不足的问题,改进后的阳光算法提出了一种自适应采样补偿机制,可以有效解决采样点丢失。改进后的

FindTangent\_mod(\cdot)

函数的伪代码如图3所示。当阳光射线由点

x_{sun}

以等角度间隔射出后,首先寻找两条射线间的最短弧长并将其设为

s

,以最短弧长

s

为基准,对于其他任意两条射线所对应的弧长

L

,如果存在关系

L=m*s

,那么就在这两条射线间的区域额外插入

m-1

条射线来将该区域平均划分为

m

份,如图4所示,其中

m

的定义式为

m=\max\left \{ 1, round\left ( \frac{\min\left \{ L,L_{pre} \right \}*\pi*\theta_{step}}{180*arc} \right ) \right \}

图2   密集小障碍物环境中的切点采样图

        有些读者可能会有这样的问题,难道不可以通过减小太阳射线间的角度间隔来提高在小障碍物密集区域的采样点数量吗?这种思路其实是可行的,然而一般的搜索地图中不仅存在小障碍物密集区域,还存在具有连续不间断边缘的大型障碍物,在这种情况下较小的角度间隔反而会生成大量的冗余节点,降低采样进行的效率,因此自适应采样补偿机制本质上是一种角度间隔的自适应调整。

图3    

FindTangent\_mod(\cdot)

函数伪代码

        除了采样点丢失的问题外,传统的阳光算法还存在时间复杂度的证明不严谨的问题。由证明的过程可知,阳光算法的时间复杂度为

O\left ( n \right )

的前提是数据集

Openset

为有限集合。但是传统的阳光算法并不存在

Openset

筛选机制,因此实际上

Openset

是无上限的,这不仅导致了时间复杂度验证的严谨性问题,无上限也意味着集合中存在冗余节点,这将降低算法的运行速度。为了提高算法的搜索速度,同时确保计算复杂度验证的严谨性,改进后的阳光算法提出了一种新型的滤波筛选机制用来保证集合

Openset

的有限性。这种滤波机制建立在之前的

NotOtherSon

的基础上,在筛选切点之前,首先对已经保存在

Openset

中的节点进行筛选。如图5所示,首先选取任意一个切点

x_{pt}

,对于

Openset

中的任意一个节点

x

L_1

表示从出发点

x_{start}

到达该点的原始路径的长度,

L_2

表示由出发点

x_{start}

经过点

x_{sun}

和切点

x_{pt}

到达该点的长度,如果存在关系

L_1>L_2

,那么说明到达该点的原始路径不是最优的,并将该点和其对应的连接关系从相应的集合中去除,重复上述操作直到所有的切点都将

Openset

中的节点遍历完成。相应的对于切点

x_{pt}

,如果连接

x_{pt}

x_{sun}

的总路径长度比连接

x_{pt}

Openset

中任何一个点的总路径长度都要长,那么说明

x_{pt}

应该是其他点的子节点而不是

x_{sun}

的。通过上述过滤机制进一步限制了

Openset

的大小使其存在有限边界,保证了时间复杂度证明的严谨性。

图4   自适应采样补偿机制演示图

      首先需要找到在算法运行过程中重复出现次数最多的函数,即

CollisionFree(\cdot)

函数,选择此函数的原因是它需要逐个像素的检查占用率,并且在每次迭代循环中都会被调用。如图6所示为改进的阳关算法的伪代码,假设闭集

Closeset

中存在

n_c

个点,由第五行可知

CollisionFree(\cdot)

函数在

Illnuminate(\cdot)

函数中被调用

n_c

次;对于第十行的每次

FindTanget\_mod(\cdot)

函数调用,可以参考图3中的伪代码,假设阳光射线的长度存在上界

\bar L

,设

CollisionFree(\cdot)

FindTanget\_mod(\cdot)

函数中的总调用次数为

n_t

,在第五行中的调用次数为

n_{t1}

次,在第十六行的调用次数为

n_{t2}

次,存在关系

n_t=n_{t1}+n_{t2}

,由

FindTanget\_mod(\cdot)

函数的伪代码可知

n_{t1}\le\left ( ceil\left ( \frac{360^\circ}{\theta_{step}} \right )+1\right )*\left ( ceil\left ( \frac{\bar L}{\Delta_{step}} \right )+1 \right )

其中

ceil\left ( \cdot \right )

为向上取整函数。由第十行可知,while循环将会执行

ceil\left ( \frac{360^\circ}{\theta_{step}} \right )

次。由

m

的定义式和阳光射线长度的上界

\bar L

可知,

m

的上界可以定义为

\bar m=round\left ( \frac{\bar L*\pi*\theta_{step}}{180*arc} \right )

由此可以得到

n_{t2}

的边界为

n_{t2}\le\bar m*ceil\left ( \frac{360^\circ}{\theta_{step}} \right )*\left ( ceil\left ( \frac{\bar L}{\theta_{step}} \right )+1 \right )

由上述不等式可知

n_{t1}

n_{t2}

均存在有限上界,那么一定存在关系

n_{t}\le\bar n_t

,并且

\bar n_t

是一个正常数。由此可知在图6第十行处

FindTanget\_mod(\cdot)

函数最多执行

n_c*n_t

次。又由于数据集

Openset

存在有限边界

\bar n_0

,切点集合

X_{candidates}

存在有限边界

\bar n_{X}

,在第十四行

CollisionFree(\cdot)

最多执行

n_c*\bar n_X*\bar n_o

次,在第二十三行最多执行

n_c*\bar n_X

次。设

CollisionFree(\cdot)

函数的最大执行次数为

n_{all}

,那么存在关系

n_{all}\le n_c+n_c*\bar n_t+n_c*\bar n_X*\bar n_o+n_c*\bar n_X

由上式可以得出关系

n_{all}\in O\left ( n \right )

,所以改进后的算法的计算复杂度为

O\left ( n \right )

图5    

Openset

数据集筛选演示图

图6    改进后的阳光算法伪代码图

Read more

EnvPilot:一款基于 Rust 的跨平台环境变量神器,一键搞定 Windows/Linux 环境配置!

EnvPilot:一款基于 Rust 的跨平台环境变量神器,一键搞定 Windows/Linux 环境配置!

文章目录 * 1. 项目介绍🎯 * 1.1. 什么是 EnvPilot? * 1.2. 为什么选择 EnvPilot? * 2. 核心优势:四大痛点全部解决!💪 * ✅ 痛点一:添加不生效?已修复! * ✅ 痛点二:删除删不掉?已修复! * ✅ 痛点三:PATH 清理失效?已修复! * ✅ 痛点四:误操作无法恢复?已解决! * 3. 支持的开发环境🛠️ * 4. 详细使用教程📖 * 4.1. Windows 平台使用教程 * 1️⃣ 下载安装 * 2️⃣ 配置环境变量 * 3️⃣ 清除环境变量 * 4.2. Linux 平台使用教程 * 1️⃣ 从源码编译 * 2️⃣ 配置环境变量 * 3️

By Ne0inhk
MySQL 表约束核心指南:从基础约束到外键关联(含实战案例)

MySQL 表约束核心指南:从基础约束到外键关联(含实战案例)

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 表约束核心概念 * 二. 基础约束:NULL/NOT NULL 与 DEFAULT * 2.1 空属性约束(NULL/NOT NULL) * 2.2 默认值约束(DEFAULT) * 2.3 列描述(COMMENT) * 2.4 零填充约束(ZEROFILL) * 三. 核心约束:主键、自增长与唯一键 * 3.1 主键约束(PRIMARY KEY) * 3.

By Ne0inhk
【MYSQL】MYSQL学习的一大重点:MYSQL表的操作

【MYSQL】MYSQL学习的一大重点:MYSQL表的操作

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 文章目录 * 0 ~> 概要 * 1 ~> 创建表 * 2 ~> 创建表的案例详解 * 3 ~> 查看表结构 * 4 ~> 修改表 * 4.1 什么时候需要修改表 * 4.2 修改方式 * 4.3 案例 * 4.3.1 在users表添加二条记录 * 4.

By Ne0inhk
RUST异步并发安全与内存管理的最佳实践

RUST异步并发安全与内存管理的最佳实践

RUST异步并发安全与内存管理的最佳实践 一、引言 异步并发编程在提高系统性能和响应时间的同时,也带来了并发安全和内存管理的挑战。Rust语言以其独特的所有权、借用和生命周期系统,为解决这些问题提供了强大的工具。本章将深入探讨异步并发安全与内存管理的核心概念、常见问题及解决方案,并通过实战项目优化演示这些方法的应用。 二、异步并发安全的基础概念 2.1 所有权、借用与生命周期 Rust的所有权系统是其并发安全的基础。每个值都有唯一的所有者,当所有者离开作用域时,值会被自动释放。借用分为可变借用和不可变借用,同一时间只能有一个可变借用或多个不可变借用,从而避免数据竞争。生命周期则确保引用在所有者有效的时间内使用。 fnmain(){letmut s =String::from("hello");// s是所有者let r1 =&s;// 不可变借用let r2 =&s;// 不可变借用(允许)// let r3 = &mut s; // 可变借用(禁止,

By Ne0inhk