【启发式算法】RRT*算法详细介绍(Python)

RRT* 算法原理

RRT*(Rapidly-exploring Random Tree Star)是RRT算法的优化版本,通过渐进最优的方式改进路径质量。核心思想是在扩展树的过程中重新选择父节点和重布线,以降低路径成本。

  • 采样:在配置空间中随机采样点。
  • 最近邻搜索:找到树上距离采样点最近的节点。
  • 扩展:从最近节点向采样点方向扩展新节点。
  • 父节点优化:在新节点附近半径内寻找成本更低的父节点。
  • 重布线:优化附近节点的父节点以降低整体路径成本。

Python 实现步骤

初始化环境

定义二维空间、起点、终点和障碍物:

import numpy as np import matplotlib.pyplot as plt class RRTStar: def __init__(self, start, goal, obstacles, bounds, max_iter=1000, step_size=0.5, radius=1.0): self.start = np.array(start) self.goal = np.array(goal) self.obstacles = obstacles # List of (center, radius) self.bounds = bounds # (x_min, x_max, y_min, y_max) self.max_iter = max_iter self.step_size = step_size self.radius = radius self.nodes = [{'point': start, 'parent': None, 'cost': 0}] 

采样与扩展

随机采样并扩展树:

def sample(self): if np.random.rand() < 0.1: # 10%概率采样目标点 return self.goal return np.random.uniform(low=[self.bounds[0], self.bounds[2]], high=[self.bounds[1], self.bounds[3]]) def nearest(self, point): distances = [np.linalg.norm(point - node['point']) for node in self.nodes] return np.argmin(distances) def steer(self, from_point, to_point): direction = to_point - from_point distance = np.linalg.norm(direction) if distance <= self.step_size: return to_point return from_point + direction * (self.step_size / distance) 

碰撞检测

检查路径是否与障碍物相交:

def is_collision_free(self, point1, point2): for (center, radius) in self.obstacles: if self.line_circle_intersection(point1, point2, center, radius): return False return True def line_circle_intersection(self, p1, p2, center, r): # 线段与圆的相交检测 d = p2 - p1 f = p1 - center a = np.dot(d, d) b = 2 * np.dot(f, d) c = np.dot(f, f) - r**2 discriminant = b**2 - 4 * a * c if discriminant < 0: return False t1 = (-b - np.sqrt(discriminant)) / (2 * a) t2 = (-b + np.sqrt(discriminant)) / (2 * a) return 0 <= t1 <= 1 or 0 <= t2 <= 1 

父节点优化与重布线
def find_best_parent(self, new_point, near_indices): min_cost = float('inf') best_parent = None for idx in near_indices: node = self.nodes[idx] if self.is_collision_free(node['point'], new_point): cost = node['cost'] + np.linalg.norm(new_point - node['point']) if cost < min_cost: min_cost = cost best_parent = idx return best_parent, min_cost def rewire(self, new_node_idx, near_indices): new_node = self.nodes[new_node_idx] for idx in near_indices: node = self.nodes[idx] if self.is_collision_free(new_node['point'], node['point']): new_cost = new_node['cost'] + np.linalg.norm(node['point'] - new_node['point']) if new_cost < node['cost']: node['parent'] = new_node_idx node['cost'] = new_cost 

主算法流程
def plan(self): for _ in range(self.max_iter): rand_point = self.sample() nearest_idx = self.nearest(rand_point) nearest_point = self.nodes[nearest_idx]['point'] new_point = self.steer(nearest_point, rand_point) if self.is_collision_free(nearest_point, new_point): near_indices = self.find_near_indices(new_point) best_parent, cost = self.find_best_parent(new_point, near_indices) if best_parent is not None: self.nodes.append({'point': new_point, 'parent': best_parent, 'cost': cost}) self.rewire(len(self.nodes)-1, near_indices) if np.linalg.norm(new_point - self.goal) <= self.step_size: if self.is_collision_free(new_point, self.goal): self.nodes.append({'point': self.goal, 'parent': len(self.nodes)-1, 'cost': self.nodes[-1]['cost'] + np.linalg.norm(self.goal - new_point)}) return self.extract_path() return None 

可视化与路径提取

def extract_path(self): path = [] node = self.nodes[-1] while node['parent'] is not None: path.append(node['point']) node = self.nodes[node['parent']] path.append(self.start) return np.array(path[::-1]) def plot(self, path=None): plt.figure(figsize=(10, 8)) for (center, radius) in self.obstacles: circle = plt.Circle(center, radius, color='r', alpha=0.5) plt.gca().add_patch(circle) for node in self.nodes[1:]: parent = self.nodes[node['parent']] plt.plot([node['point'][0], parent['point'][0]], [node['point'][1], parent['point'][1]], 'b-', alpha=0.3) if path is not None: plt.plot(path[:,0], path[:,1], 'g-', linewidth=2) plt.scatter(*self.start, color='g', s=100, label='Start') plt.scatter(*self.goal, color='y', s=100, label='Goal') plt.xlim(self.bounds[0], self.bounds[1]) plt.ylim(self.bounds[2], self.bounds[3]) plt.legend() plt.show() 

