【启发式算法】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

最全java面试题及答案(208道)

最全java面试题及答案(208道)

本文分为十九个模块,分别是:「Java 基础、容器、多线程、反射、对象拷贝、Java Web 、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM」 ,如下图所示: 共包含 208 道面试题,本文的宗旨是为读者朋友们整理一份详实而又权威的面试清单,下面一起进入主题吧。 Java 基础 1. JDK 和 JRE 有什么区别? * JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java

By Ne0inhk
10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?

10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?

文章目录 * 一、引言 * 云计算平台概览 * ToDesk云电脑:随时随地用上高性能电脑 * 二 .云电脑初体验 * DeekSeek介绍 * 版本参数与特点 * 任务类型表现 * 1、ToDesk云电脑 * 2、顺网云电脑 * 3、海马云电脑 * 三、DeekSeek本地化实操和AIGC应用 * 1. ToDesk云电脑 * 2. 海马云电脑 * 3、顺网云电脑 * 四、结语 * 总结:云电脑如何选择? 一、引言 DeepSeek这些大模型让 AI 开发变得越来越有趣,但真要跑起来,可没那么简单! * 本地配置太麻烦:显卡不够、驱动难装、环境冲突,光是折腾这些就让人心态崩了。 * 云端性能参差不齐:选错云电脑,可能卡到爆、加载慢,还容易掉线,搞得效率直线下降。 * 成本难控:有的平台按小时计费,价格一会儿一个样,

By Ne0inhk
用 DeepSeek 打造你的超强代码助手

用 DeepSeek 打造你的超强代码助手

DeepSeek Engineer 是啥? 简单来说,DeepSeek Engineer 是一个基于命令行的智能助手。它能帮你完成这些事: * 快速读文件内容:比如你有个配置文件,直接用命令把它加载进助手,后续所有操作都可以基于这个文件。 * 自动改文件:它不仅能提建议,还可以直接生成差异表(diff),甚至自动应用修改。 * 智能代码生成:比如你让它生成代码片段,它会按照指定格式和规则直接返回。 更重要的是,这一切都是通过 DeepSeek 的强大 API 来实现的。想象一下,你有个贴身助手,不仅能听懂你的代码需求,还能直接动手帮你写! 核心功能拆解 我们先来看 DeepSeek Engineer 的几个核心能力,让你更好地理解它的强大之处。 1. 自动配置 DeepSeek 客户端 启动这个工具时,你只需要准备一个 .env 文件,里面写上你的 API Key,比如: DEEPSEEK_API_

By Ne0inhk
解锁DeepSeek潜能:Docker+Ollama打造本地大模型部署新范式

解锁DeepSeek潜能:Docker+Ollama打造本地大模型部署新范式

🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是Docker 2、什么是Ollama 二、准备工作 1、操作系统 2、镜像准备 三、安装 1、安装Docker 2、启动Ollama 3、拉取Deepseek大模型 4、启动Deepseek  一、引言 1、什么是Docker Docker:就像一个“打包好的App” 想象一下,你写了一个很棒的程序,在自己的电脑上运行得很好。但当你把它发给别人,可能会遇到各种问题: * “这个软件需要 Python 3.8,但我只有 Python 3.6!

By Ne0inhk