示例用法

# 定义障碍物和边界 obstacles = [((3, 3), 1.5), ((6, 7), 2), ((8, 2), 1)] bounds = (0, 10, 0, 10) # 运行RRT* rrt = RRTStar(start=(1, 1), goal=(9, 9), obstacles=obstacles, bounds=bounds) path = rrt.plan() rrt.plot(path) 

关键参数说明

  • max_iter:最大迭代次数,影响路径优化程度。
  • step_size:扩展步长,平衡探索速度与精度。
  • radius:重布线半径,决定局部优化的范围。

通过调整参数和增加迭代次数,RRT*能够逐渐逼近最优路径。算法复杂度高于RRT,但路径质量显著提升。

Read more

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

【OpenClaw从入门到精通】第10篇:OpenClaw生产环境部署全攻略:性能优化+安全加固+监控运维(2026实测版)

摘要:本文聚焦OpenClaw从测试环境走向生产环境的核心痛点,围绕“性能优化、安全加固、监控运维”三大维度展开实操讲解。先明确生产环境硬件/系统选型标准,再通过硬件层资源管控、模型调度策略、缓存优化等手段提升响应速度(实测响应效率提升50%+);接着从网络、权限、数据三层构建安全防护体系,集成火山引擎安全方案拦截高危操作;最后落地TenacitOS可视化监控与Prometheus告警体系,配套完整故障排查清单和虚拟实战案例。全文所有配置、代码均经实测验证,兼顾新手入门实操性和进阶读者的生产级部署需求,帮助开发者真正实现OpenClaw从“能用”到“放心用”的跨越。 优质专栏欢迎订阅! 【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】 【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】 【AI工程化落地与YOLOv8/v9实战】【C#工业上位机高级应用:高并发通信+性能优化】 【Java生产级避坑指南:

By Ne0inhk
ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

ARM Linux 驱动开发篇--- Linux 并发与竞争实验(互斥体实现 LED 设备互斥访问)--- Ubuntu20.04互斥体实验

🎬 渡水无言:个人主页渡水无言 ❄专栏传送门: 《linux专栏》《嵌入式linux驱动开发》《linux系统移植专栏》 ❄专栏传送门: 《freertos专栏》《STM32 HAL库专栏》 ⭐️流水不争先,争的是滔滔不绝  📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生 | 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生 在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连 目录 前言  一、实验基础说明 1.1、互斥体简介 1.2 本次实验设计思路 二、硬件原理分析(看过之前博客的可以忽略) 三、实验程序编写 3.1 互斥体 LED 驱动代码(mutex.c) 3.2.1、设备结构体定义(28-39

By Ne0inhk
Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:swagger_dart_code_generator 接口代码自动化生成的救星(OpenAPI/Swagger) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 后端工程师扔给你一个 Swagger (OpenAPI) 文档地址,你会怎么做? 1. 对着文档,手写 Dart Model 类(容易写错字段类型)。 2. 手写 Retrofit/Dio 的 API 接口定义(容易拼错 URL)。 3. 当后端修改了字段名,你对着报错修半天。 这是重复劳动的地狱。 swagger_dart_code_generator 可以将 Swagger (JSON/YAML) 文件直接转换为高质量的 Dart 代码,包括: * Model 类:支持 json_serializable,带 fromJson/

By Ne0inhk
Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

Linux 开发别再卡壳!makefile/git/gdb 全流程实操 + 作业解析,新手看完直接用----《Hello Linux!》(5)

文章目录 * 前言 * make/makefile * 文件的三个时间 * Linux第一个小程序-进度条 * 回车和换行 * 缓冲区 * 程序的代码展示 * git指令 * 关于gitee * Linux调试器-gdb使用 * 作业部分 前言 做 Linux 开发时,你是不是也遇到过这些 “卡脖子” 时刻?写 makefile 时,明明语法没错却报错,最后发现是依赖方法行没加 Tab;想提交代码到 gitee,记不清 git add/commit/push 的 “三板斧”,还得反复搜教程;用 gdb 调试程序,输了命令没反应,才想起编译时没加-g生成 debug 版本;甚至连写个进度条,都搞不懂\r和\n的区别,导致进度条乱跳…… 其实这些问题,

By Ne0inhk