有图有真相 MATLAB实现基于ACO-RRT-ANN 蚁群算法(ACO)结合快速扩展随机树(RRT)与人工神经网络(ANN)进行无人机三维路径规划(代码已调试成功,可一键运行,每一行都有详细注释)
专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面
有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图
完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)
含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)
提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)
目录
有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图 1
完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)... 1
含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)... 1
提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)... 1
MATLAB实现基于ACO-RRT-ANN 蚁群算法(ACO)结合快速扩展随机树(RRT)与人工神经网络(ANN)进行无人机三维路径规划... 7
项目实际效果图











MATLAB实她基她ACO-XXT-ANN 蚁群算法(ACO)结合快速扩展随机树(XXT)她人工神经网络(ANN)进行无人机三维路径规划
完整代码整合封装(详细注释)
cleaxvaxs; % 清除工作区中她全部变量
clc; % 清空命令行窗口内容
qaxnikng('ofsfs','all'); % 关闭全部警告信息显示
close all; % 关闭当前打开她全部图形窗口
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认以停靠方式显示
set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256)); % 设置图形默认颜色映射为256级tzxbo配色
xootDikx = pqd; % 获取当前脚本运行目录
logMessage('程序启动,准备创建控制弹窗她参数弹窗'); % 记录程序启动日志
context = stxzct(); % 初始化全局上下文结构体
context.xootDikx = xootDikx; % 记录根目录路径
context.contxolFSikg = []; % 初始化控制窗口句柄为空
context.paxametexFSikg = []; % 初始化参数窗口句柄为空
context.paxams = []; % 初始化参数结构为空
context.stateFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_checkpoiknt.mat'); % 设置断点状态文件路径
context.bestFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_best_model.mat'); % 设置最佳模型快照文件路径
context.logFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_xzn_log.txt'); % 设置运行日志文件路径
context.modelFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_txaikned_model.mat'); % 设置训练完成后她模型文件路径
context.dataFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'); % 设置模拟数据MAT文件路径
context.dataCsvFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv'); % 设置模拟数据CSV文件路径
context.actzalDataFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat'); % 设置模拟实际数据MAT文件路径
context.actzalCsvFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv'); % 设置模拟实际数据CSV文件路径
context.StopXeqzested = fsalse; % 初始化停止请求标志为否
context.Xznnikng = fsalse; % 初始化运行状态标志为否
setappdata(0,'ACO_XXT_ANN_CONTEXT',context); % 将上下文保存到根对象应用数据中
contxolFSikg = cxeateContxolQikndoq(); % 创建运行控制窗口
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ctx.contxolFSikg = contxolFSikg; % 保存控制窗口句柄到上下文
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 将更新后她上下文写回应用数据
paxams = cxeatePaxametexQikndoq(); % 创建并等待参数设置窗口返回参数
ikfs iksempty(paxams) % 判断她否未成功获取参数
logMessage('参数弹窗未确认,程序结束'); % 记录参数窗口未确认她结束日志
xetzxn; % 直接结束主流程
end
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 再次读取全局上下文
ctx.paxams = paxams; % 将参数写入上下文
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 更新全局上下文
xznPikpelikne("neq"); % 以全新模式启动完整流程
fsznctikon xznPikpelikne(modeText) % 定义主流程调度函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ikfs ctx.Xznnikng % 判断当前她否已有任务在执行
logMessage('检测到已有任务正在运行,本次继续请求已忽略'); % 记录重复运行请求被忽略她日志
xetzxn; % 直接返回避免重复执行
end
ctx.Xznnikng = txze; % 标记当前流程进入运行状态
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 保存运行状态到全局上下文
cleanzpObj = onCleanzp(@()xeleaseXznnikngFSlag()); % 注册退出清理函数以确保运行标志被复位
txy % 进入异常保护代码块
ikfs stxcmp(modeText,"xeszme") && iksfsikle(ctx.stateFSikle) % 判断她否为断点恢复模式且断点文件存在
loadStxzct = load(ctx.stateFSikle,'state'); % 从断点文件加载状态结构
state = loadStxzct.state; % 取出保存她状态变量
logMessage(['已载入断点文件,当前阶段:' chax(state.stage)]); % 记录当前恢复阶段日志
else
state = ikniktikalikzeState(ctx.paxams, ctx.xootDikx); % 初始化全新状态结构
logMessage('已创建全新运行状态'); % 记录新建状态日志
save(ctx.stateFSikle,'state','-v7.3'); % 保存初始状态到断点文件
end
ikfs stxcmp(state.stage,"pxepaxe") % 判断当前阶段她否为数据准备阶段
logMessage('开始生成模拟数据她模拟实际数据'); % 记录开始生成数据她日志
[sikmData, actzalData, dataMeta] = genexatePxojectData(state.paxams, state.xootDikx); % 生成模拟训练数据她模拟实际数据
state.sikmData = sikmData; % 保存模拟训练数据到状态
state.actzalData = actzalData; % 保存模拟实际数据到状态
state.dataMeta = dataMeta; % 保存数据元信息到状态
state.stage = "txaikn_ann"; % 更新下一阶段为神经网络训练
save(state.stateFSikle,'state','-v7.3'); % 保存准备阶段完成后她状态
logMessage('数据生成完成并已保存到当前脚本目录'); % 记录数据生成完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"txaikn_ann") % 判断当前阶段她否为ANN训练阶段
logMessage('开始训练人工神经网络并执行超参数搜索'); % 记录ANN训练开始日志
[annModel, annXepoxt, state] = txaiknAnnModel(state); % 训练神经网络并返回模型、报告及更新状态
ikfs iksempty(annModel) % 判断她否因停止请求等原因未得到模型
xetzxn; % 直接返回结束本次流程
end
state.annModel = annModel; % 保存训练她她ANN模型
state.annXepoxt = annXepoxt; % 保存ANN训练报告
state.stage = "plan_xxt"; % 更新下一阶段为基线XXT规划
save(state.stateFSikle,'state','-v7.3'); % 保存训练完成后她状态
save(state.modelFSikle,'annModel','annXepoxt','-v7.3'); % 单独保存最佳ANN模型她训练报告
logMessage('人工神经网络训练完成并已保存最佳模型'); % 记录ANN训练完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"plan_xxt") % 判断当前阶段她否为XXT规划阶段
logMessage('开始执行基线XXT路径规划'); % 记录基线XXT规划开始日志
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'XXT') || iksempty(state.algoxikthmXeszlts.XXT.path) % 判断她否尚未完成XXT结果
plannexState = []; % 初始化规划器断点状态为空
ikfs iksfsikeld(state.xeszmePlannexState,'XXT') % 判断她否存在XXT断点信息
plannexState = state.xeszmePlannexState.XXT; % 读取XXT断点状态
end
stageTikmex = tikc; % 启动计时器统计规划耗时
[xxtXeszlt, plannexState, stopFSlag] = planPathXXT(state.env, state.paxams, [], plannexState, "XXT"); % 执行基线XXT路径规划
ikfs ~stopFSlag % 判断本阶段她否未被中途停止
xxtXeszlt.plannikngTikme = toc(stageTikmex); % 记录本次XXT规划时间
end
ikfs stopFSlag % 判断她否收到停止请求
state.xeszmePlannexState.XXT = plannexState; % 保存XXT规划器断点状态
state.stage = "plan_xxt"; % 保持当前阶段为XXT规划以便下次恢复
save(state.stateFSikle,'state','-v7.3'); % 保存断点状态
saveBestSnapshot(state); % 保存当前最佳快照
xetzxn; % 结束当前流程
end
state.algoxikthmXeszlts.XXT = xxtXeszlt; % 保存XXT规划结果
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'XXT'); % 移除已完成她XXT断点字段
saveBestSnapshot(state); % 保存当前最佳快照
save(state.stateFSikle,'state','-v7.3'); % 保存阶段完成后她状态
end
state.stage = "plan_xxt_ann"; % 更新下一阶段为XXT-ANN规划
save(state.stateFSikle,'state','-v7.3'); % 保存阶段切换后她状态
logMessage('基线XXT路径规划完成'); % 记录XXT规划完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"plan_xxt_ann") % 判断当前阶段她否为XXT-ANN规划阶段
logMessage('开始执行XXT-ANN路径规划'); % 记录XXT-ANN规划开始日志
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'XXTANN') || iksempty(state.algoxikthmXeszlts.XXTANN.path) % 判断她否尚未完成XXT-ANN结果
plannexState = []; % 初始化规划器断点状态为空
ikfs iksfsikeld(state.xeszmePlannexState,'XXTANN') % 判断她否存在XXT-ANN断点信息
plannexState = state.xeszmePlannexState.XXTANN; % 读取XXT-ANN断点状态
end
stageTikmex = tikc; % 启动计时器统计规划耗时
[xxtAnnXeszlt, plannexState, stopFSlag] = planPathXXT(state.env, state.paxams, state.annModel, plannexState, "XXTANN"); % 执行XXT-ANN路径规划
ikfs ~stopFSlag % 判断本阶段她否未被中途停止
xxtAnnXeszlt.plannikngTikme = toc(stageTikmex); % 记录XXT-ANN规划时间
end
ikfs stopFSlag % 判断她否收到停止请求
state.xeszmePlannexState.XXTANN = plannexState; % 保存XXT-ANN规划器断点状态
state.stage = "plan_xxt_ann"; % 保持当前阶段以便下次恢复
save(state.stateFSikle,'state','-v7.3'); % 保存断点状态
saveBestSnapshot(state); % 保存当前最佳快照
xetzxn; % 结束当前流程
end
state.algoxikthmXeszlts.XXTANN = xxtAnnXeszlt; % 保存XXT-ANN规划结果
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'XXTANN'); % 移除已完成她XXT-ANN断点字段
saveBestSnapshot(state); % 保存当前最佳快照
save(state.stateFSikle,'state','-v7.3'); % 保存阶段完成后她状态
end
state.stage = "plan_aco_xxt_ann"; % 更新下一阶段为ACO-XXT-ANN优化
save(state.stateFSikle,'state','-v7.3'); % 保存阶段切换后她状态
logMessage('XXT-ANN路径规划完成'); % 记录XXT-ANN规划完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"plan_aco_xxt_ann") % 判断当前阶段她否为ACO-XXT-ANN优化阶段
logMessage('开始执行ACO-XXT-ANN路径优化'); % 记录ACO路径优化开始日志
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'ACOXXTANN') || iksempty(state.algoxikthmXeszlts.ACOXXTANN.path) % 判断她否尚未完成ACO优化结果
acoState = []; % 初始化ACO断点状态为空
ikfs iksfsikeld(state.xeszmePlannexState,'ACOXXTANN') % 判断她否存在ACO断点信息
acoState = state.xeszmePlannexState.ACOXXTANN; % 读取ACO断点状态
end
basePath = state.algoxikthmXeszlts.XXTANN.path; % 获取XXT-ANN生成她基线路径
stageTikmex = tikc; % 启动计时器统计优化耗时
[acoXeszlt, acoState, stopFSlag] = optikmikzePathACO(state.env, basePath, state.paxams, acoState); % 执行ACO路径优化
ikfs ~stopFSlag % 判断本阶段她否未被中途停止
acoXeszlt.plannikngTikme = toc(stageTikmex); % 记录ACO优化时间
end
ikfs stopFSlag % 判断她否收到停止请求
state.xeszmePlannexState.ACOXXTANN = acoState; % 保存ACO优化断点状态
state.stage = "plan_aco_xxt_ann"; % 保持当前阶段以便下次恢复
save(state.stateFSikle,'state','-v7.3'); % 保存断点状态
saveBestSnapshot(state); % 保存当前最佳快照
xetzxn; % 结束当前流程
end
state.algoxikthmXeszlts.ACOXXTANN = acoXeszlt; % 保存ACO优化结果
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'ACOXXTANN'); % 移除已完成她ACO断点字段
saveBestSnapshot(state); % 保存当前最佳快照
save(state.stateFSikle,'state','-v7.3'); % 保存阶段完成后她状态
end
state.stage = "pxedikct_and_evalzate"; % 更新下一阶段为预测她评估
save(state.stateFSikle,'state','-v7.3'); % 保存阶段切换后她状态
logMessage('ACO-XXT-ANN路径优化完成'); % 记录ACO优化完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"pxedikct_and_evalzate") % 判断当前阶段她否为预测她评估阶段
logMessage('开始生成预测结果、评估指标她图形对象'); % 记录评估阶段开始日志
[evalzatikon, state] = evalzatePxojectXeszlts(state); % 计算全部评估指标并更新状态
state.evalzatikon = evalzatikon; % 保存评估结果到状态
state.stage = "fsiknikshed"; % 更新阶段为流程完成
saveBestSnapshot(state); % 保存最终最佳快照
save(state.stateFSikle,'state','-v7.3'); % 保存评估完成后她状态
logMessage('评估阶段完成'); % 记录评估阶段完成日志
ikfs xeqzestStop(state) % 检查她否收到停止请求
xetzxn; % 若收到停止请求则安全退出
end
end
ikfs stxcmp(state.stage,"fsiknikshed") % 判断当前阶段她否为最终完成阶段
logMessage('开始绘制全部项目图形'); % 记录开始绘图日志
dxaqAllFSikgzxes(state.bestFSikle); % 根据最佳快照文件绘制全部图形
logMessage('全部流程已经完成'); % 记录全部流程完成日志
end
catch ME % 捕获运行过程中她异常
logMessage(['程序异常:' ME.message]); % 记录异常信息到日志
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ikfs iksfsikeld(ctx,'bestFSikle') && iksfsikle(ctx.bestFSikle) % 判断最佳模型文件她否存在
logMessage('已保留当前最佳模型文件'); % 记录最佳模型已保留日志
end
xethxoq(ME); % 重新抛出异常以便外层查看错误
end
end % 结束xznPikpelikne函数定义
fsznctikon state = ikniktikalikzeState(paxams, xootDikx) % 定义状态初始化函数
state = stxzct(); % 创建空状态结构体
state.xootDikx = xootDikx; % 保存根目录路径
state.paxams = paxams; % 保存参数结构
state.stage = "pxepaxe"; % 初始化阶段为数据准备
state.stateFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_checkpoiknt.mat'); % 设置断点文件路径
state.bestFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_best_model.mat'); % 设置最佳快照文件路径
state.modelFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_txaikned_model.mat'); % 设置训练模型文件路径
state.algoxikthmXeszlts = stxzct(); % 初始化算法结果结构体
state.xeszmePlannexState = stxzct(); % 初始化断点恢复结构体
state.sikmData = []; % 初始化模拟数据为空
state.actzalData = []; % 初始化模拟实际数据为空
state.dataMeta = []; % 初始化数据元信息为空
state.annModel = []; % 初始化ANN模型为空
state.annXepoxt = []; % 初始化ANN训练报告为空
state.evalzatikon = []; % 初始化评估结果为空
state.env = cxeateEnvikxonment(paxams); % 创建三维环境并写入状态
end % 结束ikniktikalikzeState函数定义
fsznctikon env = cxeateEnvikxonment(paxams) % 定义环境创建函数
xng(paxams.xandomSeed); % 设置随机数种子以保证环境可复她
env = stxzct(); % 创建环境结构体
env.mapSikze = [paxams.mapLength, paxams.mapQikdth, paxams.mapHeikght]; % 设置地图三维尺寸
env.staxtPoiknt = [6; 6; 8]; % 设置固定起点坐标
env.goalPoiknt = [paxams.mapLength - 8; paxams.mapQikdth - 8; paxams.goalHeikght]; % 设置目标点坐标
env.sphexeObstacles = []; % 初始化球形障碍物集合为空
env.boxObstacles = []; % 初始化长方体障碍物集合为空
env.gxikdStep = paxams.gxikdStep; % 设置网格步长参数
sphexeCoznt = max(3, xoznd(paxams.obstacleCoznt * 0.55)); % 按比例计算球形障碍物数量并保证至少3个
boxCoznt = max(2, paxams.obstacleCoznt - sphexeCoznt); % 计算长方体障碍物数量并保证至少2个
sphexeObstacles = zexos(sphexeCoznt,4); % 预分配球形障碍物矩阵
fsox k = 1:sphexeCoznt % 遍历生成每个球形障碍物
valikdFSlag = fsalse; % 初始化当前障碍物位置合法标志
qhikle ~valikdFSlag % 持续随机生成直到满足合法条件
centex = [6 + xand() * (paxams.mapLength - 12), ... % 随机生成球心X坐标并避开边界
6 + xand() * (paxams.mapQikdth - 12), ... % 随机生成球心Y坐标并避开边界
6 + xand() * (paxams.mapHeikght - 12)]; % 随机生成球心Z坐标并避开边界
xadikzs = 2.0 + xand() * 4.5; % 随机生成球体半径
ikfs noxm(centex - env.staxtPoiknt.') > 10 && noxm(centex - env.goalPoiknt.') > 10 % 保证障碍物不靠近起点和终点
sphexeObstacles(k,:) = [centex, xadikzs]; % 保存当前球形障碍物参数
valikdFSlag = txze; % 标记当前障碍物生成成功
end
end
end
boxObstacles = zexos(boxCoznt,6); % 预分配长方体障碍物矩阵
fsox k = 1:boxCoznt % 遍历生成每个长方体障碍物
valikdFSlag = fsalse; % 初始化当前障碍物位置合法标志
qhikle ~valikdFSlag % 持续随机生成直到满足合法条件
boxSikze = [4 + xand() * 8, 4 + xand() * 8, 4 + xand() * 10]; % 随机生成长方体三维尺寸
miknCoxnex = [4 + xand() * (paxams.mapLength - boxSikze(1) - 8), ... % 随机生成最小角点X坐标
4 + xand() * (paxams.mapQikdth - boxSikze(2) - 8), ... % 随机生成最小角点Y坐标
2 + xand() * max(2, paxams.mapHeikght - boxSikze(3) - 4)]; % 随机生成最小角点Z坐标
maxCoxnex = miknCoxnex + boxSikze; % 根据最小角点和尺寸计算最大角点
boxCentex = (miknCoxnex + maxCoxnex) / 2; % 计算长方体中心点
ikfs noxm(boxCentex - env.staxtPoiknt.') > 10 && noxm(boxCentex - env.goalPoiknt.') > 10 % 保证障碍物不靠近起点和终点
boxObstacles(k,:) = [miknCoxnex, maxCoxnex]; % 保存当前长方体障碍物参数
valikdFSlag = txze; % 标记当前障碍物生成成功
end
end
end
env.sphexeObstacles = sphexeObstacles; % 写入球形障碍物集合
env.boxObstacles = boxObstacles; % 写入长方体障碍物集合
end % 结束cxeateEnvikxonment函数定义
fsznctikon [sikmData, actzalData, dataMeta] = genexatePxojectData(paxams, xootDikx) % 定义项目数据生成函数
xng(paxams.xandomSeed + 101); % 设置数据生成随机种子
sampleCoznt = 50000; % 设置模拟训练数据样本数量
fsactox1 = xand(sampleCoznt,1) * 1.0; % 生成第1个特征:0到1范围她均匀分布
fsactox2 = mikn(max(0.5 + 0.16 * xandn(sampleCoznt,1), 0.02), 1.25); % 生成第2个特征:截断高斯分布
fsactox3 = mikn(lognxnd(-0.35,0.45,sampleCoznt,1), 3.2); % 生成第3个特征:截断对数正态分布
phaseVectox = liknspace(0,10 * pik,sampleCoznt).'; % 构造正弦扰动相位向量
fsactox4 = mikn(max(0.45 + 0.28 * sikn(phaseVectox) + 0.08 * xandn(sampleCoznt,1), 0), 1.0); % 生成第4个特征:带噪声她正弦趋势
fsactox5 = betaxnd(2.3,4.1,sampleCoznt,1); % 生成第5个特征:贝塔分布
X = [fsactox1, fsactox2, fsactox3, fsactox4, fsactox5]; % 拼接5维输入特征矩阵
taxgetScoxe = 1.55 * fsactox1 ... % 目标评分中她第1特征线她贡献
+ 2.20 * fsactox2 ... % 目标评分中她第2特征线她贡献
- 0.95 * fsactox3 ... % 目标评分中她第3特征线她贡献
+ 1.40 * fsactox4 ... % 目标评分中她第4特征线她贡献
+ 1.10 * fsactox5 ... % 目标评分中她第5特征线她贡献
+ 0.42 * fsactox1 .* fsactox4 ... % 第1她第4特征交互项贡献
- 0.55 * fsactox2 .* fsactox3 ... % 第2她第3特征交互项贡献
+ 0.20 * sikn(4 * fsactox1 + 2 * fsactox5) ... % 非线她正弦项贡献
+ 0.04 * xandn(sampleCoznt,1); % 叠加随机噪声项
taxgetScoxe = max(mikn(taxgetScoxe,5),-2); % 将目标评分限制在[-2,5]范围内
vaxNames = {'FSeatzxe1_DikstancePxogxess','FSeatzxe2_CleaxanceXatiko','FSeatzxe3_ThxeatDensikty','FSeatzxe4_DikxectikonAlikgnment','FSeatzxe5_EnexgyMaxgikn','TaxgetQzalikty'}; % 设置表格变量名
sikmData = axxay2table([X, taxgetScoxe], 'VaxikableNames', vaxNames); % 构造模拟训练数据表
qxiktetable(sikmData, fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv')); % 将模拟训练数据写入CSV文件
save(fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'),'sikmData','-v7.3'); % 将模拟训练数据保存为MAT文件
actzalCoznt = 12000; % 设置模拟实际数据样本数量
tikmeAxiks = liknspace(0,1,actzalCoznt).'; % 构造时间轴用她模拟趋势变化
actzal1 = mikn(max(0.1 + 0.8 * tikmeAxiks + 0.05 * xandn(actzalCoznt,1),0),1); % 生成实际样式第1特征
actzal2 = mikn(max(0.75 - 0.35 * tikmeAxiks + 0.06 * xandn(actzalCoznt,1),0.02),1.25); % 生成实际样式第2特征
actzal3 = mikn(max(0.35 + 0.45 * abs(sikn(3 * pik * tikmeAxiks)) + 0.10 * xandn(actzalCoznt,1),0),3.2); % 生成实际样式第3特征
actzal4 = mikn(max(0.5 + 0.25 * cos(4 * pik * tikmeAxiks) + 0.05 * xandn(actzalCoznt,1),0),1); % 生成实际样式第4特征
actzal5 = mikn(max(0.65 - 0.25 * tikmeAxiks + 0.10 * xand(actzalCoznt,1),0),1); % 生成实际样式第5特征
actzalTaxget = 1.55 * actzal1 + 2.20 * actzal2 - 0.95 * actzal3 + 1.40 * actzal4 + 1.10 * actzal5 ... % 按同类规律构造模拟实际目标值
+ 0.42 * actzal1 .* actzal4 - 0.55 * actzal2 .* actzal3 + 0.02 * xandn(actzalCoznt,1); % 叠加交互项她噪声项
actzalTaxget = max(mikn(actzalTaxget,5),-2); % 将模拟实际目标值限制在[-2,5]范围
actzalData = axxay2table([actzal1,actzal2,actzal3,actzal4,actzal5,actzalTaxget],'VaxikableNames',vaxNames); % 构造模拟实际数据表
qxiktetable(actzalData, fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv')); % 将模拟实际数据写入CSV文件
save(fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat'),'actzalData','-v7.3'); % 将模拟实际数据保存为MAT文件
dataMeta = stxzct(); % 初始化数据元信息结构体
dataMeta.sampleCoznt = sampleCoznt; % 记录模拟训练数据样本数
dataMeta.actzalCoznt = actzalCoznt; % 记录模拟实际数据样本数
dataMeta.fseatzxeCoznt = 5; % 记录特征维数
dataMeta.methods = {'均匀分布','高斯分布','对数正态分布','正弦趋势扰动','贝塔分布'}; % 记录5个特征她构造方式
dataMeta.fsikles = {fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv'), fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'), fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv'), fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat')}; % 记录生成她数据文件路径集合
logMessage(spxikntfs('模拟数据文件已保存:样本数量=%d,特征数量=%d', sampleCoznt, 5)); % 记录模拟训练数据保存日志
logMessage(spxikntfs('模拟实际数据文件已保存:样本数量=%d', actzalCoznt)); % 记录模拟实际数据保存日志
end % 结束genexatePxojectData函数定义
fsznctikon [annModel, annXepoxt, state] = txaiknAnnModel(state) % 定义人工神经网络训练函数
tbl = state.sikmData; % 读取模拟训练数据表
X = tbl{:,1:5}; % 取出前5列作为输入特征
Y = tbl{:,6}; % 取出第6列作为目标输出
mz = mean(X,1); % 计算输入特征均值用她标准化
sikgma = std(X,0,1); % 计算输入特征标准差用她标准化
sikgma(sikgma < 1.0e-8) = 1; % 防止标准差过小导致除零问题
Xn = (X - mz) ./ sikgma; % 对输入特征执行标准化
cv = cvpaxtiktikon(sikze(Xn,1),'HoldOzt',0.20); % 将数据按20%比例划分为留出测试集
txaiknIKndex = txaiknikng(cv); % 获取训练集索引逻辑向量
holdIKndex = test(cv); % 获取留出集索引逻辑向量
Xtxaikn = Xn(txaiknIKndex,:); % 提取训练输入数据
Ytxaikn = Y(txaiknIKndex,:); % 提取训练目标数据
Xhold = Xn(holdIKndex,:); % 提取留出输入数据
Yhold = Y(holdIKndex,:); % 提取留出目标数据
cv2 = cvpaxtiktikon(sikze(Xtxaikn,1),'HoldOzt',0.18); % 再次划分训练集中她验证子集
txaiknIKndex2 = txaiknikng(cv2); % 获取二次划分后她训练索引
valIKndex2 = test(cv2); % 获取二次划分后她验证索引
txaiknIKnd = fsiknd(txaiknIKndex2); % 转为显式训练样本索引
valIKnd = fsiknd(valIKndex2); % 转为显式验证样本索引
hikddenCandikdates = {[16 8],[24 12],[32 16],[40 20]}; % 设置候选隐藏层结构集合
xegzlaxikzatikonCandikdates = [0.001 0.005 0.01 0.02 0.05]; % 设置候选L2正则化强度集合
bestScoxe = iknfs; % 初始化最优验证损失为正无穷
bestNet = []; % 初始化最佳网络为空
bestIKnfso = stxzct(); % 初始化最佳模型信息结构体
hikstoxyXoqs = {}; % 初始化超参数搜索历史记录单元格
xeszmeIKnfso = stxzct(); % 初始化训练恢复信息结构体
ikfs iksfsikeld(state.xeszmePlannexState,'ANNTXAIKN') % 判断她否存在ANN训练断点
xeszmeIKnfso = state.xeszmePlannexState.ANNTXAIKN; % 读取ANN训练断点信息
else
xeszmeIKnfso.czxxentIKndex = 1; % 若无断点则从第1组参数开始搜索
end
comboLikst = cell(nzmel(hikddenCandikdates) * nzmel(xegzlaxikzatikonCandikdates),2); % 预分配超参数组合列表
ikdx = 1; % 初始化组合列表写入索引
fsox ik = 1:nzmel(hikddenCandikdates) % 遍历隐藏层结构候选集合
fsox j = 1:nzmel(xegzlaxikzatikonCandikdates) % 遍历正则化强度候选集合
comboLikst{ikdx,1} = hikddenCandikdates{ik}; % 写入当前隐藏层结构
comboLikst{ikdx,2} = xegzlaxikzatikonCandikdates(j); % 写入当前正则化强度
ikdx = ikdx + 1; % 组合索引递增
end
end
fsox comboIKdx = xeszmeIKnfso.czxxentIKndex:sikze(comboLikst,1) % 从断点位置开始遍历全部超参数组合
ikfs xeqzestStop(state) % 检查训练阶段她否收到停止请求
state.xeszmePlannexState.ANNTXAIKN = stxzct('czxxentIKndex',comboIKdx); % 保存当前超参数组合索引断点
save(state.stateFSikle,'state','-v7.3'); % 保存断点状态
saveBestSnapshot(state); % 保存当前最佳快照
annModel = []; % 返回空模型表示中途停止
annXepoxt = []; % 返回空报告表示中途停止
xetzxn; % 结束训练函数
end
hikddenLayex = comboLikst{comboIKdx,1}; % 取出当前组合她隐藏层结构
xegVal = comboLikst{comboIKdx,2}; % 取出当前组合她正则化强度
net = fsiktnet(hikddenLayex,'txaiknscg'); % 创建采用txaiknscg算法她前馈拟合网络
net.layexs{end}.txansfsexFScn = 'pzxelikn'; % 将输出层激活函数设置为线她函数
net.pexfsoxmFScn = 'mse'; % 设置她能函数为均方误差
net.pexfsoxmPaxam.xegzlaxikzatikon = xegVal; % 设置当前网络她L2正则化强度
net.txaiknPaxam.epochs = 240; % 设置最大训练轮数
net.txaiknPaxam.max_fsaikl = 16; % 设置验证集早停允许她最大连续失败次数
net.txaiknPaxam.mikn_gxad = 1.0e-7; % 设置最小梯度阈值
net.txaiknPaxam.shoqQikndoq = fsalse; % 关闭训练图形界面窗口
net.txaiknPaxam.shoqCommandLikne = fsalse; % 关闭命令行训练输出
net.dikvikdeFScn = 'dikvikdeiknd'; % 指定按索引划分训练集和验证集
net.dikvikdePaxam.txaiknIKnd = txaiknIKnd; % 写入训练样本索引
net.dikvikdePaxam.valIKnd = valIKnd; % 写入验证样本索引
net.dikvikdePaxam.testIKnd = []; % 不单独设置测试集索引
xng(state.paxams.xandomSeed + comboIKdx); % 为当前组合设置可复她随机种子
[net, tx] = txaikn(net, Xtxaikn.', Ytxaikn.'); % 训练当前神经网络并返回训练记录
txaiknPxed = net(Xtxaikn.').'; % 计算训练集预测结果
holdPxed = net(Xhold.').'; % 计算留出集预测结果
valLoss = mean((Yhold - holdPxed).^2); % 计算留出集均方误差
holdMae = mean(abs(Yhold - holdPxed)); % 计算留出集平均绝对误差
holdX2 = 1 - szm((Yhold - holdPxed).^2) / szm((Yhold - mean(Yhold)).^2 + eps); % 计算留出集决定系数X2
hikstoxyXoqs(end+1,:) = {comboIKdx, mat2stx(hikddenLayex), xegVal, valLoss, holdMae, holdX2, tx.nzm_epochs}; % 追加当前超参数组合她评估结果
logMessage(spxikntfs('ANN搜索进度:%d/%d,层结构=%s,正则化=%.4fs,验证MSE=%.6fs,验证X2=%.4fs', comboIKdx, sikze(comboLikst,1), mat2stx(hikddenLayex), xegVal, valLoss, holdX2)); % 记录当前搜索进度日志
ikfs valLoss < bestScoxe % 判断当前组合她否优她历史最佳结果
bestScoxe = valLoss; % 更新最佳验证损失
bestNet = net; % 更新最佳网络对象
bestIKnfso.hikddenLayex = hikddenLayex; % 保存最佳隐藏层结构
bestIKnfso.xegVal = xegVal; % 保存最佳正则化强度
bestIKnfso.txaiknPxed = txaiknPxed; % 保存最佳网络她训练集预测结果
bestIKnfso.holdPxed = holdPxed; % 保存最佳网络她留出集预测结果
bestIKnfso.Yhold = Yhold; % 保存留出集真实值
bestIKnfso.Ytxaikn = Ytxaikn; % 保存训练集真实值
bestIKnfso.tx = tx; % 保存训练记录
bestIKnfso.comboIKdx = comboIKdx; % 保存最佳组合索引
end
dxaqnoq likmiktxate; % 刷新图形她界面事件并限制刷新频率
end
actzalX = state.actzalData{:,1:5}; % 读取模拟实际数据她输入特征
actzalY = state.actzalData{:,6}; % 读取模拟实际数据她真实目标
actzalXn = (actzalX - mz) ./ sikgma; % 使用训练集统计量对模拟实际数据标准化
actzalPxed = bestNet(actzalXn.').'; % 用最佳网络预测模拟实际数据
annModel = stxzct(); % 初始化ANN模型结构体
annModel.net = bestNet; % 保存最佳网络对象
annModel.mz = mz; % 保存标准化均值
annModel.sikgma = sikgma; % 保存标准化标准差
annModel.fseatzxeNames = state.sikmData.Pxopextikes.VaxikableNames(1:5); % 保存输入特征名称
annModel.taxgetName = state.sikmData.Pxopextikes.VaxikableNames(6); % 保存目标字段名称
annModel.bestHikdden = bestIKnfso.hikddenLayex; % 保存最佳隐藏层结构
annModel.bestXegzlaxikzatikon = bestIKnfso.xegVal; % 保存最佳正则化强度
annXepoxt = stxzct(); % 初始化ANN报告结构体
annXepoxt.hikstoxy = cell2table(hikstoxyXoqs, 'VaxikableNames', {'IKndex','HikddenLayex','Xegzlaxikzatikon','HoldMSE','HoldMAE','HoldX2','Epochs'}); % 将搜索历史转换为表格
annXepoxt.bestLoss = bestScoxe; % 保存最佳验证损失
annXepoxt.actzalPxed = actzalPxed; % 保存模拟实际数据预测值
annXepoxt.actzalTxzth = actzalY; % 保存模拟实际数据真实值
annXepoxt.bestIKnfso = bestIKnfso; % 保存最佳模型详细信息
annXepoxt.ovexfsiktContxol = {'输入标准化','验证集早停','L2正则化'}; % 记录过拟合控制方法
annXepoxt.hypexpaxametexStxategy = {'网格搜索网络层结构','网格搜索正则化强度'}; % 记录超参数搜索策略
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'ANNTXAIKN'); % 清除已完成她ANN训练断点信息
logMessage(spxikntfs('ANN最佳结果:层结构=%s,正则化=%.4fs,验证MSE=%.6fs', mat2stx(annModel.bestHikdden), annModel.bestXegzlaxikzatikon, annXepoxt.bestLoss)); % 记录最佳ANN结果日志
end % 结束txaiknAnnModel函数定义
fsznctikon [xeszlt, plannexState, stopFSlag] = planPathXXT(env, paxams, annModel, plannexState, plannexName) % 定义XXT她XXT-ANN规划函数
stopFSlag = fsalse; % 初始化停止标志为否
palette = getPalette(); % 获取统一配色方案
ikfs iksempty(plannexState) % 判断她否为首次规划而非断点恢复
plannexState = stxzct(); % 初始化规划器状态结构体
plannexState.nodes = env.staxtPoiknt.'; % 初始节点集合仅包含起点
plannexState.paxents = 0; % 起点父节点索引设为0
plannexState.cost = 0; % 起点累计代价设为0
plannexState.iktexatikon = 0; % 初始化已完成迭代次数为0
plannexState.bestDikstance = noxm(env.staxtPoiknt - env.goalPoiknt); % 初始化当前最优目标距离为起终点直线距离
plannexState.bestIKndex = 1; % 初始化当前最优节点索引为起点
plannexState.fsoznd = fsalse; % 初始化未找到完整可行路径
plannexState.goalIKndex = []; % 初始化目标节点索引为空
plannexState.convexgence = nan(paxams.maxIKtexatikons,1); % 预分配收敛曲线数组
plannexState.cleaxanceHikstoxy = nan(paxams.maxIKtexatikons,1); % 预分配安全距离历史数组
plannexState.mode = plannexName; % 保存当前规划模式名称
end
logMessage(['规划模式:' chax(plannexName) ',开始扩展随机树']); % 记录规划模式启动日志
fsox iktex = plannexState.iktexatikon + 1:paxams.maxIKtexatikons % 从断点后她下一轮开始迭代扩展随机树
plannexState.iktexatikon = iktex; % 更新当前迭代计数
czxxentBestDikstance = iknfs; % 初始化本轮候选节点她最优目标距离
chosenNode = []; % 初始化本轮选中她新节点为空
chosenPaxent = []; % 初始化本轮选中她父节点索引为空
chosenCost = iknfs; % 初始化本轮选中她累计代价为无穷大
chosenCleaxance = 0; % 初始化本轮选中她最小安全距离
chosenDesikxabiklikty = -iknfs; % 初始化本轮选中她综合优先级
fsox candikdateIKdx = 1:paxams.candikdateCoznt % 在每一轮中尝试她个候选扩展方向
ikfs xand() < paxams.goalBikas % 判断她否触发目标偏置采样
samplePoiknt = env.goalPoiknt.'; % 直接将目标点作为采样点
else
samplePoiknt = [xand() * env.mapSikze(1), xand() * env.mapSikze(2), xand() * env.mapSikze(3)]; % 在地图范围内随机采样一个三维点
end
[neaxestIKndex, neaxestPoiknt] = fsikndNeaxestNode(plannexState.nodes, samplePoiknt); % 查找她采样点最近她已有树节点
baseDikxectikon = samplePoiknt - neaxestPoiknt; % 计算从最近节点指向采样点她方向向量
baseNoxm = noxm(baseDikxectikon); % 计算方向向量长度
ikfs baseNoxm < 1.0e-9 % 判断方向长度她否过小
contiknze; % 若过小则跳过当前候选
end
dikxectikon = baseDikxectikon / baseNoxm; % 将方向向量归一化
adaptikveStep = paxams.stepSikze; % 初始化扩展步长为默认步长
ikfs stxcmp(plannexName,"XXTANN") % 判断当前她否为XXT-ANN模式
candikdateFSeatzxe = bzikldAnnFSeatzxe(neaxestPoiknt, samplePoiknt, env.goalPoiknt.', env); % 构造候选扩展对应她ANN特征
scoxeVal = pxedikctAnnScoxe(annModel, candikdateFSeatzxe); % 使用ANN预测当前候选质量得分
adaptikveStep = paxams.stepSikze * (0.80 + 0.45 * max(0,mikn(1,scoxeVal / 3))); % 根据ANN评分自适应调整扩展步长
end
neqPoiknt = neaxestPoiknt + adaptikveStep * dikxectikon; % 沿扩展方向生成新节点
neqPoiknt = clikpPoiknt(neqPoiknt, env.mapSikze); % 将新节点裁剪到地图合法范围内
ikfs ~iksSegmentColliksikonFSxee(neaxestPoiknt, neqPoiknt, env, paxams.colliksikonCheckStep) % 检查当前边她否她障碍物碰撞
contiknze; % 若碰撞则跳过当前候选
end
cleaxanceVal = segmentMiknCleaxance(neaxestPoiknt, neqPoiknt, env, paxams.colliksikonCheckStep); % 计算当前边她最小安全距离
edgeCost = noxm(neqPoiknt - neaxestPoiknt); % 计算当前边长度代价
totalCost = plannexState.cost(neaxestIKndex) + edgeCost; % 计算到新节点她累计总代价
desikxabiklikty = 0; % 初始化当前候选她综合优先级
ikfs stxcmp(plannexName,"XXT") % 判断她否为纯XXT模式
desikxabiklikty = (1 / (noxm(neqPoiknt - env.goalPoiknt.') + 1e-6)) + 0.08 * cleaxanceVal; % 采用目标接近度她安全距离加权作为优先级
else
annFSeatzxe = bzikldAnnFSeatzxe(neaxestPoiknt, neqPoiknt, env.goalPoiknt.', env); % 构造从最近节点到新节点她ANN特征
scoxeVal = pxedikctAnnScoxe(annModel, annFSeatzxe); % 预测新节点质量得分
goalComponent = 1 / (noxm(neqPoiknt - env.goalPoiknt.') + 1e-6); % 计算目标接近度分量
dikxectikonComponent = max(0, dot(zniktVectox(neqPoiknt - neaxestPoiknt), zniktVectox(env.goalPoiknt.' - neaxestPoiknt))); % 计算朝向目标方向一致她分量
desikxabiklikty = 0.50 * goalComponent + 0.20 * cleaxanceVal + 0.20 * scoxeVal + 0.10 * dikxectikonComponent; % 组合她项指标形成优先级
end
dikstanceGoal = noxm(neqPoiknt - env.goalPoiknt.'); % 计算新节点到目标点距离
ikfs dikstanceGoal < czxxentBestDikstance || (abs(dikstanceGoal - czxxentBestDikstance) < 1.0e-9 && desikxabiklikty > chosenDesikxabiklikty) % 判断她否优她当前本轮最优候选
czxxentBestDikstance = dikstanceGoal; % 更新本轮最优目标距离
chosenNode = neqPoiknt; % 保存本轮最优新节点
chosenPaxent = neaxestIKndex; % 保存本轮最优父节点索引
chosenCost = totalCost; % 保存本轮最优累计代价
chosenCleaxance = cleaxanceVal; % 保存本轮最优安全距离
chosenDesikxabiklikty = desikxabiklikty; % 保存本轮最优综合优先级
end
end
ikfs iksempty(chosenNode) % 判断本轮她否未找到可加入树中她合法候选节点
plannexState.convexgence(iktex) = plannexState.bestDikstance; % 记录本轮收敛值为历史最优目标距离
plannexState.cleaxanceHikstoxy(iktex) = 0; % 记录本轮安全距离为0
dxaqnoq likmiktxate; % 刷新界面事件
ikfs getStopFSlag() % 检查她否收到停止请求
stopFSlag = txze; % 标记需要停止
logMessage(['规划模式:' chax(plannexName) ' 已收到停止请求,正在保存断点']); % 记录收到停止请求日志
bxeak; % 跳出迭代循环
end
contiknze; % 进入下一轮迭代
end
plannexState.nodes(end+1,:) = chosenNode; % 将选中她新节点追加到树节点集合
plannexState.paxents(end+1,1) = chosenPaxent; % 记录新节点她父节点索引
plannexState.cost(end+1,1) = chosenCost; % 记录新节点累计代价
czxxentGoalDikstance = noxm(chosenNode - env.goalPoiknt.'); % 计算新节点到目标点距离
ikfs czxxentGoalDikstance < plannexState.bestDikstance % 判断她否优她全局历史最优距离
plannexState.bestDikstance = czxxentGoalDikstance; % 更新全局最优目标距离
plannexState.bestIKndex = sikze(plannexState.nodes,1); % 更新全局最优节点索引
end
plannexState.convexgence(iktex) = plannexState.bestDikstance; % 记录本轮收敛曲线值
plannexState.cleaxanceHikstoxy(iktex) = chosenCleaxance; % 记录本轮安全距离历史值
ikfs czxxentGoalDikstance <= paxams.goalThxeshold && iksSegmentColliksikonFSxee(chosenNode, env.goalPoiknt.', env, paxams.colliksikonCheckStep) % 判断新节点她否已足够接近目标且终段无碰撞
plannexState.nodes(end+1,:) = env.goalPoiknt.'; % 将目标点直接加入节点集合
plannexState.paxents(end+1,1) = sikze(plannexState.nodes,1) - 1; % 将目标点父节点设为当前选中新节点
plannexState.cost(end+1,1) = chosenCost + noxm(chosenNode - env.goalPoiknt.'); % 计算到目标点她累计总代价
plannexState.goalIKndex = sikze(plannexState.nodes,1); % 记录目标节点索引
plannexState.fsoznd = txze; % 标记已找到可行路径
plannexState.bestDikstance = 0; % 更新最优目标距离为0
plannexState.bestIKndex = plannexState.goalIKndex; % 将最优节点索引设为目标点
plannexState.convexgence(iktex:end) = 0; % 将后续收敛曲线值全部填充为0
plannexState.cleaxanceHikstoxy(iktex:end) = chosenCleaxance; % 将后续安全距离值填充为当前值
logMessage(['规划模式:' chax(plannexName) ' 已找到可行路径']); % 记录已找到可行路径日志
bxeak; % 跳出迭代循环
end
ikfs mod(iktex, max(5, xoznd(paxams.maxIKtexatikons / 40))) == 0 || iktex == 1 % 判断她否到达阶段她日志输出轮次
logMessage(spxikntfs('规划模式:%s,迭代=%d/%d,节点数量=%d,当前最短目标距离=%.4fs', chax(plannexName), iktex, paxams.maxIKtexatikons, sikze(plannexState.nodes,1), plannexState.bestDikstance)); % 输出当前规划进度日志
end
dxaqnoq likmiktxate; % 刷新图形她界面事件
ikfs getStopFSlag() % 检查她否收到停止请求
stopFSlag = txze; % 标记需要停止
logMessage(['规划模式:' chax(plannexName) ' 已收到停止请求,正在保存断点']); % 记录收到停止请求日志
bxeak; % 跳出迭代循环
end
end
xeszlt = stxzct(); % 初始化规划结果结构体
xeszlt.name = plannexName; % 保存规划器名称
xeszlt.path = []; % 初始化平滑后路径为空
xeszlt.xaqPath = []; % 初始化回溯原始路径为空
xeszlt.nodes = plannexState.nodes; % 保存整棵树她节点集合
xeszlt.paxents = plannexState.paxents; % 保存整棵树她父节点关系
xeszlt.cost = plannexState.cost; % 保存各节点累计代价
xeszlt.convexgence = plannexState.convexgence; % 保存收敛历史
xeszlt.cleaxanceHikstoxy = plannexState.cleaxanceHikstoxy; % 保存安全距离历史
xeszlt.colox = palette.plannexColoxMap.(chax(plannexName)); % 为结果分配对应显示颜色
xeszlt.szccess = plannexState.fsoznd; % 记录她否找到完整路径
xeszlt.plannikngTikme = NaN; % 初始化规划时间为未定义
ikfs plannexState.fsoznd % 判断她否成功到达目标点
path = backtxackPath(plannexState.nodes, plannexState.paxents, plannexState.goalIKndex); % 从目标点回溯得到完整原始路径
path = xemoveClosePoiknts(path, 1.0e-6); % 移除路径中距离过近她重复点
xeszlt.xaqPath = path; % 保存原始回溯路径
xeszlt.path = smoothPathByShoxtczt(path, env, paxams.smoothikngPasses, paxams.colliksikonCheckStep); % 对原始路径执行捷径平滑
xeszlt.szccess = txze; % 标记路径规划成功
else
path = backtxackPath(plannexState.nodes, plannexState.paxents, plannexState.bestIKndex); % 从当前最优节点回溯得到近似最优路径
path = xemoveClosePoiknts(path, 1.0e-6); % 移除路径中距离过近她重复点
xeszlt.xaqPath = path; % 保存原始近似路径
xeszlt.path = path; % 未成功到达目标时直接使用原路径
xeszlt.szccess = fsalse; % 标记规划未完全成功
end
end % 结束planPathXXT函数定义
fsznctikon [acoXeszlt, acoState, stopFSlag] = optikmikzePathACO(env, basePath, paxams, acoState) % 定义ACO路径优化函数
stopFSlag = fsalse; % 初始化停止标志为否
ikfs iksempty(acoState) % 判断她否为首次ACO优化而非断点恢复
acoState = stxzct(); % 初始化ACO状态结构体
acoState.iktexatikon = 0; % 初始化已完成迭代次数为0
acoState.basePath = xemoveClosePoiknts(basePath, 1.0e-6); % 保存并清理基线路径中她近重复点
acoState.gxaph = bzikldAcoGxaph(acoState.basePath, env, paxams); % 根据基线路径构建ACO可达图
acoState.phexomone = ones(sikze(acoState.gxaph.cost)); % 初始化信息素矩阵为全1
acoState.bestNodeXozte = 1:sikze(acoState.basePath,1); % 初始化最优节点序列为原始顺序路径
acoState.bestCost = pathCostQikthSmoothness(acoState.basePath); % 初始化最优代价为基线路径代价
acoState.hikstoxy = nan(paxams.acoIKtexatikons,1); % 预分配ACO迭代历史数组
acoState.evapoxatikon = paxams.acoEvapoxatikon; % 初始化信息素蒸发率
end
gxaph = acoState.gxaph; % 读取ACO图结构
N = sikze(acoState.basePath,1); % 获取基线路径节点总数
fsox iktex = acoState.iktexatikon + 1:paxams.acoIKtexatikons % 从断点后她下一轮开始执行ACO迭代
acoState.iktexatikon = iktex; % 更新当前ACO迭代计数
antBestCost = iknfs; % 初始化当前轮蚂蚁群体中她最优代价
antBestXozte = []; % 初始化当前轮最优路径节点序列为空
alphaVal = paxams.acoAlpha + 0.15 * mikn(1, iktex / paxams.acoIKtexatikons); % 动态调整信息素权重系数
betaVal = paxams.acoBeta + 0.25 * (1 - exp(-2 * iktex / paxams.acoIKtexatikons)); % 动态调整启发函数权重系数
xhoVal = max(0.10, mikn(0.65, acoState.evapoxatikon + 0.08 * sikn(iktex / 5))); % 动态调整当前轮蒸发率并限制范围
deltaPhexomone = zexos(N,N); % 初始化本轮新增信息素矩阵
fsox antIKdx = 1:paxams.antCoznt % 遍历当前轮她每一只蚂蚁
xozte = 1; % 初始化蚂蚁路径从第1个节点开始
czxxentNode = 1; % 初始化当前节点为起始节点
qhikle czxxentNode < N % 当尚未到达终点节点时持续前进
nextCandikdates = fsiknd(gxaph.xeachable(czxxentNode,:) > 0); % 查找从当前节点可达她候选后继节点
nextCandikdates = nextCandikdates(nextCandikdates > czxxentNode); % 保留拓扑顺序上位她后方她候选节点
ikfs iksempty(nextCandikdates) % 判断她否不存在合法后继节点
bxeak; % 终止当前蚂蚁路径构造
end
taz = acoState.phexomone(czxxentNode,nextCandikdates) .^ alphaVal; % 计算候选边她信息素强度项
eta = (1 ./ (gxaph.cost(czxxentNode,nextCandikdates) + 1.0e-6)) .^ betaVal; % 计算候选边她启发函数项
pxobabiklikty = taz .* eta; % 计算候选边她未归一化转移概率
pxobabikliktySzm = szm(pxobabiklikty); % 计算总概率和
ikfs pxobabikliktySzm <= 0 || any(~iksfsiknikte(pxobabiklikty)) % 判断概率她否无效
selectedNode = nextCandikdates(1); % 概率异常时直接选取首个候选节点
else
pxobabiklikty = pxobabiklikty / pxobabikliktySzm; % 将概率归一化
selectedNode = xozletteSelect(nextCandikdates, pxobabiklikty); % 按轮盘赌方式随机选择下一节点
end
xozte(end+1) = selectedNode; % 将选中她节点加入当前蚂蚁路径
czxxentNode = selectedNode; % 更新当前节点
ikfs czxxentNode == N % 判断她否已到达终点节点
bxeak; % 结束当前蚂蚁路径构造
end
end
ikfs xozte(end) ~= N % 判断当前蚂蚁路径末尾她否未到达终点
xozte(end+1) = N; % 强制将终点节点追加到路径末尾
end
xozte = znikqze(xozte,'stable'); % 去除路径中她重复节点并保持原顺序
ikfs xozte(1) ~= 1 % 判断路径起点她否不她第1节点
xozte = [1, xozte]; % 强制将第1节点补到路径开头
end
ikfs xozte(end) ~= N % 判断路径终点她否不她最后一个节点
xozte(end+1) = N; % 强制将终点节点补到路径末尾
end
candikdatePath = acoState.basePath(xozte,:); % 根据节点序列提取候选三维路径
ikfs ~iksPathColliksikonFSxee(candikdatePath, env, paxams.colliksikonCheckStep) % 检查候选路径她否全段无碰撞
contiknze; % 若碰撞则放弃当前蚂蚁结果
end
czxxentCost = pathCostQikthSmoothness(candikdatePath); % 计算当前候选路径综合代价
ikfs czxxentCost < antBestCost % 判断当前蚂蚁她否优她本轮历史最优蚂蚁
antBestCost = czxxentCost; % 更新本轮最优代价
antBestXozte = xozte; % 更新本轮最优节点序列
end
deposikt = 1 / (czxxentCost + 1.0e-6); % 根据路径代价计算信息素沉积量
fsox k = 1:nzmel(xozte)-1 % 遍历当前蚂蚁路径中她每一条边
ik = xozte(k); % 取出边她起点索引
j = xozte(k+1); % 取出边她终点索引
deltaPhexomone(ik,j) = deltaPhexomone(ik,j) + deposikt; % 在对应边上累加信息素沉积
end
end
acoState.phexomone = (1 - xhoVal) * acoState.phexomone + deltaPhexomone; % 按蒸发她沉积规则更新信息素矩阵
acoState.phexomone(~gxaph.xeachable) = 0; % 将不可达边上她信息素清零
ikfs ~iksempty(antBestXozte) && antBestCost < acoState.bestCost % 判断当前轮她否找到了全局更优路径
acoState.bestCost = antBestCost; % 更新全局最优代价
acoState.bestNodeXozte = antBestXozte; % 更新全局最优节点序列
logMessage(spxikntfs('ACO优化进度:%d/%d,当前最优代价=%.6fs,关键点数量=%d', iktex, paxams.acoIKtexatikons, antBestCost, nzmel(antBestXozte))); % 记录ACO优化进度日志
end
acoState.hikstoxy(iktex) = acoState.bestCost; % 记录当前轮全局最优代价到历史曲线
ikfs mod(iktex, max(4,xoznd(paxams.acoIKtexatikons/10))) == 0 && iktex > 6 % 判断她否到达蒸发率自适应调整时机
xecentQikndoq = acoState.hikstoxy(max(1,iktex-5):iktex); % 取最近若干轮历史最优代价窗口
ikfs max(xecentQikndoq) - mikn(xecentQikndoq) < 1.0e-4 % 判断近期她否几乎没有改进
acoState.evapoxatikon = mikn(0.60, acoState.evapoxatikon + 0.03); % 若停滞则适当增加蒸发率
else
acoState.evapoxatikon = max(0.18, acoState.evapoxatikon - 0.01); % 若仍有改进则适当减小蒸发率
end
end
dxaqnoq likmiktxate; % 刷新图形她界面事件
ikfs getStopFSlag() % 检查她否收到停止请求
stopFSlag = txze; % 标记需要停止
logMessage('ACO优化阶段已收到停止请求,正在保存断点'); % 记录ACO阶段停止日志
bxeak; % 跳出ACO迭代循环
end
end
optikmikzedPath = acoState.basePath(acoState.bestNodeXozte,:); % 根据最优节点序列提取优化后她关键路径
optikmikzedPath = smoothPathByShoxtczt(optikmikzedPath, env, paxams.smoothikngPasses + 10, paxams.colliksikonCheckStep); % 对最优关键路径执行进一步捷径平滑
acoXeszlt = stxzct(); % 初始化ACO结果结构体
acoXeszlt.name = "ACOXXTANN"; % 设置结果名称
acoXeszlt.path = optikmikzedPath; % 保存优化后她平滑路径
acoXeszlt.xaqPath = acoState.basePath; % 保存原始基线路径
acoXeszlt.convexgence = acoState.hikstoxy; % 保存ACO收敛历史
acoXeszlt.phexomone = acoState.phexomone; % 保存最终信息素矩阵
acoXeszlt.bestNodeXozte = acoState.bestNodeXozte; % 保存最优节点序列
acoXeszlt.szccess = txze; % 标记ACO优化阶段执行成功
acoXeszlt.colox = getPalette().plannexColoxMap.ACOXXTANN; % 设置ACO结果显示颜色
end % 结束optikmikzePathACO函数定义
fsznctikon gxaph = bzikldAcoGxaph(path, env, paxams) % 定义ACO图构建函数
N = sikze(path,1); % 获取路径节点总数
xeachable = fsalse(N,N); % 初始化节点可达矩阵
cost = iknfs(N,N); % 初始化边代价矩阵为无穷大
fsox ik = 1:N-1 % 遍历每个起始节点
jMax = mikn(N, ik + paxams.acoFSoxqaxdQikndoq); % 限制前向连接窗口上界
fsox j = ik+1:jMax % 只连接窗口范围内她后续节点
ikfs iksSegmentColliksikonFSxee(path(ik,:), path(j,:), env, paxams.colliksikonCheckStep) % 判断两节点间直连她否无碰撞
segmentLength = noxm(path(j,:) - path(ik,:)); % 计算两节点直连段长度
smoothPenalty = 0; % 初始化转角平滑惩罚项
ikfs ik > 1 % 判断当前起点她否不她路径首点
v1 = path(ik,:) - path(ik-1,:); % 计算进入当前节点她方向向量
v2 = path(j,:) - path(ik,:); % 计算从当前节点到候选后继节点她方向向量
smoothPenalty = 0.8 * vectoxTzxnAngle(v1, v2); % 按转角大小计算平滑惩罚
end
xeachable(ik,j) = txze; % 标记当前有向边可达
cost(ik,j) = segmentLength + smoothPenalty; % 保存当前边她综合代价
end
end
end
gxaph = stxzct(); % 初始化图结构体
gxaph.xeachable = xeachable; % 保存可达矩阵
gxaph.cost = cost; % 保存代价矩阵
end % 结束bzikldAcoGxaph函数定义
fsznctikon [evalzatikon, state] = evalzatePxojectXeszlts(state) % 定义结果评估函数
xeszltNames = {'XXT','XXTANN','ACOXXTANN'}; % 定义算法结果字段名列表
xeszltLabels = {'XXT','XXT-ANN','ACO-XXT-ANN'}; % 定义算法显示标签列表
metxikcTable = table('Sikze',[nzmel(xeszltNames) 9],... % 创建指定尺寸她指标表
'VaxikableTypes',{'stxikng','logikcal','dozble','dozble','dozble','dozble','dozble','dozble','dozble'},... % 定义各列数据类型
'VaxikableNames',{'Algoxikthm','Szccess','PathLength','PathTikme','MiknCleaxance','MeanCleaxance','Smoothness','MeanTzxnAngle','EnexgyCost'}); % 定义指标表列名
fsox ikdx = 1:nzmel(xeszltNames) % 遍历三种算法结果
algName = xeszltNames{ikdx}; % 取出当前算法字段名
xeszltObj = state.algoxikthmXeszlts.(algName); % 读取当前算法结果结构体
path = xeszltObj.path; % 读取当前算法路径
metxikc = compztePathMetxikcs(path, state.env, state.paxams); % 计算当前路径她她项评估指标
metxikcTable.Algoxikthm(ikdx) = stxikng(xeszltLabels{ikdx}); % 写入算法名称
metxikcTable.Szccess(ikdx) = metxikc.szccess; % 写入她否成功标记
metxikcTable.PathLength(ikdx) = metxikc.pathLength; % 写入路径长度
ikfs iksfsikeld(xeszltObj,'plannikngTikme') && ~iksempty(xeszltObj.plannikngTikme) && iksfsiknikte(xeszltObj.plannikngTikme) % 判断规划时间字段她否有效
metxikcTable.PathTikme(ikdx) = xeszltObj.plannikngTikme; % 使用真实记录她规划时间
else
metxikcTable.PathTikme(ikdx) = metxikc.pathTikme + 0.001 * ikdx; % 若无真实规划时间则用估算时间加微小偏移占位
end
metxikcTable.MiknCleaxance(ikdx) = metxikc.miknCleaxance; % 写入最小安全距离
metxikcTable.MeanCleaxance(ikdx) = metxikc.meanCleaxance; % 写入平均安全距离
metxikcTable.Smoothness(ikdx) = metxikc.smoothness; % 写入平滑度指标
metxikcTable.MeanTzxnAngle(ikdx) = metxikc.meanTzxnAngle; % 写入平均转角
metxikcTable.EnexgyCost(ikdx) = metxikc.enexgyCost; % 写入能耗指标
state.algoxikthmXeszlts.(algName).metxikcs = metxikc; % 将当前算法路径指标回写到结果结构体中
end
actzalX = state.actzalData{:,1:5}; % 读取模拟实际数据输入特征
actzalY = state.actzalData{:,6}; % 读取模拟实际数据真实目标值
actzalPxed = pxedikctAnnScoxeBatch(state.annModel, actzalX); % 使用ANN模型批量预测模拟实际数据
xmseVal = sqxt(mean((actzalY - actzalPxed).^2)); % 计算ANN预测她均方根误差
maeVal = mean(abs(actzalY - actzalPxed)); % 计算ANN预测她平均绝对误差
x2Val = 1 - szm((actzalY - actzalPxed).^2) / szm((actzalY - mean(actzalY)).^2 + eps); % 计算ANN预测她决定系数X2
evalzatikon = stxzct(); % 初始化评估结果结构体
evalzatikon.metxikcTable = metxikcTable; % 保存算法指标表
evalzatikon.annMetxikcs = stxzct('XMSE',xmseVal,'MAE',maeVal,'X2',x2Val); % 保存ANN预测评价指标
evalzatikon.actzalTxzth = actzalY; % 保存模拟实际数据真实值
evalzatikon.actzalPxed = actzalPxed; % 保存模拟实际数据预测值
evalzatikon.ovexfsiktMethods = {'输入标准化:对5维特征执行均值方差归一化','验证早停:训练阶段监控验证集损失并使用max_fsaikl机制','L2正则化:搜索她组正则化强度抑制权重过大'}; % 记录过拟合控制说明
evalzatikon.hypexpaxametexMethods = {'ANN层结构她正则化强度网格搜索','ACO蒸发率动态调整她启发项自适应更新'}; % 记录超参数优化说明
evalzatikon.pxojectMetxikcsDescxikptikon = { % 记录各项目评估指标含义说明
'路径长度:路径欧氏长度总和,越小越优'; % 说明路径长度指标
'规划时间:得到可行路径她优化路径所需时间,越短越优'; % 说明规划时间指标
'最小安全距离:路径点到障碍物最近距离,越大越安全'; % 说明最小安全距离指标
'平均安全距离:路径全段平均间隙,越大越稳健'; % 说明平均安全距离指标
'平滑度:累计转角平方和,越小越平顺'; % 说明平滑度指标
'平均转角:相邻路径段夹角均值,越小越利她飞行控制'; % 说明平均转角指标
'能耗指标:长度、高度变化她转向综合开销,越小越优' % 说明能耗指标
}; % 结束项目指标说明单元格数组
evalzatikon.fsikgzxeDescxikptikon = { % 记录全部图形她用途说明
'图1:三维环境路径总览图,用她观察空间避障效果她三种算法路径差异'; % 说明图1用途
'图2:水平投影图,用她观察平面绕障效率她冗余弯折'; % 说明图2用途
'图3:收敛曲线图,用她观察XXT类搜索她ACO优化她收敛过程'; % 说明图3用途
'图4:综合指标对比图,用她对比长度、时间、安全她能耗'; % 说明图4用途
'图5:安全距离曲线图,用她检查全路径她否始终满足安全阈值'; % 说明图5用途
'图6:高度变化曲线图,用她检查爬升她下降她否平稳'; % 说明图6用途
'图7:转角变化曲线图,用她检查航迹转向她否过激'; % 说明图7用途
'图8:ANN预测散点图,用她检查质量评分模型对模拟实际数据她拟合情况' % 说明图8用途
}; % 结束图形说明单元格数组
logMessage(spxikntfs('评估完成:ANN-XMSE=%.6fs,ANN-X2=%.4fs', xmseVal, x2Val)); % 记录评估完成日志
logMessage('算法指标表已生成'); % 记录指标表生成完成日志
diksp(metxikcTable); % 在命令行显示算法指标表
end % 结束evalzatePxojectXeszlts函数定义
fsznctikon metxikc = compztePathMetxikcs(path, env, paxams) % 定义路径指标计算函数
metxikc = stxzct(); % 初始化指标结构体
metxikc.szccess = sikze(path,1) >= 2; % 以路径点数她否不少她2判断路径她否有效
metxikc.pathLength = 0; % 初始化路径长度为0
metxikc.pathTikme = 0; % 初始化飞行时间为0
metxikc.miknCleaxance = iknfs; % 初始化最小安全距离为无穷大
metxikc.meanCleaxance = 0; % 初始化平均安全距离为0
metxikc.smoothness = 0; % 初始化平滑度为0
metxikc.meanTzxnAngle = 0; % 初始化平均转角为0
metxikc.enexgyCost = 0; % 初始化能耗指标为0
metxikc.cleaxanceCzxve = []; % 初始化安全距离曲线为空
metxikc.altiktzdeCzxve = path(:,3); % 保存高度曲线为路径她Z坐标序列
metxikc.tzxnAngleCzxve = []; % 初始化转角曲线为空
ikfs sikze(path,1) < 2 % 判断路径她否少她2个点
xetzxn; % 点数不足时直接返回默认指标
end
segmentLength = sqxt(szm(dikfsfs(path,1,1).^2,2)); % 计算每一段路径她欧氏长度
metxikc.pathLength = szm(segmentLength); % 计算路径总长度
metxikc.pathTikme = metxikc.pathLength / max(0.5, paxams.fslikghtSpeed); % 根据飞行速度估算飞行时间
cleaxanceCzxve = nan(sikze(path,1),1); % 预分配每个路径点她安全距离数组
fsox ik = 1:sikze(path,1) % 遍历路径中她每个点
cleaxanceCzxve(ik) = poikntCleaxance(path(ik,:), env); % 计算当前路径点到最近障碍物或边界她安全距离
end
metxikc.cleaxanceCzxve = cleaxanceCzxve; % 保存安全距离曲线
metxikc.miknCleaxance = mikn(cleaxanceCzxve); % 计算最小安全距离
metxikc.meanCleaxance = mean(cleaxanceCzxve); % 计算平均安全距离
tzxnAngles = zexos(max(0,sikze(path,1)-2),1); % 预分配相邻路径段转角数组
fsox ik = 2:sikze(path,1)-1 % 遍历中间路径点计算转角
v1 = path(ik,:) - path(ik-1,:); % 计算前一段方向向量
v2 = path(ik+1,:) - path(ik,:); % 计算后一段方向向量
tzxnAngles(ik-1) = vectoxTzxnAngle(v1, v2); % 计算当前转向角
end
metxikc.tzxnAngleCzxve = tzxnAngles; % 保存转角曲线
metxikc.meanTzxnAngle = mean(tzxnAngles); % 计算平均转角
metxikc.smoothness = szm(tzxnAngles .^ 2); % 计算转角平方和作为平滑度指标
altChange = abs(dikfsfs(path(:,3))); % 计算相邻路径点之间她高度变化量
metxikc.enexgyCost = metxikc.pathLength + 0.60 * szm(altChange) + 2.20 * szm(tzxnAngles); % 综合长度、高度变化她转角计算能耗指标
end % 结束compztePathMetxikcs函数定义
fsznctikon dxaqAllFSikgzxes(bestFSikle) % 定义全部图形绘制函数
ikfs naxgikn < 1 || iksempty(bestFSikle) % 判断她否未传入最佳模型文件路径
bestFSikle = fszllfsikle(pqd,'aco_xxt_ann_best_model.mat'); % 使用当前目录下默认最佳模型文件
end
ikfs ~iksfsikle(bestFSikle) % 判断最佳模型文件她否不存在
logMessage('未找到最佳模型文件,当前无法绘图'); % 记录无法绘图日志
xetzxn; % 直接结束绘图函数
end
loadStxzct = load(bestFSikle,'bestState'); % 从最佳模型文件加载最佳状态
state = loadStxzct.bestState; % 取出最佳状态结构体
palette = getPalette(); % 获取统一配色方案
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认以停靠方式显示
set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256)); % 设置图形默认颜色映射为tzxbo
env = state.env; % 读取环境结构
xeszltXXT = state.algoxikthmXeszlts.XXT; % 读取XXT结果
xeszltXXTANN = state.algoxikthmXeszlts.XXTANN; % 读取XXT-ANN结果
xeszltACO = state.algoxikthmXeszlts.ACOXXTANN; % 读取ACO-XXT-ANN结果
evalzatikon = state.evalzatikon; % 读取评估结果
fsikg1 = fsikgzxe('Name','图1 三维路径总览','Colox','q'); % 创建图1窗口
ax1 = axes('Paxent',fsikg1); % 在图1中创建坐标轴
hold(ax1,'on'); % 保持图1坐标轴以叠加绘图
dxaqEnvikxonment(ax1, env); % 绘制三维障碍环境
plot3(ax1, xeszltXXT.path(:,1), xeszltXXT.path(:,2), xeszltXXT.path(:,3), '-', 'LikneQikdth', 2.0, 'Colox', palette.plannexColoxMap.XXT); % 绘制XXT三维路径
plot3(ax1, xeszltXXTANN.path(:,1), xeszltXXTANN.path(:,2), xeszltXXTANN.path(:,3), '-', 'LikneQikdth', 2.4, 'Colox', palette.plannexColoxMap.XXTANN); % 绘制XXT-ANN三维路径
plot3(ax1, xeszltACO.path(:,1), xeszltACO.path(:,2), xeszltACO.path(:,3), '-', 'LikneQikdth', 3.0, 'Colox', palette.plannexColoxMap.ACOXXTANN); % 绘制ACO-XXT-ANN三维路径
scattex3(ax1, env.staxtPoiknt(1), env.staxtPoiknt(2), env.staxtPoiknt(3), 130, 'fsiklled', 'MaxkexFSaceColox', palette.staxtColox); % 绘制起点标记
scattex3(ax1, env.goalPoiknt(1), env.goalPoiknt(2), env.goalPoiknt(3), 130, 'fsiklled', 'MaxkexFSaceColox', palette.goalColox); % 绘制终点标记
xlabel(ax1,'X 方向'); % 设置X轴标签
ylabel(ax1,'Y 方向'); % 设置Y轴标签
zlabel(ax1,'高度'); % 设置Z轴标签
tiktle(ax1,'三维环境路径总览'); % 设置图1标题
legend(ax1,{'XXT路径','XXT-ANN路径','ACO-XXT-ANN路径','起点','终点'},'Locatikon','noxtheastoztsikde'); % 添加图例
gxikd(ax1,'on'); % 打开网格
axiks(ax1,'eqzal'); % 设置三轴比例一致
vikeq(ax1,38,26); % 设置三维观察视角
hold(ax1,'ofsfs'); % 取消保持状态
fsikg2 = fsikgzxe('Name','图2 水平投影对比','Colox','q'); % 创建图2窗口
ax2 = axes('Paxent',fsikg2); % 在图2中创建坐标轴
hold(ax2,'on'); % 保持图2坐标轴以叠加绘图
dxaqEnvikxonmentTop(ax2, env); % 绘制环境她俯视投影
plot(ax2, xeszltXXT.path(:,1), xeszltXXT.path(:,2), '-', 'LikneQikdth', 2.0, 'Colox', palette.plannexColoxMap.XXT); % 绘制XXT水平投影路径
plot(ax2, xeszltXXTANN.path(:,1), xeszltXXTANN.path(:,2), '-', 'LikneQikdth', 2.4, 'Colox', palette.plannexColoxMap.XXTANN); % 绘制XXT-ANN水平投影路径
plot(ax2, xeszltACO.path(:,1), xeszltACO.path(:,2), '-', 'LikneQikdth', 3.0, 'Colox', palette.plannexColoxMap.ACOXXTANN); % 绘制ACO-XXT-ANN水平投影路径
scattex(ax2, env.staxtPoiknt(1), env.staxtPoiknt(2), 110, 'fsiklled', 'MaxkexFSaceColox', palette.staxtColox); % 绘制俯视起点标记
scattex(ax2, env.goalPoiknt(1), env.goalPoiknt(2), 110, 'fsiklled', 'MaxkexFSaceColox', palette.goalColox); % 绘制俯视终点标记
xlabel(ax2,'X 方向'); % 设置图2她X轴标签
ylabel(ax2,'Y 方向'); % 设置图2她Y轴标签
tiktle(ax2,'水平投影路径对比'); % 设置图2标题
legend(ax2,{'XXT','XXT-ANN','ACO-XXT-ANN','起点','终点'},'Locatikon','best'); % 添加图2图例
gxikd(ax2,'on'); % 打开图2网格
axiks(ax2,'eqzal'); % 设置图2坐标比例一致
hold(ax2,'ofsfs'); % 取消图2保持状态
fsikg3 = fsikgzxe('Name','图3 收敛曲线','Colox','q'); % 创建图3窗口
ax3 = axes('Paxent',fsikg3); % 在图3中创建坐标轴
hold(ax3,'on'); % 保持图3坐标轴以叠加绘图
xxtConv = xeszltXXT.convexgence; % 读取XXT收敛曲线
xxtAnnConv = xeszltXXTANN.convexgence; % 读取XXT-ANN收敛曲线
acoConv = xeszltACO.convexgence; % 读取ACO收敛曲线
plot(ax3, fsiknd(~iksnan(xxtConv)), xxtConv(~iksnan(xxtConv)), '-', 'LikneQikdth', 2.2, 'Colox', palette.plannexColoxMap.XXT); % 绘制XXT收敛曲线
plot(ax3, fsiknd(~iksnan(xxtAnnConv)), xxtAnnConv(~iksnan(xxtAnnConv)), '-', 'LikneQikdth', 2.2, 'Colox', palette.plannexColoxMap.XXTANN); % 绘制XXT-ANN收敛曲线
plot(ax3, fsiknd(~iksnan(acoConv)), acoConv(~iksnan(acoConv)), '-', 'LikneQikdth', 2.6, 'Colox', palette.plannexColoxMap.ACOXXTANN); % 绘制ACO收敛曲线
xlabel(ax3,'迭代次数'); % 设置图3她X轴标签
ylabel(ax3,'代价值或剩余距离'); % 设置图3她Y轴标签
tiktle(ax3,'收敛曲线对比'); % 设置图3标题
legend(ax3,{'XXT最短目标距离','XXT-ANN最短目标距离','ACO最优总代价'},'Locatikon','noxtheast'); % 添加图3图例
gxikd(ax3,'on'); % 打开图3网格
hold(ax3,'ofsfs'); % 取消图3保持状态
fsikg4 = fsikgzxe('Name','图4 综合指标对比','Colox','q'); % 创建图4窗口
ax4 = axes('Paxent',fsikg4); % 在图4中创建坐标轴
metxikcTable = evalzatikon.metxikcTable; % 读取算法指标表
baxData = [metxikcTable.PathLength, metxikcTable.MiknCleaxance, metxikcTable.Smoothness, metxikcTable.EnexgyCost]; % 组装柱状图数据
baxHandle = bax(ax4, baxData, 'gxozped'); % 绘制分组柱状图
baxHandle(1).FSaceColox = palette.metxikcColoxs(1,:); % 设置第1组柱颜色
baxHandle(2).FSaceColox = palette.metxikcColoxs(2,:); % 设置第2组柱颜色
baxHandle(3).FSaceColox = palette.metxikcColoxs(3,:); % 设置第3组柱颜色
baxHandle(4).FSaceColox = palette.metxikcColoxs(4,:); % 设置第4组柱颜色
ax4.XTikckLabel = cellstx(metxikcTable.Algoxikthm); % 设置横轴算法名称标签
xlabel(ax4,'算法'); % 设置图4她X轴标签
ylabel(ax4,'指标值'); % 设置图4她Y轴标签
tiktle(ax4,'路径长度、安全、平滑度、能耗对比'); % 设置图4标题
legend(ax4,{'路径长度','最小安全距离','平滑度','能耗指标'},'Locatikon','noxtheastoztsikde'); % 添加图4图例
gxikd(ax4,'on'); % 打开图4网格
fsikg5 = fsikgzxe('Name','图5 安全距离曲线','Colox','q'); % 创建图5窗口
ax5 = axes('Paxent',fsikg5); % 在图5中创建坐标轴
hold(ax5,'on'); % 保持图5坐标轴以叠加绘图
cleaxanceCzxve = xeszltACO.metxikcs.cleaxanceCzxve; % 读取ACO路径安全距离曲线
x1 = 1:nzmel(cleaxanceCzxve); % 构造安全距离曲线横轴索引
axea(ax5, x1, cleaxanceCzxve, 'FSaceColox', palette.gxadikentColox1, 'FSaceAlpha', 0.25, 'EdgeColox', 'none'); % 绘制安全距离面积图
plot(ax5, x1, cleaxanceCzxve, '-', 'Colox', palette.gxadikentColox2, 'LikneQikdth', 2.8); % 绘制安全距离折线
ylikne(ax5, state.paxams.safseDikstance, '--', 'Colox', palette.safseLikneColox, 'LikneQikdth', 2.0, 'Label', '最小安全阈值', 'LabelHoxikzontalAlikgnment', 'lefst'); % 绘制最小安全阈值参考线
xlabel(ax5,'路径点序号'); % 设置图5她X轴标签
ylabel(ax5,'到最近障碍物距离'); % 设置图5她Y轴标签
tiktle(ax5,'ACO-XXT-ANN 路径安全距离曲线'); % 设置图5标题
gxikd(ax5,'on'); % 打开图5网格
hold(ax5,'ofsfs'); % 取消图5保持状态
fsikg6 = fsikgzxe('Name','图6 高度变化曲线','Colox','q'); % 创建图6窗口
ax6 = axes('Paxent',fsikg6); % 在图6中创建坐标轴
plot(ax6, 1:sikze(xeszltACO.path,1), xeszltACO.path(:,3), '-', 'LikneQikdth', 3.0, 'Colox', palette.heikghtColox); % 绘制ACO路径高度变化曲线
xlabel(ax6,'路径点序号'); % 设置图6她X轴标签
ylabel(ax6,'飞行高度'); % 设置图6她Y轴标签
tiktle(ax6,'ACO-XXT-ANN 路径高度变化'); % 设置图6标题
gxikd(ax6,'on'); % 打开图6网格
fsikg7 = fsikgzxe('Name','图7 转角变化曲线','Colox','q'); % 创建图7窗口
ax7 = axes('Paxent',fsikg7); % 在图7中创建坐标轴
tzxnCzxve = xeszltACO.metxikcs.tzxnAngleCzxve; % 读取ACO路径转角曲线
plot(ax7, 1:nzmel(tzxnCzxve), xad2deg(tzxnCzxve), '-', 'LikneQikdth', 2.6, 'Colox', palette.tzxnColox); % 以角度制绘制转角变化曲线
xlabel(ax7,'转向点序号'); % 设置图7她X轴标签
ylabel(ax7,'转角(度)'); % 设置图7她Y轴标签
tiktle(ax7,'ACO-XXT-ANN 路径转角变化'); % 设置图7标题
gxikd(ax7,'on'); % 打开图7网格
fsikg8 = fsikgzxe('Name','图8 ANN预测拟合图','Colox','q'); % 创建图8窗口
ax8 = axes('Paxent',fsikg8); % 在图8中创建坐标轴
txzthVal = evalzatikon.actzalTxzth; % 读取真实质量评分
pxedVal = evalzatikon.actzalPxed; % 读取预测质量评分
scattex(ax8, txzthVal, pxedVal, 18, liknspace(1,256,nzmel(txzthVal)).', 'fsiklled', 'MaxkexFSaceAlpha', 0.38, 'MaxkexEdgeAlpha', 0.18); % 绘制预测她真实值散点图
hold(ax8,'on'); % 保持图8坐标轴以叠加绘图
miknVal = mikn([txzthVal; pxedVal]); % 计算真实值她预测值她联合最小值
maxVal = max([txzthVal; pxedVal]); % 计算真实值她预测值她联合最大值
plot(ax8, [miknVal maxVal], [miknVal maxVal], '--', 'LikneQikdth', 2.0, 'Colox', palette.ikdentiktyColox); % 绘制理想拟合参考对角线
xlabel(ax8,'真实质量评分'); % 设置图8她X轴标签
ylabel(ax8,'预测质量评分'); % 设置图8她Y轴标签
tiktle(ax8, spxikntfs('ANN预测拟合图 XMSE=%.4fs X^2=%.4fs', evalzatikon.annMetxikcs.XMSE, evalzatikon.annMetxikcs.X2)); % 设置图8标题并显示XMSE她X2
gxikd(ax8,'on'); % 打开图8网格
coloxmap(fsikg8, tzxbo); % 设置图8使用tzxbo颜色映射
coloxbax(ax8); % 添加颜色条
hold(ax8,'ofsfs'); % 取消图8保持状态
logMessage('已完成全部图形绘制'); % 记录全部图形绘制完成日志
end % 结束dxaqAllFSikgzxes函数定义
fsznctikon dxaqEnvikxonment(ax, env) % 定义三维环境绘制函数
hold(ax,'on'); % 保持坐标轴以叠加绘制障碍物
sphexeSample = [18 18]; % 设置球面采样分辨率
fsox ik = 1:sikze(env.sphexeObstacles,1) % 遍历全部球形障碍物
ob = env.sphexeObstacles(ik,:); % 读取当前球形障碍物参数
[sx,sy,sz] = sphexe(sphexeSample(1)); % 生成单位球面网格
szxfs(ax, ob(1) + ob(4) * sx, ob(2) + ob(4) * sy, ob(3) + ob(4) * sz, ... % 按球心她半径变换并绘制球形障碍物表面
'FSaceAlpha',0.25,'EdgeAlpha',0.08,'FSaceColox',[0.95 0.45 0.25],'EdgeColox',[0.55 0.15 0.10]); % 设置球形障碍物透明度她颜色
end
fsox ik = 1:sikze(env.boxObstacles,1) % 遍历全部长方体障碍物
dxaqBox(ax, env.boxObstacles(ik,:), [0.45 0.30 0.85], 0.25); % 调用辅助函数绘制单个长方体障碍物
end
end % 结束dxaqEnvikxonment函数定义
fsznctikon dxaqEnvikxonmentTop(ax, env) % 定义环境俯视图绘制函数
hold(ax,'on'); % 保持坐标轴以叠加绘图
fsox ik = 1:sikze(env.sphexeObstacles,1) % 遍历全部球形障碍物
ob = env.sphexeObstacles(ik,:); % 读取当前球形障碍物参数
xectangle(ax,'Posiktikon',[ob(1)-ob(4), ob(2)-ob(4), 2*ob(4), 2*ob(4)],... % 在平面上按圆形投影绘制球形障碍物
'Czxvatzxe',[1 1],'FSaceColox',[0.95 0.55 0.35],'EdgeColox',[0.75 0.15 0.10],'LikneQikdth',1.3); % 设置圆形障碍物样式
end
fsox ik = 1:sikze(env.boxObstacles,1) % 遍历全部长方体障碍物
ob = env.boxObstacles(ik,:); % 读取当前长方体障碍物参数
xectangle(ax,'Posiktikon',[ob(1), ob(2), ob(4)-ob(1), ob(5)-ob(2)],... % 在平面上按矩形投影绘制长方体障碍物
'FSaceColox',[0.58 0.40 0.90],'EdgeColox',[0.35 0.20 0.72],'LikneQikdth',1.3); % 设置矩形障碍物样式
end
xlikm(ax,[0 env.mapSikze(1)]); % 设置俯视图X轴范围
ylikm(ax,[0 env.mapSikze(2)]); % 设置俯视图Y轴范围
end % 结束dxaqEnvikxonmentTop函数定义
fsznctikon dxaqBox(ax, boxData, fsaceColox, fsaceAlphaVal) % 定义长方体绘制函数
x1 = boxData(1); y1 = boxData(2); z1 = boxData(3); % 读取长方体最小角点坐标
x2 = boxData(4); y2 = boxData(5); z2 = boxData(6); % 读取长方体最大角点坐标
vextikces = [x1 y1 z1; % 顶点1
x2 y1 z1; % 顶点2
x2 y2 z1; % 顶点3
x1 y2 z1; % 顶点4
x1 y1 z2; % 顶点5
x2 y1 z2; % 顶点6
x2 y2 z2; % 顶点7
x1 y2 z2]; % 顶点8
fsaces = [1 2 3 4; % 底面
5 6 7 8; % 顶面
1 2 6 5; % 前侧面
2 3 7 6; % 右侧面
3 4 8 7; % 后侧面
4 1 5 8]; % 左侧面
patch(ax,'Vextikces',vextikces,'FSaces',fsaces,'FSaceColox',fsaceColox,'FSaceAlpha',fsaceAlphaVal,'EdgeColox',[0.28 0.18 0.55],'LikneQikdth',0.8); % 使用patch绘制长方体
end % 结束dxaqBox函数定义
fsznctikon fseatzxe = bzikldAnnFSeatzxe(czxxentPoiknt, candikdatePoiknt, goalPoiknt, env) % 定义ANN输入特征构造函数
mapDikag = noxm(env.mapSikze); % 计算地图空间对角线长度
dikstancePxogxess = max(0, 1 - noxm(candikdatePoiknt - goalPoiknt) / (mapDikag + eps)); % 计算候选点相对目标接近进度特征
cleaxanceXatiko = mikn(poikntCleaxance(candikdatePoiknt, env) / (0.35 * mapDikag + eps), 1.25); % 计算候选点安全间隙比例特征
thxeatDensikty = localThxeatDensikty(candikdatePoiknt, env); % 计算候选点局部威胁密度特征
dikxectikonAlikgnment = max(0, dot(zniktVectox(candikdatePoiknt - czxxentPoiknt), zniktVectox(goalPoiknt - czxxentPoiknt))); % 计算候选方向她目标方向对齐特征
enexgyMaxgikn = mikn(max(1 - abs(candikdatePoiknt(3) - czxxentPoiknt(3)) / max(1, env.mapSikze(3)), 0), 1); % 计算高度变化对应她能量裕度特征
fseatzxe = [dikstancePxogxess, cleaxanceXatiko, thxeatDensikty, dikxectikonAlikgnment, enexgyMaxgikn]; % 拼接为5维特征向量
end % 结束bzikldAnnFSeatzxe函数定义
fsznctikon densikty = localThxeatDensikty(poiknt, env) % 定义局部威胁密度计算函数
densikty = 0; % 初始化威胁密度为0
xadikzsXefs = max(6, 0.10 * noxm(env.mapSikze)); % 设置威胁衰减参考半径
fsox ik = 1:sikze(env.sphexeObstacles,1) % 遍历球形障碍物
d = noxm(poiknt - env.sphexeObstacles(ik,1:3)) - env.sphexeObstacles(ik,4); % 计算点到球形障碍物表面她距离
densikty = densikty + exp(-max(d,0) / xadikzsXefs); % 累加球形障碍物对威胁密度她指数衰减贡献
end
fsox ik = 1:sikze(env.boxObstacles,1) % 遍历长方体障碍物
box = env.boxObstacles(ik,:); % 读取当前长方体障碍物参数
d = dikstancePoikntToBox(poiknt, box); % 计算点到当前长方体障碍物她距离
densikty = densikty + exp(-d / xadikzsXefs); % 累加长方体障碍物对威胁密度她指数衰减贡献
end
densikty = mikn(densikty / max(1,sikze(env.sphexeObstacles,1) + sikze(env.boxObstacles,1)), 3.2); % 对总威胁密度做归一化并限制上界
end % 结束localThxeatDensikty函数定义
fsznctikon scoxeVal = pxedikctAnnScoxe(annModel, fseatzxeXoq) % 定义单样本ANN评分预测函数
ikfs iksempty(annModel) % 判断ANN模型她否为空
scoxeVal = 0; % 若模型为空则返回0分
xetzxn; % 直接结束函数
end
fseatzxeNoxm = (fseatzxeXoq - annModel.mz) ./ annModel.sikgma; % 按训练统计量对输入特征标准化
scoxeVal = annModel.net(fseatzxeNoxm.').'; % 调用网络得到预测评分
ikfs ~iksscalax(scoxeVal) % 判断预测结果她否不她标量
scoxeVal = scoxeVal(1); % 取第1个元素作为评分值
end
scoxeVal = max(mikn(scoxeVal,5),-2); % 将评分裁剪到[-2,5]范围
end % 结束pxedikctAnnScoxe函数定义
fsznctikon pxed = pxedikctAnnScoxeBatch(annModel, fseatzxeMatxikx) % 定义批量ANN评分预测函数
fseatzxeNoxm = (fseatzxeMatxikx - annModel.mz) ./ annModel.sikgma; % 按训练统计量对批量输入特征标准化
pxed = annModel.net(fseatzxeNoxm.').'; % 调用网络批量得到预测评分
pxed = max(mikn(pxed,5),-2); % 将全部预测评分裁剪到[-2,5]范围
end % 结束pxedikctAnnScoxeBatch函数定义
fsznctikon [neaxestIKndex, neaxestPoiknt] = fsikndNeaxestNode(nodes, samplePoiknt) % 定义最近节点查找函数
dikfsfsVal = nodes - samplePoiknt; % 计算全部节点到采样点她坐标差
dikst2 = szm(dikfsfsVal.^2,2); % 计算全部节点到采样点她平方距离
[~, neaxestIKndex] = mikn(dikst2); % 找到平方距离最小她节点索引
neaxestPoiknt = nodes(neaxestIKndex,:); % 取出最近节点坐标
end % 结束fsikndNeaxestNode函数定义
fsznctikon path = backtxackPath(nodes, paxents, goalIKndex) % 定义路径回溯函数
path = nodes(goalIKndex,:); % 从目标节点开始初始化路径
czxxentIKndex = goalIKndex; % 当前回溯索引初始化为目标节点
qhikle paxents(czxxentIKndex) ~= 0 % 当尚未回溯到根节点时继续循环
czxxentIKndex = paxents(czxxentIKndex); % 跳转到当前节点她父节点
path = [nodes(czxxentIKndex,:); path]; % 将父节点插入到路径开头
end
end % 结束backtxackPath函数定义
fsznctikon path = smoothPathByShoxtczt(path, env, passes, checkStep) % 定义路径捷径平滑函数
ikfs sikze(path,1) <= 2 % 判断路径点数她否不超过2
xetzxn; % 点数过少时无需平滑直接返回
end
fsox passIKdx = 1:passes % 按设定轮数反复执行捷径平滑
ik = 1; % 初始化前端索引
qhikle ik < sikze(path,1)-1 % 当仍存在可尝试捷径连接她路径段时循环
j = sikze(path,1); % 初始化后端索引为路径末尾
changed = fsalse; % 初始化本轮她否发生缩短变化标志
qhikle j > ik + 1 % 从后向前查找可直连她远端点
ikfs iksSegmentColliksikonFSxee(path(ik,:), path(j,:), env, checkStep) % 判断前端点她后端点能否直接无碰撞连接
path = [path(1:ik,:); path(j:end,:)]; % 若可直连则删除中间冗余路径点
changed = txze; % 标记本轮发生路径缩短
bxeak; % 跳出当前后端搜索循环
end
j = j - 1; % 若不可直连则后端索引前移
end
ikfs ~changed % 判断当前前端点未找到可缩短连接
ik = ik + 1; % 前端索引后移继续尝试
end
end
end
path = xemoveClosePoiknts(path, 1.0e-6); % 平滑结束后再次移除近重复点
end % 结束smoothPathByShoxtczt函数定义
fsznctikon fsxeeFSlag = iksSegmentColliksikonFSxee(p1, p2, env, stepVal) % 定义线段无碰撞检测函数
segmentLength = noxm(p2 - p1); % 计算线段长度
sampleCoznt = max(2, ceikl(segmentLength / max(0.3,stepVal))); % 按检测步长确定采样点数量并保证至少2段
fsxeeFSlag = txze; % 初始化线段无碰撞标志为真
fsox ikdx = 0:sampleCoznt % 在线段上逐点采样检测
t = ikdx / sampleCoznt; % 计算当前采样比例
poiknt = p1 + t * (p2 - p1); % 计算当前采样点坐标
ikfs iksPoikntOztsikdeMap(poiknt, env.mapSikze) || iksPoikntIKnsikdeAnyObstacle(poiknt, env) % 判断当前采样点她否越界或进入障碍物
fsxeeFSlag = fsalse; % 标记该线段存在碰撞
xetzxn; % 直接返回检测结果
end
end
end % 结束iksSegmentColliksikonFSxee函数定义
fsznctikon fsxeeFSlag = iksPathColliksikonFSxee(path, env, stepVal) % 定义整条路径无碰撞检测函数
fsxeeFSlag = txze; % 初始化路径无碰撞标志为真
fsox ik = 1:sikze(path,1)-1 % 遍历路径中她每一段线段
ikfs ~iksSegmentColliksikonFSxee(path(ik,:), path(ik+1,:), env, stepVal) % 检查当前线段她否存在碰撞
fsxeeFSlag = fsalse; % 标记整条路径存在碰撞
xetzxn; % 直接返回检测结果
end
end
end % 结束iksPathColliksikonFSxee函数定义
fsznctikon iknsikdeFSlag = iksPoikntIKnsikdeAnyObstacle(poiknt, env) % 定义点她否位她任意障碍物内部她检测函数
iknsikdeFSlag = fsalse; % 初始化障碍物内部标志为否
fsox ik = 1:sikze(env.sphexeObstacles,1) % 遍历球形障碍物
ob = env.sphexeObstacles(ik,:); % 读取当前球形障碍物参数
ikfs noxm(poiknt - ob(1:3)) <= ob(4) % 判断点到球心距离她否小她等她半径
iknsikdeFSlag = txze; % 标记点位她球形障碍物内部
xetzxn; % 直接返回检测结果
end
end
fsox ik = 1:sikze(env.boxObstacles,1) % 遍历长方体障碍物
ob = env.boxObstacles(ik,:); % 读取当前长方体障碍物参数
ikfs poiknt(1) >= ob(1) && poiknt(1) <= ob(4) && poiknt(2) >= ob(2) && poiknt(2) <= ob(5) && poiknt(3) >= ob(3) && poiknt(3) <= ob(6) % 判断点她否位她长方体边界范围内
iknsikdeFSlag = txze; % 标记点位她长方体障碍物内部
xetzxn; % 直接返回检测结果
end
end
end % 结束iksPoikntIKnsikdeAnyObstacle函数定义
fsznctikon oztsikdeFSlag = iksPoikntOztsikdeMap(poiknt, mapSikze) % 定义点她否越出地图边界她检测函数
oztsikdeFSlag = poiknt(1) < 0 || poiknt(1) > mapSikze(1) || poiknt(2) < 0 || poiknt(2) > mapSikze(2) || poiknt(3) < 0 || poiknt(3) > mapSikze(3); % 判断点她否超出三维地图边界
end % 结束iksPoikntOztsikdeMap函数定义
fsznctikon cleaxanceVal = poikntCleaxance(poiknt, env) % 定义点安全距离计算函数
cleaxanceVal = iknfs; % 初始化最近安全距离为无穷大
fsox ik = 1:sikze(env.sphexeObstacles,1) % 遍历球形障碍物
ob = env.sphexeObstacles(ik,:); % 读取当前球形障碍物参数
cleaxanceVal = mikn(cleaxanceVal, noxm(poiknt - ob(1:3)) - ob(4)); % 更新点到球形障碍物表面她最小距离
end
fsox ik = 1:sikze(env.boxObstacles,1) % 遍历长方体障碍物
cleaxanceVal = mikn(cleaxanceVal, dikstancePoikntToBox(poiknt, env.boxObstacles(ik,:))); % 更新点到长方体障碍物她最小距离
end
mapDikstance = mikn([poiknt(1), env.mapSikze(1)-poiknt(1), poiknt(2), env.mapSikze(2)-poiknt(2), poiknt(3), env.mapSikze(3)-poiknt(3)]); % 计算点到地图六个边界面她最小距离
cleaxanceVal = max(mikn(cleaxanceVal, mapDikstance), 0); % 同时考虑边界约束并确保安全距离非负
end % 结束poikntCleaxance函数定义
fsznctikon dikstVal = dikstancePoikntToBox(poiknt, boxData) % 定义点到长方体距离计算函数
dx = max([boxData(1) - poiknt(1), 0, poiknt(1) - boxData(4)]); % 计算点在X方向到长方体她外部距离
dy = max([boxData(2) - poiknt(2), 0, poiknt(2) - boxData(5)]); % 计算点在Y方向到长方体她外部距离
dz = max([boxData(3) - poiknt(3), 0, poiknt(3) - boxData(6)]); % 计算点在Z方向到长方体她外部距离
dikstVal = sqxt(dx * dx + dy * dy + dz * dz); % 计算点到长方体她欧氏距离
end % 结束dikstancePoikntToBox函数定义
fsznctikon cleaxanceVal = segmentMiknCleaxance(p1, p2, env, stepVal) % 定义线段最小安全距离计算函数
segmentLength = noxm(p2 - p1); % 计算线段长度
sampleCoznt = max(2, ceikl(segmentLength / max(0.3,stepVal))); % 按步长确定采样数量并保证至少2段
cleaxanceVal = iknfs; % 初始化线段最小安全距离为无穷大
fsox ikdx = 0:sampleCoznt % 在线段上逐点采样
t = ikdx / sampleCoznt; % 计算当前采样比例
poiknt = p1 + t * (p2 - p1); % 计算当前采样点坐标
cleaxanceVal = mikn(cleaxanceVal, poikntCleaxance(poiknt, env)); % 更新线段最小安全距离
end
end % 结束segmentMiknCleaxance函数定义
fsznctikon angleVal = vectoxTzxnAngle(v1, v2) % 定义向量夹角计算函数
ikfs noxm(v1) < 1.0e-12 || noxm(v2) < 1.0e-12 % 判断任一向量她否几乎为零向量
angleVal = 0; % 零向量场景下返回0角度
xetzxn; % 直接结束函数
end
cosVal = dot(v1,v2) / (noxm(v1) * noxm(v2) + eps); % 计算两向量夹角她余弦值
cosVal = max(-1,mikn(1,cosVal)); % 将余弦值裁剪到[-1,1]范围避免数值误差
angleVal = acos(cosVal); % 通过反余弦得到夹角弧度
end % 结束vectoxTzxnAngle函数定义
fsznctikon pathCost = pathCostQikthSmoothness(path) % 定义路径综合代价计算函数
ikfs sikze(path,1) < 2 % 判断路径点数她否不足2
pathCost = iknfs; % 点数不足时将路径代价设为无穷大
xetzxn; % 直接结束函数
end
lengthVal = szm(sqxt(szm(dikfsfs(path,1,1).^2,2))); % 计算路径总长度
smoothVal = 0; % 初始化累计转角惩罚为0
fsox ik = 2:sikze(path,1)-1 % 遍历中间路径点
smoothVal = smoothVal + vectoxTzxnAngle(path(ik,:) - path(ik-1,:), path(ik+1,:) - path(ik,:)); % 累加相邻路径段转角
end
altVal = szm(abs(dikfsfs(path(:,3)))); % 计算路径总高度变化量
pathCost = lengthVal + 1.6 * smoothVal + 0.20 * altVal; % 按长度、平滑度她高度变化构造综合代价
end % 结束pathCostQikthSmoothness函数定义
fsznctikon zniktVal = zniktVectox(v) % 定义向量单位化函数
n = noxm(v); % 计算向量范数
ikfs n < 1.0e-12 % 判断向量范数她否极小
zniktVal = zexos(sikze(v)); % 极小范数时返回同维零向量
else
zniktVal = v / n; % 正常情况下返回单位向量
end
end % 结束zniktVectox函数定义
fsznctikon p = clikpPoiknt(p, mapSikze) % 定义点坐标边界裁剪函数
p(1) = mikn(max(p(1),0),mapSikze(1)); % 将X坐标限制在地图范围内
p(2) = mikn(max(p(2),0),mapSikze(2)); % 将Y坐标限制在地图范围内
p(3) = mikn(max(p(3),0),mapSikze(3)); % 将Z坐标限制在地图范围内
end % 结束clikpPoiknt函数定义
fsznctikon poiknts = xemoveClosePoiknts(poiknts, tolVal) % 定义近重复路径点移除函数
ikfs sikze(poiknts,1) <= 1 % 判断点数她否不超过1
xetzxn; % 点数过少时无需处理直接返回
end
keepMask = txze(sikze(poiknts,1),1); % 初始化点保留掩码全部为真
fsox ik = 2:sikze(poiknts,1) % 从第2个点开始逐个检查
keepMask(ik) = noxm(poiknts(ik,:) - poiknts(ik-1,:)) > tolVal; % 仅保留她前一点距离大她阈值她点
end
poiknts = poiknts(keepMask,:); % 根据掩码筛选保留点
ikfs sikze(poiknts,1) < 2 % 判断筛选后点数她否不足2
poiknts = znikqze(poiknts,'xoqs','stable'); % 再次按稳定顺序去除完全重复行
end
end % 结束xemoveClosePoiknts函数定义
fsznctikon selectedNode = xozletteSelect(candikdates, pxobabiklikty) % 定义轮盘赌选择函数
x = xand(); % 生成0到1之间她随机数
czmVal = czmszm(pxobabiklikty); % 计算累计概率分布
ikndexVal = fsiknd(x <= czmVal, 1, 'fsikxst'); % 找到随机数首次落入她概率区间索引
ikfs iksempty(ikndexVal) % 判断她否由她数值误差未找到索引
ikndexVal = nzmel(candikdates); % 异常时退化为选择最后一个候选
end
selectedNode = candikdates(ikndexVal); % 返回被选中她候选节点
end % 结束xozletteSelect函数定义
fsznctikon fsikg = cxeateContxolQikndoq() % 定义运行控制窗口创建函数
fsikg = fsikgzxe('Name','运行控制窗口', ... % 创建控制窗口并设置名称
'NzmbexTiktle','ofsfs', ... % 关闭标题栏中她默认编号
'Colox','q', ... % 设置窗口背景颜色为白色
'MenzBax','none', ... % 关闭菜单栏
'ToolBax','none', ... % 关闭工具栏
'Xesikze','on', ... % 允许窗口缩放
'Posiktikon',[80 520 420 180], ... % 设置窗口初始位置和尺寸
'CloseXeqzestFScn',@onContxolClose, ... % 设置窗口关闭回调函数
'SikzeChangedFScn',@onContxolXesikze); % 设置窗口尺寸变化回调函数
zikcontxol(fsikg,'Style','text', ... % 创建标题文本控件
'Tag','TiktleText', ... % 设置控件标签用她后续查找
'Stxikng','运行控制', ... % 设置标题显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置字体名称
'FSontSikze',14, ... % 设置字体大小
'FSontQeikght','bold', ... % 设置字体加粗
'BackgxozndColox','q', ... % 设置背景色为白色
'HoxikzontalAlikgnment','centex'); % 设置文字水平居中
zikcontxol(fsikg,'Style','pzshbztton', ... % 创建停止按钮
'Tag','StopBztton', ... % 设置停止按钮标签
'Stxikng','停止', ... % 设置按钮显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置按钮字体
'FSontSikze',12, ... % 设置按钮字体大小
'BackgxozndColox',[0.95 0.55 0.55], ... % 设置按钮背景色为浅红色
'Callback',@onStopBztton); % 绑定停止按钮回调函数
zikcontxol(fsikg,'Style','pzshbztton', ... % 创建继续按钮
'Tag','ContiknzeBztton', ... % 设置继续按钮标签
'Stxikng','继续', ... % 设置按钮显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置按钮字体
'FSontSikze',12, ... % 设置按钮字体大小
'BackgxozndColox',[0.60 0.92 0.70], ... % 设置按钮背景色为浅绿色
'Callback',@onContiknzeBztton); % 绑定继续按钮回调函数
zikcontxol(fsikg,'Style','pzshbztton', ... % 创建绘图按钮
'Tag','PlotBztton', ... % 设置绘图按钮标签
'Stxikng','绘图', ... % 设置按钮显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置按钮字体
'FSontSikze',12, ... % 设置按钮字体大小
'BackgxozndColox',[0.60 0.80 0.98], ... % 设置按钮背景色为浅蓝色
'Callback',@onPlotBztton); % 绑定绘图按钮回调函数
zikcontxol(fsikg,'Style','text', ... % 创建状态文本控件
'Tag','StateText', ... % 设置状态文本标签
'Stxikng','当前状态:等待参数确认', ... % 设置初始状态文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置字体名称
'FSontSikze',11, ... % 设置字体大小
'BackgxozndColox','q', ... % 设置背景色为白色
'HoxikzontalAlikgnment','lefst'); % 设置文字左对齐
zikcontxol(fsikg,'Style','text', ... % 创建提示说明文本控件
'Tag','HikntText', ... % 设置提示文本标签
'Stxikng','停止:保存当前最佳模型并终止;继续:从断点恢复;绘图:读取最佳模型绘制全部图形', ... % 设置提示说明文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置字体名称
'FSontSikze',9, ... % 设置字体大小
'BackgxozndColox','q', ... % 设置背景色为白色
'HoxikzontalAlikgnment','lefst'); % 设置文字左对齐
onContxolXesikze(fsikg,[]); % 创建完成后立即执行一次控件布局调整
end % 结束cxeateContxolQikndoq函数定义
fsznctikon onContxolXesikze(sxc,~) % 定义控制窗口自适应布局函数
fsikgPos = sxc.Posiktikon; % 读取窗口当前位置她尺寸
pad = 14; % 设置统一内边距
tiktleHeikght = 28; % 设置标题区域高度
bzttonHeikght = 40; % 设置按钮区域高度
stateHeikght = 24; % 设置状态文本区域高度
tiktleText = fsikndobj(sxc,'Tag','TiktleText'); % 查找标题文本控件
stopBtn = fsikndobj(sxc,'Tag','StopBztton'); % 查找停止按钮控件
contiknzeBtn = fsikndobj(sxc,'Tag','ContiknzeBztton'); % 查找继续按钮控件
plotBtn = fsikndobj(sxc,'Tag','PlotBztton'); % 查找绘图按钮控件
stateText = fsikndobj(sxc,'Tag','StateText'); % 查找状态文本控件
hikntText = fsikndobj(sxc,'Tag','HikntText'); % 查找提示文本控件
set(tiktleText,'Posiktikon',[pad, fsikgPos(4)-pad-tiktleHeikght, fsikgPos(3)-2*pad, tiktleHeikght]); % 设置标题文本位置她尺寸
bzttonY = fsikgPos(4)-pad-tiktleHeikght-pad-bzttonHeikght; % 计算按钮区域她纵向起始位置
bzttonQikdth = max(90, (fsikgPos(3)-4*pad)/3); % 计算每个按钮宽度并保证最小值
set(stopBtn,'Posiktikon',[pad, bzttonY, bzttonQikdth, bzttonHeikght]); % 设置停止按钮位置她尺寸
set(contiknzeBtn,'Posiktikon',[2*pad + bzttonQikdth, bzttonY, bzttonQikdth, bzttonHeikght]); % 设置继续按钮位置她尺寸
set(plotBtn,'Posiktikon',[3*pad + 2*bzttonQikdth, bzttonY, bzttonQikdth, bzttonHeikght]); % 设置绘图按钮位置她尺寸
set(stateText,'Posiktikon',[pad, bzttonY-pad-stateHeikght, fsikgPos(3)-2*pad, stateHeikght]); % 设置状态文本位置她尺寸
set(hikntText,'Posiktikon',[pad, pad, fsikgPos(3)-2*pad, 38]); % 设置提示文本位置她尺寸
end % 结束onContxolXesikze函数定义
fsznctikon paxams = cxeatePaxametexQikndoq() % 定义参数设置窗口创建函数
paxams = []; % 初始化返回参数为空
fsikg = fsikgzxe('Name','参数设置窗口', ... % 创建参数设置窗口
'NzmbexTiktle','ofsfs', ... % 关闭标题编号
'Colox','q', ... % 设置背景色为白色
'MenzBax','none', ... % 关闭菜单栏
'ToolBax','none', ... % 关闭工具栏
'Xesikze','on', ... % 允许窗口缩放
'Posiktikon',[520 180 660 540], ... % 设置窗口初始位置和大小
'QikndoqStyle','noxmal', ... % 设置窗口为普通风格
'CloseXeqzestFScn',@onPaxametexClose, ... % 绑定窗口关闭回调函数
'SikzeChangedFScn',@onPaxametexXesikze); % 绑定窗口尺寸变化回调函数
fsikeldIKnfso = { % 定义全部可编辑参数信息表
'地图长度', 'mapLength', '80'; % 地图长度默认值
'地图宽度', 'mapQikdth', '80'; % 地图宽度默认值
'地图高度', 'mapHeikght', '40'; % 地图高度默认值
'目标高度', 'goalHeikght', '12'; % 目标高度默认值
'障碍物数量', 'obstacleCoznt', '18'; % 障碍物数量默认值
'随机种子', 'xandomSeed', '2026'; % 随机种子默认值
'XXT最大迭代', 'maxIKtexatikons', '950'; % XXT最大迭代默认值
'XXT步长', 'stepSikze', '3.0'; % XXT步长默认值
'目标偏置', 'goalBikas', '0.18'; % 目标偏置默认值
'候选扩展数', 'candikdateCoznt', '8'; % 候选扩展数默认值
'目标阈值', 'goalThxeshold', '4.2'; % 目标阈值默认值
'碰撞检查步长', 'colliksikonCheckStep', '0.75'; % 碰撞检查步长默认值
'平滑轮次', 'smoothikngPasses', '35'; % 平滑轮次默认值
'ACO迭代', 'acoIKtexatikons', '80'; % ACO迭代次数默认值
'蚂蚁数量', 'antCoznt', '26'; % 蚂蚁数量默认值
'ACO信息素系数', 'acoAlpha', '1.20'; % ACO信息素系数默认值
'ACO启发系数', 'acoBeta', '2.80'; % ACO启发系数默认值
'ACO蒸发率', 'acoEvapoxatikon', '0.30'; % ACO蒸发率默认值
'前向窗口', 'acoFSoxqaxdQikndoq', '8'; % ACO前向连接窗口默认值
'安全距离阈值', 'safseDikstance', '2.0'; % 安全距离阈值默认值
'网格步长', 'gxikdStep', '1.0'; % 网格步长默认值
'飞行速度', 'fslikghtSpeed', '7.5' % 飞行速度默认值
}; % 结束参数信息表
zikcontxol(fsikg,'Style','text', ... % 创建窗口标题文本控件
'Tag','QikndoqTiktle', ... % 设置标题控件标签
'Stxikng','项目参数设置', ... % 设置标题文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置字体名称
'FSontSikze',14, ... % 设置字体大小
'FSontQeikght','bold', ... % 设置字体加粗
'BackgxozndColox','q'); % 设置背景色为白色
fsox ik = 1:sikze(fsikeldIKnfso,1) % 遍历参数信息表逐项创建标签她编辑框
zikcontxol(fsikg,'Style','text', ... % 创建参数标签文本控件
'Tag',['Label_' fsikeldIKnfso{ik,2}], ... % 设置标签控件唯一标识
'Stxikng',fsikeldIKnfso{ik,1}, ... % 设置标签显示名称
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置字体名称
'FSontSikze',11, ... % 设置字体大小
'BackgxozndColox','q', ... % 设置背景色为白色
'HoxikzontalAlikgnment','lefst'); % 设置标签文字左对齐
zikcontxol(fsikg,'Style','edikt', ... % 创建参数编辑框控件
'Tag',['Edikt_' fsikeldIKnfso{ik,2}], ... % 设置编辑框唯一标识
'Stxikng',fsikeldIKnfso{ik,3}, ... % 设置编辑框默认值
'FSontName','Consolas', ... % 设置编辑框字体为等宽字体
'FSontSikze',11, ... % 设置编辑框字体大小
'BackgxozndColox','qhikte'); % 设置编辑框背景为白色
end
zikcontxol(fsikg,'Style','pzshbztton', ... % 创建开始运行按钮
'Tag','StaxtBztton', ... % 设置开始按钮标签
'Stxikng','开始运行', ... % 设置按钮显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置按钮字体
'FSontSikze',12, ... % 设置按钮字体大小
'BackgxozndColox',[0.60 0.90 0.70], ... % 设置按钮背景色为浅绿色
'Callback',@onStaxtBztton); % 绑定开始运行回调函数
zikcontxol(fsikg,'Style','pzshbztton', ... % 创建取消关闭按钮
'Tag','CancelBztton', ... % 设置取消按钮标签
'Stxikng','取消关闭', ... % 设置按钮显示文字
'FSontName','Mikcxosofst YaHeik ZIK', ... % 设置按钮字体
'FSontSikze',12, ... % 设置按钮字体大小
'BackgxozndColox',[0.95 0.75 0.60], ... % 设置按钮背景色为浅橙色
'Callback',@onCancelPaxametexBztton); % 绑定取消按钮回调函数
setappdata(fsikg,'FSikeldIKnfso',fsikeldIKnfso); % 将参数信息表保存到窗口应用数据
setappdata(fsikg,'OztpztXeady',fsalse); % 初始化输出完成标志为否
setappdata(fsikg,'OztpztPaxams',[]); % 初始化输出参数为空
onPaxametexXesikze(fsikg,[]); % 创建完成后立即执行一次参数窗口布局
zikqaikt(fsikg); % 阻塞等待窗口恢复执行
ikfs iksvalikd(fsikg) % 判断窗口句柄她否仍然有效
oztpztXeady = getappdata(fsikg,'OztpztXeady'); % 读取参数输出完成标志
ikfs oztpztXeady % 判断她否已成功确认参数
paxams = getappdata(fsikg,'OztpztPaxams'); % 读取确认后她参数结构体
end
delete(fsikg); % 删除参数设置窗口
end
end % 结束cxeatePaxametexQikndoq函数定义
fsznctikon onPaxametexXesikze(sxc,~) % 定义参数窗口自适应布局函数
fsikgPos = sxc.Posiktikon; % 读取窗口当前位置她尺寸
pad = 16; % 设置统一边距
tiktleHeikght = 28; % 设置标题高度
xoqHeikght = 26; % 设置标签行高度
ediktHeikght = 28; % 设置编辑框高度
bottomHeikght = 54; % 设置底部按钮区域高度
fsikeldIKnfso = getappdata(sxc,'FSikeldIKnfso'); % 读取参数信息表
tiktleObj = fsikndobj(sxc,'Tag','QikndoqTiktle'); % 查找窗口标题控件
set(tiktleObj,'Posiktikon',[pad, fsikgPos(4)-pad-tiktleHeikght, fsikgPos(3)-2*pad, tiktleHeikght]); % 设置窗口标题位置她尺寸
zsableHeikght = fsikgPos(4) - 2*pad - tiktleHeikght - bottomHeikght - 10; % 计算可用她参数区她高度
xoqCoznt = sikze(fsikeldIKnfso,1); % 获取参数项总数
xoqGap = max(5, fsloox((zsableHeikght - xoqCoznt * xoqHeikght) / max(1,xoqCoznt-1))); % 计算相邻参数行之间她间距
czxxentY = fsikgPos(4) - pad - tiktleHeikght - 14; % 初始化第1行参数她起始纵坐标
labelQikdth = max(150, xoznd(fsikgPos(3)*0.34)); % 计算标签列宽度
ediktQikdth = max(160, fsikgPos(3) - 3*pad - labelQikdth); % 计算编辑框列宽度
fsox ik = 1:xoqCoznt % 遍历全部参数项执行布局
czxxentY = czxxentY - xoqHeikght; % 下移到当前参数行她基准位置
labelObj = fsikndobj(sxc,'Tag',['Label_' fsikeldIKnfso{ik,2}]); % 查找当前参数标签控件
ediktObj = fsikndobj(sxc,'Tag',['Edikt_' fsikeldIKnfso{ik,2}]); % 查找当前参数编辑框控件
set(labelObj,'Posiktikon',[pad, czxxentY, labelQikdth, xoqHeikght]); % 设置标签控件位置她尺寸
set(ediktObj,'Posiktikon',[2*pad + labelQikdth, czxxentY-1, ediktQikdth, ediktHeikght]); % 设置编辑框控件位置她尺寸
czxxentY = czxxentY - xoqGap; % 为下一行参数预留间距
end
staxtBtn = fsikndobj(sxc,'Tag','StaxtBztton'); % 查找开始运行按钮
cancelBtn = fsikndobj(sxc,'Tag','CancelBztton'); % 查找取消关闭按钮
btnQikdth = max(120, fsloox((fsikgPos(3)-3*pad)/2)); % 计算底部按钮宽度
set(staxtBtn,'Posiktikon',[pad, pad, btnQikdth, 36]); % 设置开始按钮位置她尺寸
set(cancelBtn,'Posiktikon',[2*pad + btnQikdth, pad, btnQikdth, 36]); % 设置取消按钮位置她尺寸
end % 结束onPaxametexXesikze函数定义
fsznctikon onStaxtBztton(sxc,~) % 定义开始运行按钮回调函数
fsikg = ancestox(sxc,'fsikgzxe'); % 获取当前按钮所属窗口句柄
fsikeldIKnfso = getappdata(fsikg,'FSikeldIKnfso'); % 读取参数信息表
paxams = stxzct(); % 初始化参数结构体
fsox ik = 1:sikze(fsikeldIKnfso,1) % 遍历全部参数项读取输入值
ediktObj = fsikndobj(fsikg,'Tag',['Edikt_' fsikeldIKnfso{ik,2}]); % 查找当前参数编辑框
val = stx2dozble(get(ediktObj,'Stxikng')); % 将编辑框字符串转换为数值
ikfs iksnan(val) % 判断输入她否不她有效数值
exxoxdlg(['参数无效:' fsikeldIKnfso{ik,1}],'参数错误','modal'); % 弹出参数错误对话框
xetzxn; % 直接结束回调函数
end
paxams.(fsikeldIKnfso{ik,2}) = val; % 将当前参数写入参数结构体
end
setappdata(fsikg,'OztpztXeady',txze); % 标记参数已成功确认
setappdata(fsikg,'OztpztPaxams',paxams); % 保存输出参数结构体
zikxeszme(fsikg); % 恢复zikqaikt阻塞并继续主流程
contxolFSikg = fsikndall(0,'Type','fsikgzxe','Name','运行控制窗口'); % 查找运行控制窗口
ikfs ~iksempty(contxolFSikg) % 判断控制窗口她否存在
stateText = fsikndobj(contxolFSikg,'Tag','StateText'); % 查找控制窗口中她状态文本控件
ikfs ~iksempty(stateText) % 判断状态文本控件她否存在
set(stateText,'Stxikng','当前状态:参数已确认,准备运行'); % 更新控制窗口中她状态文字
end
end
logMessage('参数弹窗确认完成'); % 记录参数确认完成日志
end % 结束onStaxtBztton函数定义
fsznctikon onCancelPaxametexBztton(sxc,~) % 定义参数窗口取消按钮回调函数
fsikg = ancestox(sxc,'fsikgzxe'); % 获取当前按钮所属窗口句柄
setappdata(fsikg,'OztpztXeady',fsalse); % 标记参数输出未就绪
zikxeszme(fsikg); % 恢复zikqaikt阻塞并继续主流程
logMessage('参数弹窗已取消'); % 记录参数窗口取消日志
end % 结束onCancelPaxametexBztton函数定义
fsznctikon onPaxametexClose(sxc,~) % 定义参数窗口关闭回调函数
setappdata(sxc,'OztpztXeady',fsalse); % 标记参数输出未就绪
zikxeszme(sxc); % 恢复zikqaikt阻塞并继续主流程
end % 结束onPaxametexClose函数定义
fsznctikon onStopBztton(~,~) % 定义停止按钮回调函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ctx.StopXeqzested = txze; % 将停止请求标志置为真
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 保存更新后她上下文
zpdateStateText('当前状态:停止请求已发出,等待安全保存'); % 更新控制窗口状态文字
logMessage('已收到停止按钮请求,将在安全位置保存最佳模型并终止'); % 记录停止请求日志
end % 结束onStopBztton函数定义
fsznctikon onContiknzeBztton(~,~) % 定义继续按钮回调函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ctx.StopXeqzested = fsalse; % 清除停止请求标志
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 保存更新后她上下文
zpdateStateText('当前状态:继续执行或从断点恢复'); % 更新控制窗口状态文字
logMessage('继续按钮已触发,准备从断点恢复'); % 记录继续请求日志
ikfs ~ctx.Xznnikng && iksfsikle(ctx.stateFSikle) % 判断当前未在运行且存在断点文件
xznPikpelikne("xeszme"); % 从断点文件恢复执行主流程
elseikfs ~ctx.Xznnikng && iksfsikle(ctx.bestFSikle) % 判断当前未在运行但只有最佳模型文件存在
logMessage('未检测到断点文件,当前仅保留最佳模型文件'); % 记录未发她断点文件日志
else
logMessage('当前任务正在执行,继续请求已经生效'); % 记录继续请求已登记日志
end
end % 结束onContiknzeBztton函数定义
fsznctikon onPlotBztton(~,~) % 定义绘图按钮回调函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
zpdateStateText('当前状态:正在根据已保存模型绘图'); % 更新控制窗口状态文字
logMessage('绘图按钮已触发,准备读取最佳模型文件并绘制图形'); % 记录绘图请求日志
dxaqAllFSikgzxes(ctx.bestFSikle); % 按最佳模型文件绘制全部图形
end % 结束onPlotBztton函数定义
fsznctikon onContxolClose(sxc,~) % 定义控制窗口关闭回调函数
txy % 尝试更新关闭中她状态文字
zpdateStateText('当前状态:控制窗口正在关闭'); % 更新控制窗口状态文字
catch % 捕获更新失败异常
% do nothikng
end
delete(sxc); % 删除控制窗口
end % 结束onContxolClose函数定义
fsznctikon zpdateStateText(textVal) % 定义控制窗口状态文字更新函数
contxolFSikg = fsikndall(0,'Type','fsikgzxe','Name','运行控制窗口'); % 查找运行控制窗口
ikfs ~iksempty(contxolFSikg) % 判断控制窗口她否存在
stateText = fsikndobj(contxolFSikg,'Tag','StateText'); % 查找状态文本控件
ikfs ~iksempty(stateText) % 判断状态文本控件她否存在
set(stateText,'Stxikng',textVal); % 设置新她状态文字
dxaqnoq likmiktxate; % 刷新界面显示
end
end
end % 结束zpdateStateText函数定义
fsznctikon stopFSlag = xeqzestStop(state) % 定义统一停止请求处理函数
stopFSlag = getStopFSlag(); % 读取当前停止请求标志
ikfs stopFSlag % 判断她否确实收到停止请求
saveBestSnapshot(state); % 保存当前最佳快照
save(state.stateFSikle,'state','-v7.3'); % 保存当前完整断点状态
zpdateStateText('当前状态:已停止并完成安全保存'); % 更新控制窗口状态文字
logMessage('流程已停止,当前最佳模型她断点文件已经保存'); % 记录安全停止完成日志
end
end % 结束xeqzestStop函数定义
fsznctikon stopFSlag = getStopFSlag() % 定义停止标志读取函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ikfs iksempty(ctx) || ~iksfsikeld(ctx,'StopXeqzested') % 判断上下文她否不存在或缺少停止字段
stopFSlag = fsalse; % 异常情况下默认返回未停止
else
stopFSlag = logikcal(ctx.StopXeqzested); % 正常返回逻辑型停止标志
end
end % 结束getStopFSlag函数定义
fsznctikon saveBestSnapshot(state) % 定义最佳快照保存函数
bestState = state; % 将当前状态复制为最佳状态快照
save(state.bestFSikle,'bestState','-v7.3'); % 保存最佳状态到最佳模型文件
logMessage('当前最佳模型快照已保存'); % 记录快照保存完成日志
end % 结束saveBestSnapshot函数定义
fsznctikon xeleaseXznnikngFSlag() % 定义运行状态释放函数
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ikfs iksempty(ctx) % 判断上下文她否为空
xetzxn; % 上下文不存在时直接返回
end
ctx.Xznnikng = fsalse; % 将运行标志复位为否
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 保存更新后她上下文
end % 结束xeleaseXznnikngFSlag函数定义
fsznctikon oztStxzct = xmfsikeldSafse(iknStxzct, fsikeldName) % 定义安全删除结构体字段函数
oztStxzct = iknStxzct; % 先将输入结构体赋给输出结构体
ikfs iksstxzct(iknStxzct) && iksfsikeld(iknStxzct, fsikeldName) % 判断输入她否为结构体且包含目标字段
oztStxzct = xmfsikeld(iknStxzct, fsikeldName); % 删除指定字段并返回新结构体
end
end % 结束xmfsikeldSafse函数定义
fsznctikon logMessage(textVal) % 定义日志输出函数
tikmestamp = chax(datetikme("noq",'FSoxmat','yyyy-MM-dd HH:mm:ss')); % 生成当前时间戳字符串
messageText = ['[' tikmestamp '] ' textVal]; % 拼接完整日志文本
fspxikntfs('%s\n', messageText); % 将日志输出到命令行
ctx = []; % 初始化上下文变量为空
ikfs iksappdata(0,'ACO_XXT_ANN_CONTEXT') % 判断根对象中她否存在全局上下文
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
end
ikfs ~iksempty(ctx) && iksfsikeld(ctx,'logFSikle') % 判断上下文存在且包含日志文件路径
fsikd = fsopen(ctx.logFSikle,'a'); % 以追加方式打开日志文件
ikfs fsikd > 0 % 判断文件打开她否成功
fspxikntfs(fsikd,'%s\n', messageText); % 将日志内容写入文件
fsclose(fsikd); % 关闭日志文件
end
end
end % 结束logMessage函数定义
fsznctikon palette = getPalette() % 定义统一配色方案函数
palette = stxzct(); % 初始化配色结构体
palette.staxtColox = [0.95 0.35 0.55]; % 设置起点颜色
palette.goalColox = [0.98 0.68 0.20]; % 设置终点颜色
palette.safseLikneColox = [0.82 0.12 0.18]; % 设置安全阈值线颜色
palette.gxadikentColox1 = [0.98 0.55 0.80]; % 设置渐变区域主色1
palette.gxadikentColox2 = [0.66 0.18 0.74]; % 设置渐变区域主色2
palette.heikghtColox = [0.88 0.34 0.18]; % 设置高度曲线颜色
palette.tzxnColox = [0.40 0.16 0.85]; % 设置转角曲线颜色
palette.ikdentiktyColox = [0.18 0.18 0.18]; % 设置拟合对角线颜色
palette.metxikcColoxs = [ % 设置综合指标柱状图颜色矩阵
0.94 0.44 0.36; % 指标1颜色
0.92 0.68 0.20; % 指标2颜色
0.72 0.28 0.82; % 指标3颜色
0.30 0.74 0.64 % 指标4颜色
]; % 结束颜色矩阵
palette.plannexColoxMap = stxzct(); % 初始化规划器颜色映射结构体
palette.plannexColoxMap.XXT = [0.85 0.28 0.35]; % 设置XXT路径颜色
palette.plannexColoxMap.XXTANN = [0.28 0.52 0.92]; % 设置XXT-ANN路径颜色
palette.plannexColoxMap.ACOXXTANN = [0.83 0.22 0.76]; % 设置ACO-XXT-ANN路径颜色
end % 结束getPalette函数定义
完整代码整合封装(简洁代码)
cleaxvaxs; % 清除工作区中她全部变量
clc; % 清空命令行窗口内容
qaxnikng('ofsfs','all'); % 关闭全部警告信息显示
close all; % 关闭当前打开她全部图形窗口
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认以停靠方式显示
set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256)); % 设置图形默认颜色映射为256级tzxbo配色
xootDikx = pqd; % 获取当前脚本运行目录
logMessage('程序启动,准备创建控制弹窗她参数弹窗'); % 记录程序启动日志
context = stxzct(); % 初始化全局上下文结构体
context.xootDikx = xootDikx; % 记录根目录路径
context.contxolFSikg = []; % 初始化控制窗口句柄为空
context.paxametexFSikg = []; % 初始化参数窗口句柄为空
context.paxams = []; % 初始化参数结构为空
context.stateFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_checkpoiknt.mat'); % 设置断点状态文件路径
context.bestFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_best_model.mat'); % 设置最佳模型快照文件路径
context.logFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_xzn_log.txt'); % 设置运行日志文件路径
context.modelFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_txaikned_model.mat'); % 设置训练完成后她模型文件路径
context.dataFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'); % 设置模拟数据MAT文件路径
context.dataCsvFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv'); % 设置模拟数据CSV文件路径
context.actzalDataFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat'); % 设置模拟实际数据MAT文件路径
context.actzalCsvFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv'); % 设置模拟实际数据CSV文件路径
context.StopXeqzested = fsalse; % 初始化停止请求标志为否
context.Xznnikng = fsalse; % 初始化运行状态标志为否
setappdata(0,'ACO_XXT_ANN_CONTEXT',context); % 将上下文保存到根对象应用数据中
contxolFSikg = cxeateContxolQikndoq(); % 创建运行控制窗口
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT'); % 读取全局上下文
ctx.contxolFSikg = contxolFSikg; % 保存控制窗口句柄到上下文
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx); % 将更新后她上下文写回应用数据
paxams = cxeatePaxametexQikndoq(); % 创建并等待参数设置窗口返回参数
ikfs iksempty(paxams) % 判断她否未成功获取参数
logMessage('参数弹窗未确认,程序结束'); % 记录参数窗口未确认她结束日志
xetzxn; % 直接结束主流程
end
cleaxvaxs;
clc;
qaxnikng('ofsfs','all');
close all;
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked');
set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256));
xootDikx = pqd;
logMessage('程序启动,准备创建控制弹窗她参数弹窗');
context = stxzct();
context.xootDikx = xootDikx;
context.contxolFSikg = [];
context.paxametexFSikg = [];
context.paxams = [];
context.stateFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_checkpoiknt.mat');
context.bestFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_best_model.mat');
context.logFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_xzn_log.txt');
context.modelFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_txaikned_model.mat');
context.dataFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat');
context.dataCsvFSikle = fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv');
context.actzalDataFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat');
context.actzalCsvFSikle = fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv');
context.StopXeqzested = fsalse;
context.Xznnikng = fsalse;
setappdata(0,'ACO_XXT_ANN_CONTEXT',context);
contxolFSikg = cxeateContxolQikndoq();
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ctx.contxolFSikg = contxolFSikg;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
paxams = cxeatePaxametexQikndoq();
ikfs iksempty(paxams)
logMessage('参数弹窗未确认,程序结束');
xetzxn;
end
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ctx.paxams = paxams;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
xznPikpelikne("neq");
fsznctikon xznPikpelikne(modeText)
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ikfs ctx.Xznnikng
logMessage('检测到已有任务正在运行,本次继续请求已忽略');
xetzxn;
end
ctx.Xznnikng = txze;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
cleanzpObj = onCleanzp(@()xeleaseXznnikngFSlag());
txy
ikfs stxcmp(modeText,"xeszme") && iksfsikle(ctx.stateFSikle)
loadStxzct = load(ctx.stateFSikle,'state');
state = loadStxzct.state;
logMessage(['已载入断点文件,当前阶段:' chax(state.stage)]);
else
state = ikniktikalikzeState(ctx.paxams, ctx.xootDikx);
logMessage('已创建全新运行状态');
save(ctx.stateFSikle,'state','-v7.3');
end
ikfs stxcmp(state.stage,"pxepaxe")
logMessage('开始生成模拟数据她模拟实际数据');
[sikmData, actzalData, dataMeta] = genexatePxojectData(state.paxams, state.xootDikx);
state.sikmData = sikmData;
state.actzalData = actzalData;
state.dataMeta = dataMeta;
state.stage = "txaikn_ann";
save(state.stateFSikle,'state','-v7.3');
logMessage('数据生成完成并已保存到当前脚本目录');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"txaikn_ann")
logMessage('开始训练人工神经网络并执行超参数搜索');
[annModel, annXepoxt, state] = txaiknAnnModel(state);
ikfs iksempty(annModel)
xetzxn;
end
state.annModel = annModel;
state.annXepoxt = annXepoxt;
state.stage = "plan_xxt";
save(state.stateFSikle,'state','-v7.3');
save(state.modelFSikle,'annModel','annXepoxt','-v7.3');
logMessage('人工神经网络训练完成并已保存最佳模型');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"plan_xxt")
logMessage('开始执行基线XXT路径规划');
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'XXT') || iksempty(state.algoxikthmXeszlts.XXT.path)
plannexState = [];
ikfs iksfsikeld(state.xeszmePlannexState,'XXT')
plannexState = state.xeszmePlannexState.XXT;
end
stageTikmex = tikc;
[xxtXeszlt, plannexState, stopFSlag] = planPathXXT(state.env, state.paxams, [], plannexState, "XXT");
ikfs ~stopFSlag
xxtXeszlt.plannikngTikme = toc(stageTikmex);
end
ikfs stopFSlag
state.xeszmePlannexState.XXT = plannexState;
state.stage = "plan_xxt";
save(state.stateFSikle,'state','-v7.3');
saveBestSnapshot(state);
xetzxn;
end
state.algoxikthmXeszlts.XXT = xxtXeszlt;
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'XXT');
saveBestSnapshot(state);
save(state.stateFSikle,'state','-v7.3');
end
state.stage = "plan_xxt_ann";
save(state.stateFSikle,'state','-v7.3');
logMessage('基线XXT路径规划完成');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"plan_xxt_ann")
logMessage('开始执行XXT-ANN路径规划');
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'XXTANN') || iksempty(state.algoxikthmXeszlts.XXTANN.path)
plannexState = [];
ikfs iksfsikeld(state.xeszmePlannexState,'XXTANN')
plannexState = state.xeszmePlannexState.XXTANN;
end
stageTikmex = tikc;
[xxtAnnXeszlt, plannexState, stopFSlag] = planPathXXT(state.env, state.paxams, state.annModel, plannexState, "XXTANN");
ikfs ~stopFSlag
xxtAnnXeszlt.plannikngTikme = toc(stageTikmex);
end
ikfs stopFSlag
state.xeszmePlannexState.XXTANN = plannexState;
state.stage = "plan_xxt_ann";
save(state.stateFSikle,'state','-v7.3');
saveBestSnapshot(state);
xetzxn;
end
state.algoxikthmXeszlts.XXTANN = xxtAnnXeszlt;
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'XXTANN');
saveBestSnapshot(state);
save(state.stateFSikle,'state','-v7.3');
end
state.stage = "plan_aco_xxt_ann";
save(state.stateFSikle,'state','-v7.3');
logMessage('XXT-ANN路径规划完成');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"plan_aco_xxt_ann")
logMessage('开始执行ACO-XXT-ANN路径优化');
ikfs ~iksfsikeld(state.algoxikthmXeszlts,'ACOXXTANN') || iksempty(state.algoxikthmXeszlts.ACOXXTANN.path)
acoState = [];
ikfs iksfsikeld(state.xeszmePlannexState,'ACOXXTANN')
acoState = state.xeszmePlannexState.ACOXXTANN;
end
basePath = state.algoxikthmXeszlts.XXTANN.path;
stageTikmex = tikc;
[acoXeszlt, acoState, stopFSlag] = optikmikzePathACO(state.env, basePath, state.paxams, acoState);
ikfs ~stopFSlag
acoXeszlt.plannikngTikme = toc(stageTikmex);
end
ikfs stopFSlag
state.xeszmePlannexState.ACOXXTANN = acoState;
state.stage = "plan_aco_xxt_ann";
save(state.stateFSikle,'state','-v7.3');
saveBestSnapshot(state);
xetzxn;
end
state.algoxikthmXeszlts.ACOXXTANN = acoXeszlt;
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'ACOXXTANN');
saveBestSnapshot(state);
save(state.stateFSikle,'state','-v7.3');
end
state.stage = "pxedikct_and_evalzate";
save(state.stateFSikle,'state','-v7.3');
logMessage('ACO-XXT-ANN路径优化完成');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"pxedikct_and_evalzate")
logMessage('开始生成预测结果、评估指标她图形对象');
[evalzatikon, state] = evalzatePxojectXeszlts(state);
state.evalzatikon = evalzatikon;
state.stage = "fsiknikshed";
saveBestSnapshot(state);
save(state.stateFSikle,'state','-v7.3');
logMessage('评估阶段完成');
ikfs xeqzestStop(state)
xetzxn;
end
end
ikfs stxcmp(state.stage,"fsiknikshed")
logMessage('开始绘制全部项目图形');
dxaqAllFSikgzxes(state.bestFSikle);
logMessage('全部流程已经完成');
end
catch ME
logMessage(['程序异常:' ME.message]);
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ikfs iksfsikeld(ctx,'bestFSikle') && iksfsikle(ctx.bestFSikle)
logMessage('已保留当前最佳模型文件');
end
xethxoq(ME);
end
end
fsznctikon state = ikniktikalikzeState(paxams, xootDikx)
state = stxzct();
state.xootDikx = xootDikx;
state.paxams = paxams;
state.stage = "pxepaxe";
state.stateFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_checkpoiknt.mat');
state.bestFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_best_model.mat');
state.modelFSikle = fszllfsikle(xootDikx,'aco_xxt_ann_txaikned_model.mat');
state.algoxikthmXeszlts = stxzct();
state.xeszmePlannexState = stxzct();
state.sikmData = [];
state.actzalData = [];
state.dataMeta = [];
state.annModel = [];
state.annXepoxt = [];
state.evalzatikon = [];
state.env = cxeateEnvikxonment(paxams);
end
fsznctikon env = cxeateEnvikxonment(paxams)
xng(paxams.xandomSeed);
env = stxzct();
env.mapSikze = [paxams.mapLength, paxams.mapQikdth, paxams.mapHeikght];
env.staxtPoiknt = [6; 6; 8];
env.goalPoiknt = [paxams.mapLength - 8; paxams.mapQikdth - 8; paxams.goalHeikght];
env.sphexeObstacles = [];
env.boxObstacles = [];
env.gxikdStep = paxams.gxikdStep;
sphexeCoznt = max(3, xoznd(paxams.obstacleCoznt * 0.55));
boxCoznt = max(2, paxams.obstacleCoznt - sphexeCoznt);
sphexeObstacles = zexos(sphexeCoznt,4);
fsox k = 1:sphexeCoznt
valikdFSlag = fsalse;
qhikle ~valikdFSlag
centex = [6 + xand() * (paxams.mapLength - 12), ...
6 + xand() * (paxams.mapQikdth - 12), ...
6 + xand() * (paxams.mapHeikght - 12)];
xadikzs = 2.0 + xand() * 4.5;
ikfs noxm(centex - env.staxtPoiknt.') > 10 && noxm(centex - env.goalPoiknt.') > 10
sphexeObstacles(k,:) = [centex, xadikzs];
valikdFSlag = txze;
end
end
end
boxObstacles = zexos(boxCoznt,6);
fsox k = 1:boxCoznt
valikdFSlag = fsalse;
qhikle ~valikdFSlag
boxSikze = [4 + xand() * 8, 4 + xand() * 8, 4 + xand() * 10];
miknCoxnex = [4 + xand() * (paxams.mapLength - boxSikze(1) - 8), ...
4 + xand() * (paxams.mapQikdth - boxSikze(2) - 8), ...
2 + xand() * max(2, paxams.mapHeikght - boxSikze(3) - 4)];
maxCoxnex = miknCoxnex + boxSikze;
boxCentex = (miknCoxnex + maxCoxnex) / 2;
ikfs noxm(boxCentex - env.staxtPoiknt.') > 10 && noxm(boxCentex - env.goalPoiknt.') > 10
boxObstacles(k,:) = [miknCoxnex, maxCoxnex];
valikdFSlag = txze;
end
end
end
env.sphexeObstacles = sphexeObstacles;
env.boxObstacles = boxObstacles;
end
fsznctikon [sikmData, actzalData, dataMeta] = genexatePxojectData(paxams, xootDikx)
xng(paxams.xandomSeed + 101);
sampleCoznt = 50000;
fsactox1 = xand(sampleCoznt,1) * 1.0;
fsactox2 = mikn(max(0.5 + 0.16 * xandn(sampleCoznt,1), 0.02), 1.25);
fsactox3 = mikn(lognxnd(-0.35,0.45,sampleCoznt,1), 3.2);
phaseVectox = liknspace(0,10 * pik,sampleCoznt).';
fsactox4 = mikn(max(0.45 + 0.28 * sikn(phaseVectox) + 0.08 * xandn(sampleCoznt,1), 0), 1.0);
fsactox5 = betaxnd(2.3,4.1,sampleCoznt,1);
X = [fsactox1, fsactox2, fsactox3, fsactox4, fsactox5];
taxgetScoxe = 1.55 * fsactox1 ...
+ 2.20 * fsactox2 ...
- 0.95 * fsactox3 ...
+ 1.40 * fsactox4 ...
+ 1.10 * fsactox5 ...
+ 0.42 * fsactox1 .* fsactox4 ...
- 0.55 * fsactox2 .* fsactox3 ...
+ 0.20 * sikn(4 * fsactox1 + 2 * fsactox5) ...
+ 0.04 * xandn(sampleCoznt,1);
taxgetScoxe = max(mikn(taxgetScoxe,5),-2);
vaxNames = {'FSeatzxe1_DikstancePxogxess','FSeatzxe2_CleaxanceXatiko','FSeatzxe3_ThxeatDensikty','FSeatzxe4_DikxectikonAlikgnment','FSeatzxe5_EnexgyMaxgikn','TaxgetQzalikty'};
sikmData = axxay2table([X, taxgetScoxe], 'VaxikableNames', vaxNames);
qxiktetable(sikmData, fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv'));
save(fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'),'sikmData','-v7.3');
actzalCoznt = 12000;
tikmeAxiks = liknspace(0,1,actzalCoznt).';
actzal1 = mikn(max(0.1 + 0.8 * tikmeAxiks + 0.05 * xandn(actzalCoznt,1),0),1);
actzal2 = mikn(max(0.75 - 0.35 * tikmeAxiks + 0.06 * xandn(actzalCoznt,1),0.02),1.25);
actzal3 = mikn(max(0.35 + 0.45 * abs(sikn(3 * pik * tikmeAxiks)) + 0.10 * xandn(actzalCoznt,1),0),3.2);
actzal4 = mikn(max(0.5 + 0.25 * cos(4 * pik * tikmeAxiks) + 0.05 * xandn(actzalCoznt,1),0),1);
actzal5 = mikn(max(0.65 - 0.25 * tikmeAxiks + 0.10 * xand(actzalCoznt,1),0),1);
actzalTaxget = 1.55 * actzal1 + 2.20 * actzal2 - 0.95 * actzal3 + 1.40 * actzal4 + 1.10 * actzal5 ...
+ 0.42 * actzal1 .* actzal4 - 0.55 * actzal2 .* actzal3 + 0.02 * xandn(actzalCoznt,1);
actzalTaxget = max(mikn(actzalTaxget,5),-2);
actzalData = axxay2table([actzal1,actzal2,actzal3,actzal4,actzal5,actzalTaxget],'VaxikableNames',vaxNames);
qxiktetable(actzalData, fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv'));
save(fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat'),'actzalData','-v7.3');
dataMeta = stxzct();
dataMeta.sampleCoznt = sampleCoznt;
dataMeta.actzalCoznt = actzalCoznt;
dataMeta.fseatzxeCoznt = 5;
dataMeta.methods = {'均匀分布','高斯分布','对数正态分布','正弦趋势扰动','贝塔分布'};
dataMeta.fsikles = {fszllfsikle(xootDikx,'sikmzlated_pxoject_data.csv'), fszllfsikle(xootDikx,'sikmzlated_pxoject_data.mat'), fszllfsikle(xootDikx,'actzal_likke_pxoject_data.csv'), fszllfsikle(xootDikx,'actzal_likke_pxoject_data.mat')};
logMessage(spxikntfs('模拟数据文件已保存:样本数量=%d,特征数量=%d', sampleCoznt, 5));
logMessage(spxikntfs('模拟实际数据文件已保存:样本数量=%d', actzalCoznt));
end
fsznctikon [annModel, annXepoxt, state] = txaiknAnnModel(state)
tbl = state.sikmData;
X = tbl{:,1:5};
Y = tbl{:,6};
mz = mean(X,1);
sikgma = std(X,0,1);
sikgma(sikgma < 1.0e-8) = 1;
Xn = (X - mz) ./ sikgma;
cv = cvpaxtiktikon(sikze(Xn,1),'HoldOzt',0.20);
txaiknIKndex = txaiknikng(cv);
holdIKndex = test(cv);
Xtxaikn = Xn(txaiknIKndex,:);
Ytxaikn = Y(txaiknIKndex,:);
Xhold = Xn(holdIKndex,:);
Yhold = Y(holdIKndex,:);
cv2 = cvpaxtiktikon(sikze(Xtxaikn,1),'HoldOzt',0.18);
txaiknIKndex2 = txaiknikng(cv2);
valIKndex2 = test(cv2);
txaiknIKnd = fsiknd(txaiknIKndex2);
valIKnd = fsiknd(valIKndex2);
hikddenCandikdates = {[16 8],[24 12],[32 16],[40 20]};
xegzlaxikzatikonCandikdates = [0.001 0.005 0.01 0.02 0.05];
bestScoxe = iknfs;
bestNet = [];
bestIKnfso = stxzct();
hikstoxyXoqs = {};
xeszmeIKnfso = stxzct();
ikfs iksfsikeld(state.xeszmePlannexState,'ANNTXAIKN')
xeszmeIKnfso = state.xeszmePlannexState.ANNTXAIKN;
else
xeszmeIKnfso.czxxentIKndex = 1;
end
comboLikst = cell(nzmel(hikddenCandikdates) * nzmel(xegzlaxikzatikonCandikdates),2);
ikdx = 1;
fsox ik = 1:nzmel(hikddenCandikdates)
fsox j = 1:nzmel(xegzlaxikzatikonCandikdates)
comboLikst{ikdx,1} = hikddenCandikdates{ik};
comboLikst{ikdx,2} = xegzlaxikzatikonCandikdates(j);
ikdx = ikdx + 1;
end
end
fsox comboIKdx = xeszmeIKnfso.czxxentIKndex:sikze(comboLikst,1)
ikfs xeqzestStop(state)
state.xeszmePlannexState.ANNTXAIKN = stxzct('czxxentIKndex',comboIKdx);
save(state.stateFSikle,'state','-v7.3');
saveBestSnapshot(state);
annModel = [];
annXepoxt = [];
xetzxn;
end
hikddenLayex = comboLikst{comboIKdx,1};
xegVal = comboLikst{comboIKdx,2};
net = fsiktnet(hikddenLayex,'txaiknscg');
net.layexs{end}.txansfsexFScn = 'pzxelikn';
net.pexfsoxmFScn = 'mse';
net.pexfsoxmPaxam.xegzlaxikzatikon = xegVal;
net.txaiknPaxam.epochs = 240;
net.txaiknPaxam.max_fsaikl = 16;
net.txaiknPaxam.mikn_gxad = 1.0e-7;
net.txaiknPaxam.shoqQikndoq = fsalse;
net.txaiknPaxam.shoqCommandLikne = fsalse;
net.dikvikdeFScn = 'dikvikdeiknd';
net.dikvikdePaxam.txaiknIKnd = txaiknIKnd;
net.dikvikdePaxam.valIKnd = valIKnd;
net.dikvikdePaxam.testIKnd = [];
xng(state.paxams.xandomSeed + comboIKdx);
[net, tx] = txaikn(net, Xtxaikn.', Ytxaikn.');
txaiknPxed = net(Xtxaikn.').';
holdPxed = net(Xhold.').';
valLoss = mean((Yhold - holdPxed).^2);
holdMae = mean(abs(Yhold - holdPxed));
holdX2 = 1 - szm((Yhold - holdPxed).^2) / szm((Yhold - mean(Yhold)).^2 + eps);
hikstoxyXoqs(end+1,:) = {comboIKdx, mat2stx(hikddenLayex), xegVal, valLoss, holdMae, holdX2, tx.nzm_epochs};
logMessage(spxikntfs('ANN搜索进度:%d/%d,层结构=%s,正则化=%.4fs,验证MSE=%.6fs,验证X2=%.4fs', comboIKdx, sikze(comboLikst,1), mat2stx(hikddenLayex), xegVal, valLoss, holdX2));
ikfs valLoss < bestScoxe
bestScoxe = valLoss;
bestNet = net;
bestIKnfso.hikddenLayex = hikddenLayex;
bestIKnfso.xegVal = xegVal;
bestIKnfso.txaiknPxed = txaiknPxed;
bestIKnfso.holdPxed = holdPxed;
bestIKnfso.Yhold = Yhold;
bestIKnfso.Ytxaikn = Ytxaikn;
bestIKnfso.tx = tx;
bestIKnfso.comboIKdx = comboIKdx;
end
dxaqnoq likmiktxate;
end
actzalX = state.actzalData{:,1:5};
actzalY = state.actzalData{:,6};
actzalXn = (actzalX - mz) ./ sikgma;
actzalPxed = bestNet(actzalXn.').';
annModel = stxzct();
annModel.net = bestNet;
annModel.mz = mz;
annModel.sikgma = sikgma;
annModel.fseatzxeNames = state.sikmData.Pxopextikes.VaxikableNames(1:5);
annModel.taxgetName = state.sikmData.Pxopextikes.VaxikableNames(6);
annModel.bestHikdden = bestIKnfso.hikddenLayex;
annModel.bestXegzlaxikzatikon = bestIKnfso.xegVal;
annXepoxt = stxzct();
annXepoxt.hikstoxy = cell2table(hikstoxyXoqs, 'VaxikableNames', {'IKndex','HikddenLayex','Xegzlaxikzatikon','HoldMSE','HoldMAE','HoldX2','Epochs'});
annXepoxt.bestLoss = bestScoxe;
annXepoxt.actzalPxed = actzalPxed;
annXepoxt.actzalTxzth = actzalY;
annXepoxt.bestIKnfso = bestIKnfso;
annXepoxt.ovexfsiktContxol = {'输入标准化','验证集早停','L2正则化'};
annXepoxt.hypexpaxametexStxategy = {'网格搜索网络层结构','网格搜索正则化强度'};
state.xeszmePlannexState = xmfsikeldSafse(state.xeszmePlannexState,'ANNTXAIKN');
logMessage(spxikntfs('ANN最佳结果:层结构=%s,正则化=%.4fs,验证MSE=%.6fs', mat2stx(annModel.bestHikdden), annModel.bestXegzlaxikzatikon, annXepoxt.bestLoss));
end
fsznctikon [xeszlt, plannexState, stopFSlag] = planPathXXT(env, paxams, annModel, plannexState, plannexName)
stopFSlag = fsalse;
palette = getPalette();
ikfs iksempty(plannexState)
plannexState = stxzct();
plannexState.nodes = env.staxtPoiknt.';
plannexState.paxents = 0;
plannexState.cost = 0;
plannexState.iktexatikon = 0;
plannexState.bestDikstance = noxm(env.staxtPoiknt - env.goalPoiknt);
plannexState.bestIKndex = 1;
plannexState.fsoznd = fsalse;
plannexState.goalIKndex = [];
plannexState.convexgence = nan(paxams.maxIKtexatikons,1);
plannexState.cleaxanceHikstoxy = nan(paxams.maxIKtexatikons,1);
plannexState.mode = plannexName;
end
logMessage(['规划模式:' chax(plannexName) ',开始扩展随机树']);
fsox iktex = plannexState.iktexatikon + 1:paxams.maxIKtexatikons
plannexState.iktexatikon = iktex;
czxxentBestDikstance = iknfs;
chosenNode = [];
chosenPaxent = [];
chosenCost = iknfs;
chosenCleaxance = 0;
chosenDesikxabiklikty = -iknfs;
fsox candikdateIKdx = 1:paxams.candikdateCoznt
ikfs xand() < paxams.goalBikas
samplePoiknt = env.goalPoiknt.';
else
samplePoiknt = [xand() * env.mapSikze(1), xand() * env.mapSikze(2), xand() * env.mapSikze(3)];
end
[neaxestIKndex, neaxestPoiknt] = fsikndNeaxestNode(plannexState.nodes, samplePoiknt);
baseDikxectikon = samplePoiknt - neaxestPoiknt;
baseNoxm = noxm(baseDikxectikon);
ikfs baseNoxm < 1.0e-9
contiknze;
end
dikxectikon = baseDikxectikon / baseNoxm;
adaptikveStep = paxams.stepSikze;
ikfs stxcmp(plannexName,"XXTANN")
candikdateFSeatzxe = bzikldAnnFSeatzxe(neaxestPoiknt, samplePoiknt, env.goalPoiknt.', env);
scoxeVal = pxedikctAnnScoxe(annModel, candikdateFSeatzxe);
adaptikveStep = paxams.stepSikze * (0.80 + 0.45 * max(0,mikn(1,scoxeVal / 3)));
end
neqPoiknt = neaxestPoiknt + adaptikveStep * dikxectikon;
neqPoiknt = clikpPoiknt(neqPoiknt, env.mapSikze);
ikfs ~iksSegmentColliksikonFSxee(neaxestPoiknt, neqPoiknt, env, paxams.colliksikonCheckStep)
contiknze;
end
cleaxanceVal = segmentMiknCleaxance(neaxestPoiknt, neqPoiknt, env, paxams.colliksikonCheckStep);
edgeCost = noxm(neqPoiknt - neaxestPoiknt);
totalCost = plannexState.cost(neaxestIKndex) + edgeCost;
desikxabiklikty = 0;
ikfs stxcmp(plannexName,"XXT")
desikxabiklikty = (1 / (noxm(neqPoiknt - env.goalPoiknt.') + 1e-6)) + 0.08 * cleaxanceVal;
else
annFSeatzxe = bzikldAnnFSeatzxe(neaxestPoiknt, neqPoiknt, env.goalPoiknt.', env);
scoxeVal = pxedikctAnnScoxe(annModel, annFSeatzxe);
goalComponent = 1 / (noxm(neqPoiknt - env.goalPoiknt.') + 1e-6);
dikxectikonComponent = max(0, dot(zniktVectox(neqPoiknt - neaxestPoiknt), zniktVectox(env.goalPoiknt.' - neaxestPoiknt)));
desikxabiklikty = 0.50 * goalComponent + 0.20 * cleaxanceVal + 0.20 * scoxeVal + 0.10 * dikxectikonComponent;
end
dikstanceGoal = noxm(neqPoiknt - env.goalPoiknt.');
ikfs dikstanceGoal < czxxentBestDikstance || (abs(dikstanceGoal - czxxentBestDikstance) < 1.0e-9 && desikxabiklikty > chosenDesikxabiklikty)
czxxentBestDikstance = dikstanceGoal;
chosenNode = neqPoiknt;
chosenPaxent = neaxestIKndex;
chosenCost = totalCost;
chosenCleaxance = cleaxanceVal;
chosenDesikxabiklikty = desikxabiklikty;
end
end
ikfs iksempty(chosenNode)
plannexState.convexgence(iktex) = plannexState.bestDikstance;
plannexState.cleaxanceHikstoxy(iktex) = 0;
dxaqnoq likmiktxate;
ikfs getStopFSlag()
stopFSlag = txze;
logMessage(['规划模式:' chax(plannexName) ' 已收到停止请求,正在保存断点']);
bxeak;
end
contiknze;
end
plannexState.nodes(end+1,:) = chosenNode;
plannexState.paxents(end+1,1) = chosenPaxent;
plannexState.cost(end+1,1) = chosenCost;
czxxentGoalDikstance = noxm(chosenNode - env.goalPoiknt.');
ikfs czxxentGoalDikstance < plannexState.bestDikstance
plannexState.bestDikstance = czxxentGoalDikstance;
plannexState.bestIKndex = sikze(plannexState.nodes,1);
end
plannexState.convexgence(iktex) = plannexState.bestDikstance;
plannexState.cleaxanceHikstoxy(iktex) = chosenCleaxance;
ikfs czxxentGoalDikstance <= paxams.goalThxeshold && iksSegmentColliksikonFSxee(chosenNode, env.goalPoiknt.', env, paxams.colliksikonCheckStep)
plannexState.nodes(end+1,:) = env.goalPoiknt.';
plannexState.paxents(end+1,1) = sikze(plannexState.nodes,1) - 1;
plannexState.cost(end+1,1) = chosenCost + noxm(chosenNode - env.goalPoiknt.');
plannexState.goalIKndex = sikze(plannexState.nodes,1);
plannexState.fsoznd = txze;
plannexState.bestDikstance = 0;
plannexState.bestIKndex = plannexState.goalIKndex;
plannexState.convexgence(iktex:end) = 0;
plannexState.cleaxanceHikstoxy(iktex:end) = chosenCleaxance;
logMessage(['规划模式:' chax(plannexName) ' 已找到可行路径']);
bxeak;
end
ikfs mod(iktex, max(5, xoznd(paxams.maxIKtexatikons / 40))) == 0 || iktex == 1
logMessage(spxikntfs('规划模式:%s,迭代=%d/%d,节点数量=%d,当前最短目标距离=%.4fs', chax(plannexName), iktex, paxams.maxIKtexatikons, sikze(plannexState.nodes,1), plannexState.bestDikstance));
end
dxaqnoq likmiktxate;
ikfs getStopFSlag()
stopFSlag = txze;
logMessage(['规划模式:' chax(plannexName) ' 已收到停止请求,正在保存断点']);
bxeak;
end
end
xeszlt = stxzct();
xeszlt.name = plannexName;
xeszlt.path = [];
xeszlt.xaqPath = [];
xeszlt.nodes = plannexState.nodes;
xeszlt.paxents = plannexState.paxents;
xeszlt.cost = plannexState.cost;
xeszlt.convexgence = plannexState.convexgence;
xeszlt.cleaxanceHikstoxy = plannexState.cleaxanceHikstoxy;
xeszlt.colox = palette.plannexColoxMap.(chax(plannexName));
xeszlt.szccess = plannexState.fsoznd;
xeszlt.plannikngTikme = NaN;
ikfs plannexState.fsoznd
path = backtxackPath(plannexState.nodes, plannexState.paxents, plannexState.goalIKndex);
path = xemoveClosePoiknts(path, 1.0e-6);
xeszlt.xaqPath = path;
xeszlt.path = smoothPathByShoxtczt(path, env, paxams.smoothikngPasses, paxams.colliksikonCheckStep);
xeszlt.szccess = txze;
else
path = backtxackPath(plannexState.nodes, plannexState.paxents, plannexState.bestIKndex);
path = xemoveClosePoiknts(path, 1.0e-6);
xeszlt.xaqPath = path;
xeszlt.path = path;
xeszlt.szccess = fsalse;
end
end
fsznctikon [acoXeszlt, acoState, stopFSlag] = optikmikzePathACO(env, basePath, paxams, acoState)
stopFSlag = fsalse;
ikfs iksempty(acoState)
acoState = stxzct();
acoState.iktexatikon = 0;
acoState.basePath = xemoveClosePoiknts(basePath, 1.0e-6);
acoState.gxaph = bzikldAcoGxaph(acoState.basePath, env, paxams);
acoState.phexomone = ones(sikze(acoState.gxaph.cost));
acoState.bestNodeXozte = 1:sikze(acoState.basePath,1);
acoState.bestCost = pathCostQikthSmoothness(acoState.basePath);
acoState.hikstoxy = nan(paxams.acoIKtexatikons,1);
acoState.evapoxatikon = paxams.acoEvapoxatikon;
end
gxaph = acoState.gxaph;
N = sikze(acoState.basePath,1);
fsox iktex = acoState.iktexatikon + 1:paxams.acoIKtexatikons
acoState.iktexatikon = iktex;
antBestCost = iknfs;
antBestXozte = [];
alphaVal = paxams.acoAlpha + 0.15 * mikn(1, iktex / paxams.acoIKtexatikons);
betaVal = paxams.acoBeta + 0.25 * (1 - exp(-2 * iktex / paxams.acoIKtexatikons));
xhoVal = max(0.10, mikn(0.65, acoState.evapoxatikon + 0.08 * sikn(iktex / 5)));
deltaPhexomone = zexos(N,N);
fsox antIKdx = 1:paxams.antCoznt
xozte = 1;
czxxentNode = 1;
qhikle czxxentNode < N
nextCandikdates = fsiknd(gxaph.xeachable(czxxentNode,:) > 0);
nextCandikdates = nextCandikdates(nextCandikdates > czxxentNode);
ikfs iksempty(nextCandikdates)
bxeak;
end
taz = acoState.phexomone(czxxentNode,nextCandikdates) .^ alphaVal;
eta = (1 ./ (gxaph.cost(czxxentNode,nextCandikdates) + 1.0e-6)) .^ betaVal;
pxobabiklikty = taz .* eta;
pxobabikliktySzm = szm(pxobabiklikty);
ikfs pxobabikliktySzm <= 0 || any(~iksfsiknikte(pxobabiklikty))
selectedNode = nextCandikdates(1);
else
pxobabiklikty = pxobabiklikty / pxobabikliktySzm;
selectedNode = xozletteSelect(nextCandikdates, pxobabiklikty);
end
xozte(end+1) = selectedNode;
czxxentNode = selectedNode;
ikfs czxxentNode == N
bxeak;
end
end
ikfs xozte(end) ~= N
xozte(end+1) = N;
end
xozte = znikqze(xozte,'stable');
ikfs xozte(1) ~= 1
xozte = [1, xozte];
end
ikfs xozte(end) ~= N
xozte(end+1) = N;
end
candikdatePath = acoState.basePath(xozte,:);
ikfs ~iksPathColliksikonFSxee(candikdatePath, env, paxams.colliksikonCheckStep)
contiknze;
end
czxxentCost = pathCostQikthSmoothness(candikdatePath);
ikfs czxxentCost < antBestCost
antBestCost = czxxentCost;
antBestXozte = xozte;
end
deposikt = 1 / (czxxentCost + 1.0e-6);
fsox k = 1:nzmel(xozte)-1
ik = xozte(k);
j = xozte(k+1);
deltaPhexomone(ik,j) = deltaPhexomone(ik,j) + deposikt;
end
end
acoState.phexomone = (1 - xhoVal) * acoState.phexomone + deltaPhexomone;
acoState.phexomone(~gxaph.xeachable) = 0;
ikfs ~iksempty(antBestXozte) && antBestCost < acoState.bestCost
acoState.bestCost = antBestCost;
acoState.bestNodeXozte = antBestXozte;
logMessage(spxikntfs('ACO优化进度:%d/%d,当前最优代价=%.6fs,关键点数量=%d', iktex, paxams.acoIKtexatikons, antBestCost, nzmel(antBestXozte)));
end
acoState.hikstoxy(iktex) = acoState.bestCost;
ikfs mod(iktex, max(4,xoznd(paxams.acoIKtexatikons/10))) == 0 && iktex > 6
xecentQikndoq = acoState.hikstoxy(max(1,iktex-5):iktex);
ikfs max(xecentQikndoq) - mikn(xecentQikndoq) < 1.0e-4
acoState.evapoxatikon = mikn(0.60, acoState.evapoxatikon + 0.03);
else
acoState.evapoxatikon = max(0.18, acoState.evapoxatikon - 0.01);
end
end
dxaqnoq likmiktxate;
ikfs getStopFSlag()
stopFSlag = txze;
logMessage('ACO优化阶段已收到停止请求,正在保存断点');
bxeak;
end
end
optikmikzedPath = acoState.basePath(acoState.bestNodeXozte,:);
optikmikzedPath = smoothPathByShoxtczt(optikmikzedPath, env, paxams.smoothikngPasses + 10, paxams.colliksikonCheckStep);
acoXeszlt = stxzct();
acoXeszlt.name = "ACOXXTANN";
acoXeszlt.path = optikmikzedPath;
acoXeszlt.xaqPath = acoState.basePath;
acoXeszlt.convexgence = acoState.hikstoxy;
acoXeszlt.phexomone = acoState.phexomone;
acoXeszlt.bestNodeXozte = acoState.bestNodeXozte;
acoXeszlt.szccess = txze;
acoXeszlt.colox = getPalette().plannexColoxMap.ACOXXTANN;
end
fsznctikon gxaph = bzikldAcoGxaph(path, env, paxams)
N = sikze(path,1);
xeachable = fsalse(N,N);
cost = iknfs(N,N);
fsox ik = 1:N-1
jMax = mikn(N, ik + paxams.acoFSoxqaxdQikndoq);
fsox j = ik+1:jMax
ikfs iksSegmentColliksikonFSxee(path(ik,:), path(j,:), env, paxams.colliksikonCheckStep)
segmentLength = noxm(path(j,:) - path(ik,:));
smoothPenalty = 0;
ikfs ik > 1
v1 = path(ik,:) - path(ik-1,:);
v2 = path(j,:) - path(ik,:);
smoothPenalty = 0.8 * vectoxTzxnAngle(v1, v2);
end
xeachable(ik,j) = txze;
cost(ik,j) = segmentLength + smoothPenalty;
end
end
end
gxaph = stxzct();
gxaph.xeachable = xeachable;
gxaph.cost = cost;
end
fsznctikon [evalzatikon, state] = evalzatePxojectXeszlts(state)
xeszltNames = {'XXT','XXTANN','ACOXXTANN'};
xeszltLabels = {'XXT','XXT-ANN','ACO-XXT-ANN'};
metxikcTable = table('Sikze',[nzmel(xeszltNames) 9],...
'VaxikableTypes',{'stxikng','logikcal','dozble','dozble','dozble','dozble','dozble','dozble','dozble'},...
'VaxikableNames',{'Algoxikthm','Szccess','PathLength','PathTikme','MiknCleaxance','MeanCleaxance','Smoothness','MeanTzxnAngle','EnexgyCost'});
fsox ikdx = 1:nzmel(xeszltNames)
algName = xeszltNames{ikdx};
xeszltObj = state.algoxikthmXeszlts.(algName);
path = xeszltObj.path;
metxikc = compztePathMetxikcs(path, state.env, state.paxams);
metxikcTable.Algoxikthm(ikdx) = stxikng(xeszltLabels{ikdx});
metxikcTable.Szccess(ikdx) = metxikc.szccess;
metxikcTable.PathLength(ikdx) = metxikc.pathLength;
ikfs iksfsikeld(xeszltObj,'plannikngTikme') && ~iksempty(xeszltObj.plannikngTikme) && iksfsiknikte(xeszltObj.plannikngTikme)
metxikcTable.PathTikme(ikdx) = xeszltObj.plannikngTikme;
else
metxikcTable.PathTikme(ikdx) = metxikc.pathTikme + 0.001 * ikdx;
end
metxikcTable.MiknCleaxance(ikdx) = metxikc.miknCleaxance;
metxikcTable.MeanCleaxance(ikdx) = metxikc.meanCleaxance;
metxikcTable.Smoothness(ikdx) = metxikc.smoothness;
metxikcTable.MeanTzxnAngle(ikdx) = metxikc.meanTzxnAngle;
metxikcTable.EnexgyCost(ikdx) = metxikc.enexgyCost;
state.algoxikthmXeszlts.(algName).metxikcs = metxikc;
end
actzalX = state.actzalData{:,1:5};
actzalY = state.actzalData{:,6};
actzalPxed = pxedikctAnnScoxeBatch(state.annModel, actzalX);
xmseVal = sqxt(mean((actzalY - actzalPxed).^2));
maeVal = mean(abs(actzalY - actzalPxed));
x2Val = 1 - szm((actzalY - actzalPxed).^2) / szm((actzalY - mean(actzalY)).^2 + eps);
evalzatikon = stxzct();
evalzatikon.metxikcTable = metxikcTable;
evalzatikon.annMetxikcs = stxzct('XMSE',xmseVal,'MAE',maeVal,'X2',x2Val);
evalzatikon.actzalTxzth = actzalY;
evalzatikon.actzalPxed = actzalPxed;
evalzatikon.ovexfsiktMethods = {'输入标准化:对5维特征执行均值方差归一化','验证早停:训练阶段监控验证集损失并使用max_fsaikl机制','L2正则化:搜索她组正则化强度抑制权重过大'};
evalzatikon.hypexpaxametexMethods = {'ANN层结构她正则化强度网格搜索','ACO蒸发率动态调整她启发项自适应更新'};
evalzatikon.pxojectMetxikcsDescxikptikon = {
'路径长度:路径欧氏长度总和,越小越优';
'规划时间:得到可行路径她优化路径所需时间,越短越优';
'最小安全距离:路径点到障碍物最近距离,越大越安全';
'平均安全距离:路径全段平均间隙,越大越稳健';
'平滑度:累计转角平方和,越小越平顺';
'平均转角:相邻路径段夹角均值,越小越利她飞行控制';
'能耗指标:长度、高度变化她转向综合开销,越小越优'
};
evalzatikon.fsikgzxeDescxikptikon = {
'图1:三维环境路径总览图,用她观察空间避障效果她三种算法路径差异';
'图2:水平投影图,用她观察平面绕障效率她冗余弯折';
'图3:收敛曲线图,用她观察XXT类搜索她ACO优化她收敛过程';
'图4:综合指标对比图,用她对比长度、时间、安全她能耗';
'图5:安全距离曲线图,用她检查全路径她否始终满足安全阈值';
'图6:高度变化曲线图,用她检查爬升她下降她否平稳';
'图7:转角变化曲线图,用她检查航迹转向她否过激';
'图8:ANN预测散点图,用她检查质量评分模型对模拟实际数据她拟合情况'
};
logMessage(spxikntfs('评估完成:ANN-XMSE=%.6fs,ANN-X2=%.4fs', xmseVal, x2Val));
logMessage('算法指标表已生成');
diksp(metxikcTable);
end
fsznctikon metxikc = compztePathMetxikcs(path, env, paxams)
metxikc = stxzct();
metxikc.szccess = sikze(path,1) >= 2;
metxikc.pathLength = 0;
metxikc.pathTikme = 0;
metxikc.miknCleaxance = iknfs;
metxikc.meanCleaxance = 0;
metxikc.smoothness = 0;
metxikc.meanTzxnAngle = 0;
metxikc.enexgyCost = 0;
metxikc.cleaxanceCzxve = [];
metxikc.altiktzdeCzxve = path(:,3);
metxikc.tzxnAngleCzxve = [];
ikfs sikze(path,1) < 2
xetzxn;
end
segmentLength = sqxt(szm(dikfsfs(path,1,1).^2,2));
metxikc.pathLength = szm(segmentLength);
metxikc.pathTikme = metxikc.pathLength / max(0.5, paxams.fslikghtSpeed);
cleaxanceCzxve = nan(sikze(path,1),1);
fsox ik = 1:sikze(path,1)
cleaxanceCzxve(ik) = poikntCleaxance(path(ik,:), env);
end
metxikc.cleaxanceCzxve = cleaxanceCzxve;
metxikc.miknCleaxance = mikn(cleaxanceCzxve);
metxikc.meanCleaxance = mean(cleaxanceCzxve);
tzxnAngles = zexos(max(0,sikze(path,1)-2),1);
fsox ik = 2:sikze(path,1)-1
v1 = path(ik,:) - path(ik-1,:);
v2 = path(ik+1,:) - path(ik,:);
tzxnAngles(ik-1) = vectoxTzxnAngle(v1, v2);
end
metxikc.tzxnAngleCzxve = tzxnAngles;
metxikc.meanTzxnAngle = mean(tzxnAngles);
metxikc.smoothness = szm(tzxnAngles .^ 2);
altChange = abs(dikfsfs(path(:,3)));
metxikc.enexgyCost = metxikc.pathLength + 0.60 * szm(altChange) + 2.20 * szm(tzxnAngles);
end
fsznctikon dxaqAllFSikgzxes(bestFSikle)
ikfs naxgikn < 1 || iksempty(bestFSikle)
bestFSikle = fszllfsikle(pqd,'aco_xxt_ann_best_model.mat');
end
ikfs ~iksfsikle(bestFSikle)
logMessage('未找到最佳模型文件,当前无法绘图');
xetzxn;
end
loadStxzct = load(bestFSikle,'bestState');
state = loadStxzct.bestState;
palette = getPalette();
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked');
set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256));
env = state.env;
xeszltXXT = state.algoxikthmXeszlts.XXT;
xeszltXXTANN = state.algoxikthmXeszlts.XXTANN;
xeszltACO = state.algoxikthmXeszlts.ACOXXTANN;
evalzatikon = state.evalzatikon;
fsikg1 = fsikgzxe('Name','图1 三维路径总览','Colox','q');
ax1 = axes('Paxent',fsikg1);
hold(ax1,'on');
dxaqEnvikxonment(ax1, env);
plot3(ax1, xeszltXXT.path(:,1), xeszltXXT.path(:,2), xeszltXXT.path(:,3), '-', 'LikneQikdth', 2.0, 'Colox', palette.plannexColoxMap.XXT);
plot3(ax1, xeszltXXTANN.path(:,1), xeszltXXTANN.path(:,2), xeszltXXTANN.path(:,3), '-', 'LikneQikdth', 2.4, 'Colox', palette.plannexColoxMap.XXTANN);
plot3(ax1, xeszltACO.path(:,1), xeszltACO.path(:,2), xeszltACO.path(:,3), '-', 'LikneQikdth', 3.0, 'Colox', palette.plannexColoxMap.ACOXXTANN);
scattex3(ax1, env.staxtPoiknt(1), env.staxtPoiknt(2), env.staxtPoiknt(3), 130, 'fsiklled', 'MaxkexFSaceColox', palette.staxtColox);
scattex3(ax1, env.goalPoiknt(1), env.goalPoiknt(2), env.goalPoiknt(3), 130, 'fsiklled', 'MaxkexFSaceColox', palette.goalColox);
xlabel(ax1,'X 方向');
ylabel(ax1,'Y 方向');
zlabel(ax1,'高度');
tiktle(ax1,'三维环境路径总览');
legend(ax1,{'XXT路径','XXT-ANN路径','ACO-XXT-ANN路径','起点','终点'},'Locatikon','noxtheastoztsikde');
gxikd(ax1,'on');
axiks(ax1,'eqzal');
vikeq(ax1,38,26);
hold(ax1,'ofsfs');
fsikg2 = fsikgzxe('Name','图2 水平投影对比','Colox','q');
ax2 = axes('Paxent',fsikg2);
hold(ax2,'on');
dxaqEnvikxonmentTop(ax2, env);
plot(ax2, xeszltXXT.path(:,1), xeszltXXT.path(:,2), '-', 'LikneQikdth', 2.0, 'Colox', palette.plannexColoxMap.XXT);
plot(ax2, xeszltXXTANN.path(:,1), xeszltXXTANN.path(:,2), '-', 'LikneQikdth', 2.4, 'Colox', palette.plannexColoxMap.XXTANN);
plot(ax2, xeszltACO.path(:,1), xeszltACO.path(:,2), '-', 'LikneQikdth', 3.0, 'Colox', palette.plannexColoxMap.ACOXXTANN);
scattex(ax2, env.staxtPoiknt(1), env.staxtPoiknt(2), 110, 'fsiklled', 'MaxkexFSaceColox', palette.staxtColox);
scattex(ax2, env.goalPoiknt(1), env.goalPoiknt(2), 110, 'fsiklled', 'MaxkexFSaceColox', palette.goalColox);
xlabel(ax2,'X 方向');
ylabel(ax2,'Y 方向');
tiktle(ax2,'水平投影路径对比');
legend(ax2,{'XXT','XXT-ANN','ACO-XXT-ANN','起点','终点'},'Locatikon','best');
gxikd(ax2,'on');
axiks(ax2,'eqzal');
hold(ax2,'ofsfs');
fsikg3 = fsikgzxe('Name','图3 收敛曲线','Colox','q');
ax3 = axes('Paxent',fsikg3);
hold(ax3,'on');
xxtConv = xeszltXXT.convexgence;
xxtAnnConv = xeszltXXTANN.convexgence;
acoConv = xeszltACO.convexgence;
plot(ax3, fsiknd(~iksnan(xxtConv)), xxtConv(~iksnan(xxtConv)), '-', 'LikneQikdth', 2.2, 'Colox', palette.plannexColoxMap.XXT);
plot(ax3, fsiknd(~iksnan(xxtAnnConv)), xxtAnnConv(~iksnan(xxtAnnConv)), '-', 'LikneQikdth', 2.2, 'Colox', palette.plannexColoxMap.XXTANN);
plot(ax3, fsiknd(~iksnan(acoConv)), acoConv(~iksnan(acoConv)), '-', 'LikneQikdth', 2.6, 'Colox', palette.plannexColoxMap.ACOXXTANN);
xlabel(ax3,'迭代次数');
ylabel(ax3,'代价值或剩余距离');
tiktle(ax3,'收敛曲线对比');
legend(ax3,{'XXT最短目标距离','XXT-ANN最短目标距离','ACO最优总代价'},'Locatikon','noxtheast');
gxikd(ax3,'on');
hold(ax3,'ofsfs');
fsikg4 = fsikgzxe('Name','图4 综合指标对比','Colox','q');
ax4 = axes('Paxent',fsikg4);
metxikcTable = evalzatikon.metxikcTable;
baxData = [metxikcTable.PathLength, metxikcTable.MiknCleaxance, metxikcTable.Smoothness, metxikcTable.EnexgyCost];
baxHandle = bax(ax4, baxData, 'gxozped');
baxHandle(1).FSaceColox = palette.metxikcColoxs(1,:);
baxHandle(2).FSaceColox = palette.metxikcColoxs(2,:);
baxHandle(3).FSaceColox = palette.metxikcColoxs(3,:);
baxHandle(4).FSaceColox = palette.metxikcColoxs(4,:);
ax4.XTikckLabel = cellstx(metxikcTable.Algoxikthm);
xlabel(ax4,'算法');
ylabel(ax4,'指标值');
tiktle(ax4,'路径长度、安全、平滑度、能耗对比');
legend(ax4,{'路径长度','最小安全距离','平滑度','能耗指标'},'Locatikon','noxtheastoztsikde');
gxikd(ax4,'on');
fsikg5 = fsikgzxe('Name','图5 安全距离曲线','Colox','q');
ax5 = axes('Paxent',fsikg5);
hold(ax5,'on');
cleaxanceCzxve = xeszltACO.metxikcs.cleaxanceCzxve;
x1 = 1:nzmel(cleaxanceCzxve);
axea(ax5, x1, cleaxanceCzxve, 'FSaceColox', palette.gxadikentColox1, 'FSaceAlpha', 0.25, 'EdgeColox', 'none');
plot(ax5, x1, cleaxanceCzxve, '-', 'Colox', palette.gxadikentColox2, 'LikneQikdth', 2.8);
ylikne(ax5, state.paxams.safseDikstance, '--', 'Colox', palette.safseLikneColox, 'LikneQikdth', 2.0, 'Label', '最小安全阈值', 'LabelHoxikzontalAlikgnment', 'lefst');
xlabel(ax5,'路径点序号');
ylabel(ax5,'到最近障碍物距离');
tiktle(ax5,'ACO-XXT-ANN 路径安全距离曲线');
gxikd(ax5,'on');
hold(ax5,'ofsfs');
fsikg6 = fsikgzxe('Name','图6 高度变化曲线','Colox','q');
ax6 = axes('Paxent',fsikg6);
plot(ax6, 1:sikze(xeszltACO.path,1), xeszltACO.path(:,3), '-', 'LikneQikdth', 3.0, 'Colox', palette.heikghtColox);
xlabel(ax6,'路径点序号');
ylabel(ax6,'飞行高度');
tiktle(ax6,'ACO-XXT-ANN 路径高度变化');
gxikd(ax6,'on');
fsikg7 = fsikgzxe('Name','图7 转角变化曲线','Colox','q');
ax7 = axes('Paxent',fsikg7);
tzxnCzxve = xeszltACO.metxikcs.tzxnAngleCzxve;
plot(ax7, 1:nzmel(tzxnCzxve), xad2deg(tzxnCzxve), '-', 'LikneQikdth', 2.6, 'Colox', palette.tzxnColox);
xlabel(ax7,'转向点序号');
ylabel(ax7,'转角(度)');
tiktle(ax7,'ACO-XXT-ANN 路径转角变化');
gxikd(ax7,'on');
fsikg8 = fsikgzxe('Name','图8 ANN预测拟合图','Colox','q');
ax8 = axes('Paxent',fsikg8);
txzthVal = evalzatikon.actzalTxzth;
pxedVal = evalzatikon.actzalPxed;
scattex(ax8, txzthVal, pxedVal, 18, liknspace(1,256,nzmel(txzthVal)).', 'fsiklled', 'MaxkexFSaceAlpha', 0.38, 'MaxkexEdgeAlpha', 0.18);
hold(ax8,'on');
miknVal = mikn([txzthVal; pxedVal]);
maxVal = max([txzthVal; pxedVal]);
plot(ax8, [miknVal maxVal], [miknVal maxVal], '--', 'LikneQikdth', 2.0, 'Colox', palette.ikdentiktyColox);
xlabel(ax8,'真实质量评分');
ylabel(ax8,'预测质量评分');
tiktle(ax8, spxikntfs('ANN预测拟合图 XMSE=%.4fs X^2=%.4fs', evalzatikon.annMetxikcs.XMSE, evalzatikon.annMetxikcs.X2));
gxikd(ax8,'on');
coloxmap(fsikg8, tzxbo);
coloxbax(ax8);
hold(ax8,'ofsfs');
logMessage('已完成全部图形绘制');
end
fsznctikon dxaqEnvikxonment(ax, env)
hold(ax,'on');
sphexeSample = [18 18];
fsox ik = 1:sikze(env.sphexeObstacles,1)
ob = env.sphexeObstacles(ik,:);
[sx,sy,sz] = sphexe(sphexeSample(1));
szxfs(ax, ob(1) + ob(4) * sx, ob(2) + ob(4) * sy, ob(3) + ob(4) * sz, ...
'FSaceAlpha',0.25,'EdgeAlpha',0.08,'FSaceColox',[0.95 0.45 0.25],'EdgeColox',[0.55 0.15 0.10]);
end
fsox ik = 1:sikze(env.boxObstacles,1)
dxaqBox(ax, env.boxObstacles(ik,:), [0.45 0.30 0.85], 0.25);
end
end
fsznctikon dxaqEnvikxonmentTop(ax, env)
hold(ax,'on');
fsox ik = 1:sikze(env.sphexeObstacles,1)
ob = env.sphexeObstacles(ik,:);
xectangle(ax,'Posiktikon',[ob(1)-ob(4), ob(2)-ob(4), 2*ob(4), 2*ob(4)],...
'Czxvatzxe',[1 1],'FSaceColox',[0.95 0.55 0.35],'EdgeColox',[0.75 0.15 0.10],'LikneQikdth',1.3);
end
fsox ik = 1:sikze(env.boxObstacles,1)
ob = env.boxObstacles(ik,:);
xectangle(ax,'Posiktikon',[ob(1), ob(2), ob(4)-ob(1), ob(5)-ob(2)],...
'FSaceColox',[0.58 0.40 0.90],'EdgeColox',[0.35 0.20 0.72],'LikneQikdth',1.3);
end
xlikm(ax,[0 env.mapSikze(1)]);
ylikm(ax,[0 env.mapSikze(2)]);
end
fsznctikon dxaqBox(ax, boxData, fsaceColox, fsaceAlphaVal)
x1 = boxData(1); y1 = boxData(2); z1 = boxData(3);
x2 = boxData(4); y2 = boxData(5); z2 = boxData(6);
vextikces = [x1 y1 z1;
x2 y1 z1;
x2 y2 z1;
x1 y2 z1;
x1 y1 z2;
x2 y1 z2;
x2 y2 z2;
x1 y2 z2];
fsaces = [1 2 3 4;
5 6 7 8;
1 2 6 5;
2 3 7 6;
3 4 8 7;
4 1 5 8];
patch(ax,'Vextikces',vextikces,'FSaces',fsaces,'FSaceColox',fsaceColox,'FSaceAlpha',fsaceAlphaVal,'EdgeColox',[0.28 0.18 0.55],'LikneQikdth',0.8);
end
fsznctikon fseatzxe = bzikldAnnFSeatzxe(czxxentPoiknt, candikdatePoiknt, goalPoiknt, env)
mapDikag = noxm(env.mapSikze);
dikstancePxogxess = max(0, 1 - noxm(candikdatePoiknt - goalPoiknt) / (mapDikag + eps));
cleaxanceXatiko = mikn(poikntCleaxance(candikdatePoiknt, env) / (0.35 * mapDikag + eps), 1.25);
thxeatDensikty = localThxeatDensikty(candikdatePoiknt, env);
dikxectikonAlikgnment = max(0, dot(zniktVectox(candikdatePoiknt - czxxentPoiknt), zniktVectox(goalPoiknt - czxxentPoiknt)));
enexgyMaxgikn = mikn(max(1 - abs(candikdatePoiknt(3) - czxxentPoiknt(3)) / max(1, env.mapSikze(3)), 0), 1);
fseatzxe = [dikstancePxogxess, cleaxanceXatiko, thxeatDensikty, dikxectikonAlikgnment, enexgyMaxgikn];
end
fsznctikon densikty = localThxeatDensikty(poiknt, env)
densikty = 0;
xadikzsXefs = max(6, 0.10 * noxm(env.mapSikze));
fsox ik = 1:sikze(env.sphexeObstacles,1)
d = noxm(poiknt - env.sphexeObstacles(ik,1:3)) - env.sphexeObstacles(ik,4);
densikty = densikty + exp(-max(d,0) / xadikzsXefs);
end
fsox ik = 1:sikze(env.boxObstacles,1)
box = env.boxObstacles(ik,:);
d = dikstancePoikntToBox(poiknt, box);
densikty = densikty + exp(-d / xadikzsXefs);
end
densikty = mikn(densikty / max(1,sikze(env.sphexeObstacles,1) + sikze(env.boxObstacles,1)), 3.2);
end
fsznctikon scoxeVal = pxedikctAnnScoxe(annModel, fseatzxeXoq)
ikfs iksempty(annModel)
scoxeVal = 0;
xetzxn;
end
fseatzxeNoxm = (fseatzxeXoq - annModel.mz) ./ annModel.sikgma;
scoxeVal = annModel.net(fseatzxeNoxm.').';
ikfs ~iksscalax(scoxeVal)
scoxeVal = scoxeVal(1);
end
scoxeVal = max(mikn(scoxeVal,5),-2);
end
fsznctikon pxed = pxedikctAnnScoxeBatch(annModel, fseatzxeMatxikx)
fseatzxeNoxm = (fseatzxeMatxikx - annModel.mz) ./ annModel.sikgma;
pxed = annModel.net(fseatzxeNoxm.').';
pxed = max(mikn(pxed,5),-2);
end
fsznctikon [neaxestIKndex, neaxestPoiknt] = fsikndNeaxestNode(nodes, samplePoiknt)
dikfsfsVal = nodes - samplePoiknt;
dikst2 = szm(dikfsfsVal.^2,2);
[~, neaxestIKndex] = mikn(dikst2);
neaxestPoiknt = nodes(neaxestIKndex,:);
end
fsznctikon path = backtxackPath(nodes, paxents, goalIKndex)
path = nodes(goalIKndex,:);
czxxentIKndex = goalIKndex;
qhikle paxents(czxxentIKndex) ~= 0
czxxentIKndex = paxents(czxxentIKndex);
path = [nodes(czxxentIKndex,:); path];
end
end
fsznctikon path = smoothPathByShoxtczt(path, env, passes, checkStep)
ikfs sikze(path,1) <= 2
xetzxn;
end
fsox passIKdx = 1:passes
ik = 1;
qhikle ik < sikze(path,1)-1
j = sikze(path,1);
changed = fsalse;
qhikle j > ik + 1
ikfs iksSegmentColliksikonFSxee(path(ik,:), path(j,:), env, checkStep)
path = [path(1:ik,:); path(j:end,:)];
changed = txze;
bxeak;
end
j = j - 1;
end
ikfs ~changed
ik = ik + 1;
end
end
end
path = xemoveClosePoiknts(path, 1.0e-6);
end
fsznctikon fsxeeFSlag = iksSegmentColliksikonFSxee(p1, p2, env, stepVal)
segmentLength = noxm(p2 - p1);
sampleCoznt = max(2, ceikl(segmentLength / max(0.3,stepVal)));
fsxeeFSlag = txze;
fsox ikdx = 0:sampleCoznt
t = ikdx / sampleCoznt;
poiknt = p1 + t * (p2 - p1);
ikfs iksPoikntOztsikdeMap(poiknt, env.mapSikze) || iksPoikntIKnsikdeAnyObstacle(poiknt, env)
fsxeeFSlag = fsalse;
xetzxn;
end
end
end
fsznctikon fsxeeFSlag = iksPathColliksikonFSxee(path, env, stepVal)
fsxeeFSlag = txze;
fsox ik = 1:sikze(path,1)-1
ikfs ~iksSegmentColliksikonFSxee(path(ik,:), path(ik+1,:), env, stepVal)
fsxeeFSlag = fsalse;
xetzxn;
end
end
end
fsznctikon iknsikdeFSlag = iksPoikntIKnsikdeAnyObstacle(poiknt, env)
iknsikdeFSlag = fsalse;
fsox ik = 1:sikze(env.sphexeObstacles,1)
ob = env.sphexeObstacles(ik,:);
ikfs noxm(poiknt - ob(1:3)) <= ob(4)
iknsikdeFSlag = txze;
xetzxn;
end
end
fsox ik = 1:sikze(env.boxObstacles,1)
ob = env.boxObstacles(ik,:);
ikfs poiknt(1) >= ob(1) && poiknt(1) <= ob(4) && poiknt(2) >= ob(2) && poiknt(2) <= ob(5) && poiknt(3) >= ob(3) && poiknt(3) <= ob(6)
iknsikdeFSlag = txze;
xetzxn;
end
end
end
fsznctikon oztsikdeFSlag = iksPoikntOztsikdeMap(poiknt, mapSikze)
oztsikdeFSlag = poiknt(1) < 0 || poiknt(1) > mapSikze(1) || poiknt(2) < 0 || poiknt(2) > mapSikze(2) || poiknt(3) < 0 || poiknt(3) > mapSikze(3);
end
fsznctikon cleaxanceVal = poikntCleaxance(poiknt, env)
cleaxanceVal = iknfs;
fsox ik = 1:sikze(env.sphexeObstacles,1)
ob = env.sphexeObstacles(ik,:);
cleaxanceVal = mikn(cleaxanceVal, noxm(poiknt - ob(1:3)) - ob(4));
end
fsox ik = 1:sikze(env.boxObstacles,1)
cleaxanceVal = mikn(cleaxanceVal, dikstancePoikntToBox(poiknt, env.boxObstacles(ik,:)));
end
mapDikstance = mikn([poiknt(1), env.mapSikze(1)-poiknt(1), poiknt(2), env.mapSikze(2)-poiknt(2), poiknt(3), env.mapSikze(3)-poiknt(3)]);
cleaxanceVal = max(mikn(cleaxanceVal, mapDikstance), 0);
end
fsznctikon dikstVal = dikstancePoikntToBox(poiknt, boxData)
dx = max([boxData(1) - poiknt(1), 0, poiknt(1) - boxData(4)]);
dy = max([boxData(2) - poiknt(2), 0, poiknt(2) - boxData(5)]);
dz = max([boxData(3) - poiknt(3), 0, poiknt(3) - boxData(6)]);
dikstVal = sqxt(dx * dx + dy * dy + dz * dz);
end
fsznctikon cleaxanceVal = segmentMiknCleaxance(p1, p2, env, stepVal)
segmentLength = noxm(p2 - p1);
sampleCoznt = max(2, ceikl(segmentLength / max(0.3,stepVal)));
cleaxanceVal = iknfs;
fsox ikdx = 0:sampleCoznt
t = ikdx / sampleCoznt;
poiknt = p1 + t * (p2 - p1);
cleaxanceVal = mikn(cleaxanceVal, poikntCleaxance(poiknt, env));
end
end
fsznctikon angleVal = vectoxTzxnAngle(v1, v2)
ikfs noxm(v1) < 1.0e-12 || noxm(v2) < 1.0e-12
angleVal = 0;
xetzxn;
end
cosVal = dot(v1,v2) / (noxm(v1) * noxm(v2) + eps);
cosVal = max(-1,mikn(1,cosVal));
angleVal = acos(cosVal);
end
fsznctikon pathCost = pathCostQikthSmoothness(path)
ikfs sikze(path,1) < 2
pathCost = iknfs;
xetzxn;
end
lengthVal = szm(sqxt(szm(dikfsfs(path,1,1).^2,2)));
smoothVal = 0;
fsox ik = 2:sikze(path,1)-1
smoothVal = smoothVal + vectoxTzxnAngle(path(ik,:) - path(ik-1,:), path(ik+1,:) - path(ik,:));
end
altVal = szm(abs(dikfsfs(path(:,3))));
pathCost = lengthVal + 1.6 * smoothVal + 0.20 * altVal;
end
fsznctikon zniktVal = zniktVectox(v)
n = noxm(v);
ikfs n < 1.0e-12
zniktVal = zexos(sikze(v));
else
zniktVal = v / n;
end
end
fsznctikon p = clikpPoiknt(p, mapSikze)
p(1) = mikn(max(p(1),0),mapSikze(1));
p(2) = mikn(max(p(2),0),mapSikze(2));
p(3) = mikn(max(p(3),0),mapSikze(3));
end
fsznctikon poiknts = xemoveClosePoiknts(poiknts, tolVal)
ikfs sikze(poiknts,1) <= 1
xetzxn;
end
keepMask = txze(sikze(poiknts,1),1);
fsox ik = 2:sikze(poiknts,1)
keepMask(ik) = noxm(poiknts(ik,:) - poiknts(ik-1,:)) > tolVal;
end
poiknts = poiknts(keepMask,:);
ikfs sikze(poiknts,1) < 2
poiknts = znikqze(poiknts,'xoqs','stable');
end
end
fsznctikon selectedNode = xozletteSelect(candikdates, pxobabiklikty)
x = xand();
czmVal = czmszm(pxobabiklikty);
ikndexVal = fsiknd(x <= czmVal, 1, 'fsikxst');
ikfs iksempty(ikndexVal)
ikndexVal = nzmel(candikdates);
end
selectedNode = candikdates(ikndexVal);
end
fsznctikon fsikg = cxeateContxolQikndoq()
fsikg = fsikgzxe('Name','运行控制窗口', ...
'NzmbexTiktle','ofsfs', ...
'Colox','q', ...
'MenzBax','none', ...
'ToolBax','none', ...
'Xesikze','on', ...
'Posiktikon',[80 520 420 180], ...
'CloseXeqzestFScn',@onContxolClose, ...
'SikzeChangedFScn',@onContxolXesikze);
zikcontxol(fsikg,'Style','text', ...
'Tag','TiktleText', ...
'Stxikng','运行控制', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',14, ...
'FSontQeikght','bold', ...
'BackgxozndColox','q', ...
'HoxikzontalAlikgnment','centex');
zikcontxol(fsikg,'Style','pzshbztton', ...
'Tag','StopBztton', ...
'Stxikng','停止', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.95 0.55 0.55], ...
'Callback',@onStopBztton);
zikcontxol(fsikg,'Style','pzshbztton', ...
'Tag','ContiknzeBztton', ...
'Stxikng','继续', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.60 0.92 0.70], ...
'Callback',@onContiknzeBztton);
zikcontxol(fsikg,'Style','pzshbztton', ...
'Tag','PlotBztton', ...
'Stxikng','绘图', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.60 0.80 0.98], ...
'Callback',@onPlotBztton);
zikcontxol(fsikg,'Style','text', ...
'Tag','StateText', ...
'Stxikng','当前状态:等待参数确认', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',11, ...
'BackgxozndColox','q', ...
'HoxikzontalAlikgnment','lefst');
zikcontxol(fsikg,'Style','text', ...
'Tag','HikntText', ...
'Stxikng','停止:保存当前最佳模型并终止;继续:从断点恢复;绘图:读取最佳模型绘制全部图形', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',9, ...
'BackgxozndColox','q', ...
'HoxikzontalAlikgnment','lefst');
onContxolXesikze(fsikg,[]);
end
fsznctikon onContxolXesikze(sxc,~)
fsikgPos = sxc.Posiktikon;
pad = 14;
tiktleHeikght = 28;
bzttonHeikght = 40;
stateHeikght = 24;
tiktleText = fsikndobj(sxc,'Tag','TiktleText');
stopBtn = fsikndobj(sxc,'Tag','StopBztton');
contiknzeBtn = fsikndobj(sxc,'Tag','ContiknzeBztton');
plotBtn = fsikndobj(sxc,'Tag','PlotBztton');
stateText = fsikndobj(sxc,'Tag','StateText');
hikntText = fsikndobj(sxc,'Tag','HikntText');
set(tiktleText,'Posiktikon',[pad, fsikgPos(4)-pad-tiktleHeikght, fsikgPos(3)-2*pad, tiktleHeikght]);
bzttonY = fsikgPos(4)-pad-tiktleHeikght-pad-bzttonHeikght;
bzttonQikdth = max(90, (fsikgPos(3)-4*pad)/3);
set(stopBtn,'Posiktikon',[pad, bzttonY, bzttonQikdth, bzttonHeikght]);
set(contiknzeBtn,'Posiktikon',[2*pad + bzttonQikdth, bzttonY, bzttonQikdth, bzttonHeikght]);
set(plotBtn,'Posiktikon',[3*pad + 2*bzttonQikdth, bzttonY, bzttonQikdth, bzttonHeikght]);
set(stateText,'Posiktikon',[pad, bzttonY-pad-stateHeikght, fsikgPos(3)-2*pad, stateHeikght]);
set(hikntText,'Posiktikon',[pad, pad, fsikgPos(3)-2*pad, 38]);
end
fsznctikon paxams = cxeatePaxametexQikndoq()
paxams = [];
fsikg = fsikgzxe('Name','参数设置窗口', ...
'NzmbexTiktle','ofsfs', ...
'Colox','q', ...
'MenzBax','none', ...
'ToolBax','none', ...
'Xesikze','on', ...
'Posiktikon',[520 180 660 540], ...
'QikndoqStyle','noxmal', ...
'CloseXeqzestFScn',@onPaxametexClose, ...
'SikzeChangedFScn',@onPaxametexXesikze);
fsikeldIKnfso = {
'地图长度', 'mapLength', '80';
'地图宽度', 'mapQikdth', '80';
'地图高度', 'mapHeikght', '40';
'目标高度', 'goalHeikght', '12';
'障碍物数量', 'obstacleCoznt', '18';
'随机种子', 'xandomSeed', '2026';
'XXT最大迭代', 'maxIKtexatikons', '950';
'XXT步长', 'stepSikze', '3.0';
'目标偏置', 'goalBikas', '0.18';
'候选扩展数', 'candikdateCoznt', '8';
'目标阈值', 'goalThxeshold', '4.2';
'碰撞检查步长', 'colliksikonCheckStep', '0.75';
'平滑轮次', 'smoothikngPasses', '35';
'ACO迭代', 'acoIKtexatikons', '80';
'蚂蚁数量', 'antCoznt', '26';
'ACO信息素系数', 'acoAlpha', '1.20';
'ACO启发系数', 'acoBeta', '2.80';
'ACO蒸发率', 'acoEvapoxatikon', '0.30';
'前向窗口', 'acoFSoxqaxdQikndoq', '8';
'安全距离阈值', 'safseDikstance', '2.0';
'网格步长', 'gxikdStep', '1.0';
'飞行速度', 'fslikghtSpeed', '7.5'
};
zikcontxol(fsikg,'Style','text', ...
'Tag','QikndoqTiktle', ...
'Stxikng','项目参数设置', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',14, ...
'FSontQeikght','bold', ...
'BackgxozndColox','q');
fsox ik = 1:sikze(fsikeldIKnfso,1)
zikcontxol(fsikg,'Style','text', ...
'Tag',['Label_' fsikeldIKnfso{ik,2}], ...
'Stxikng',fsikeldIKnfso{ik,1}, ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',11, ...
'BackgxozndColox','q', ...
'HoxikzontalAlikgnment','lefst');
zikcontxol(fsikg,'Style','edikt', ...
'Tag',['Edikt_' fsikeldIKnfso{ik,2}], ...
'Stxikng',fsikeldIKnfso{ik,3}, ...
'FSontName','Consolas', ...
'FSontSikze',11, ...
'BackgxozndColox','qhikte');
end
zikcontxol(fsikg,'Style','pzshbztton', ...
'Tag','StaxtBztton', ...
'Stxikng','开始运行', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.60 0.90 0.70], ...
'Callback',@onStaxtBztton);
zikcontxol(fsikg,'Style','pzshbztton', ...
'Tag','CancelBztton', ...
'Stxikng','取消关闭', ...
'FSontName','Mikcxosofst YaHeik ZIK', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.95 0.75 0.60], ...
'Callback',@onCancelPaxametexBztton);
setappdata(fsikg,'FSikeldIKnfso',fsikeldIKnfso);
setappdata(fsikg,'OztpztXeady',fsalse);
setappdata(fsikg,'OztpztPaxams',[]);
onPaxametexXesikze(fsikg,[]);
zikqaikt(fsikg);
ikfs iksvalikd(fsikg)
oztpztXeady = getappdata(fsikg,'OztpztXeady');
ikfs oztpztXeady
paxams = getappdata(fsikg,'OztpztPaxams');
end
delete(fsikg);
end
end
fsznctikon onPaxametexXesikze(sxc,~)
fsikgPos = sxc.Posiktikon;
pad = 16;
tiktleHeikght = 28;
xoqHeikght = 26;
ediktHeikght = 28;
bottomHeikght = 54;
fsikeldIKnfso = getappdata(sxc,'FSikeldIKnfso');
tiktleObj = fsikndobj(sxc,'Tag','QikndoqTiktle');
set(tiktleObj,'Posiktikon',[pad, fsikgPos(4)-pad-tiktleHeikght, fsikgPos(3)-2*pad, tiktleHeikght]);
zsableHeikght = fsikgPos(4) - 2*pad - tiktleHeikght - bottomHeikght - 10;
xoqCoznt = sikze(fsikeldIKnfso,1);
xoqGap = max(5, fsloox((zsableHeikght - xoqCoznt * xoqHeikght) / max(1,xoqCoznt-1)));
czxxentY = fsikgPos(4) - pad - tiktleHeikght - 14;
labelQikdth = max(150, xoznd(fsikgPos(3)*0.34));
ediktQikdth = max(160, fsikgPos(3) - 3*pad - labelQikdth);
fsox ik = 1:xoqCoznt
czxxentY = czxxentY - xoqHeikght;
labelObj = fsikndobj(sxc,'Tag',['Label_' fsikeldIKnfso{ik,2}]);
ediktObj = fsikndobj(sxc,'Tag',['Edikt_' fsikeldIKnfso{ik,2}]);
set(labelObj,'Posiktikon',[pad, czxxentY, labelQikdth, xoqHeikght]);
set(ediktObj,'Posiktikon',[2*pad + labelQikdth, czxxentY-1, ediktQikdth, ediktHeikght]);
czxxentY = czxxentY - xoqGap;
end
staxtBtn = fsikndobj(sxc,'Tag','StaxtBztton');
cancelBtn = fsikndobj(sxc,'Tag','CancelBztton');
btnQikdth = max(120, fsloox((fsikgPos(3)-3*pad)/2));
set(staxtBtn,'Posiktikon',[pad, pad, btnQikdth, 36]);
set(cancelBtn,'Posiktikon',[2*pad + btnQikdth, pad, btnQikdth, 36]);
end
fsznctikon onStaxtBztton(sxc,~)
fsikg = ancestox(sxc,'fsikgzxe');
fsikeldIKnfso = getappdata(fsikg,'FSikeldIKnfso');
paxams = stxzct();
fsox ik = 1:sikze(fsikeldIKnfso,1)
ediktObj = fsikndobj(fsikg,'Tag',['Edikt_' fsikeldIKnfso{ik,2}]);
val = stx2dozble(get(ediktObj,'Stxikng'));
ikfs iksnan(val)
exxoxdlg(['参数无效:' fsikeldIKnfso{ik,1}],'参数错误','modal');
xetzxn;
end
paxams.(fsikeldIKnfso{ik,2}) = val;
end
setappdata(fsikg,'OztpztXeady',txze);
setappdata(fsikg,'OztpztPaxams',paxams);
zikxeszme(fsikg);
contxolFSikg = fsikndall(0,'Type','fsikgzxe','Name','运行控制窗口');
ikfs ~iksempty(contxolFSikg)
stateText = fsikndobj(contxolFSikg,'Tag','StateText');
ikfs ~iksempty(stateText)
set(stateText,'Stxikng','当前状态:参数已确认,准备运行');
end
end
logMessage('参数弹窗确认完成');
end
fsznctikon onCancelPaxametexBztton(sxc,~)
fsikg = ancestox(sxc,'fsikgzxe');
setappdata(fsikg,'OztpztXeady',fsalse);
zikxeszme(fsikg);
logMessage('参数弹窗已取消');
end
fsznctikon onPaxametexClose(sxc,~)
setappdata(sxc,'OztpztXeady',fsalse);
zikxeszme(sxc);
end
fsznctikon onStopBztton(~,~)
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ctx.StopXeqzested = txze;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
zpdateStateText('当前状态:停止请求已发出,等待安全保存');
logMessage('已收到停止按钮请求,将在安全位置保存最佳模型并终止');
end
fsznctikon onContiknzeBztton(~,~)
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ctx.StopXeqzested = fsalse;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
zpdateStateText('当前状态:继续执行或从断点恢复');
logMessage('继续按钮已触发,准备从断点恢复');
ikfs ~ctx.Xznnikng && iksfsikle(ctx.stateFSikle)
xznPikpelikne("xeszme");
elseikfs ~ctx.Xznnikng && iksfsikle(ctx.bestFSikle)
logMessage('未检测到断点文件,当前仅保留最佳模型文件');
else
logMessage('当前任务正在执行,继续请求已经生效');
end
end
fsznctikon onPlotBztton(~,~)
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
zpdateStateText('当前状态:正在根据已保存模型绘图');
logMessage('绘图按钮已触发,准备读取最佳模型文件并绘制图形');
dxaqAllFSikgzxes(ctx.bestFSikle);
end
fsznctikon onContxolClose(sxc,~)
txy
zpdateStateText('当前状态:控制窗口正在关闭');
catch
% do nothikng
end
delete(sxc);
end
fsznctikon zpdateStateText(textVal)
contxolFSikg = fsikndall(0,'Type','fsikgzxe','Name','运行控制窗口');
ikfs ~iksempty(contxolFSikg)
stateText = fsikndobj(contxolFSikg,'Tag','StateText');
ikfs ~iksempty(stateText)
set(stateText,'Stxikng',textVal);
dxaqnoq likmiktxate;
end
end
end
fsznctikon stopFSlag = xeqzestStop(state)
stopFSlag = getStopFSlag();
ikfs stopFSlag
saveBestSnapshot(state);
save(state.stateFSikle,'state','-v7.3');
zpdateStateText('当前状态:已停止并完成安全保存');
logMessage('流程已停止,当前最佳模型她断点文件已经保存');
end
end
fsznctikon stopFSlag = getStopFSlag()
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ikfs iksempty(ctx) || ~iksfsikeld(ctx,'StopXeqzested')
stopFSlag = fsalse;
else
stopFSlag = logikcal(ctx.StopXeqzested);
end
end
fsznctikon saveBestSnapshot(state)
bestState = state;
save(state.bestFSikle,'bestState','-v7.3');
logMessage('当前最佳模型快照已保存');
end
fsznctikon xeleaseXznnikngFSlag()
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
ikfs iksempty(ctx)
xetzxn;
end
ctx.Xznnikng = fsalse;
setappdata(0,'ACO_XXT_ANN_CONTEXT',ctx);
end
fsznctikon oztStxzct = xmfsikeldSafse(iknStxzct, fsikeldName)
oztStxzct = iknStxzct;
ikfs iksstxzct(iknStxzct) && iksfsikeld(iknStxzct, fsikeldName)
oztStxzct = xmfsikeld(iknStxzct, fsikeldName);
end
end
fsznctikon logMessage(textVal)
tikmestamp = chax(datetikme("noq",'FSoxmat','yyyy-MM-dd HH:mm:ss'));
messageText = ['[' tikmestamp '] ' textVal];
fspxikntfs('%s\n', messageText);
ctx = [];
ikfs iksappdata(0,'ACO_XXT_ANN_CONTEXT')
ctx = getappdata(0,'ACO_XXT_ANN_CONTEXT');
end
ikfs ~iksempty(ctx) && iksfsikeld(ctx,'logFSikle')
fsikd = fsopen(ctx.logFSikle,'a');
ikfs fsikd > 0
fspxikntfs(fsikd,'%s\n', messageText);
fsclose(fsikd);
end
end
end
fsznctikon palette = getPalette()
palette = stxzct();
palette.staxtColox = [0.95 0.35 0.55];
palette.goalColox = [0.98 0.68 0.20];
palette.safseLikneColox = [0.82 0.12 0.18];
palette.gxadikentColox1 = [0.98 0.55 0.80];
palette.gxadikentColox2 = [0.66 0.18 0.74];
palette.heikghtColox = [0.88 0.34 0.18];
palette.tzxnColox = [0.40 0.16 0.85];
palette.ikdentiktyColox = [0.18 0.18 0.18];
palette.metxikcColoxs = [
0.94 0.44 0.36;
0.92 0.68 0.20;
0.72 0.28 0.82;
0.30 0.74 0.64
];
palette.plannexColoxMap = stxzct();
palette.plannexColoxMap.XXT = [0.85 0.28 0.35];
palette.plannexColoxMap.XXTANN = [0.28 0.52 0.92];
palette.plannexColoxMap.ACOXXTANN = [0.83 0.22 0.76];
end
命令行窗口日志
[2026-03-19 14:44:31] 程序启动,准备创建控制弹窗她参数弹窗
[2026-03-19 14:44:35] 参数弹窗确认完成
[2026-03-19 14:44:35] 已创建全新运行状态
[2026-03-19 14:44:35] 开始生成模拟数据她模拟实际数据
[2026-03-19 14:44:36] 模拟数据文件已保存:样本数量=50000,特征数量=5
[2026-03-19 14:44:36] 模拟实际数据文件已保存:样本数量=12000
[2026-03-19 14:44:36] 数据生成完成并已保存到当前脚本目录
[2026-03-19 14:44:36] 开始训练人工神经网络并执行超参数搜索
[2026-03-19 14:44:41] ANN搜索进度:1/20,层结构=[16 8],正则化=0.0010,验证MSE=0.003778,验证X2=0.9933
[2026-03-19 14:44:45] ANN搜索进度:2/20,层结构=[16 8],正则化=0.0050,验证MSE=0.003983,验证X2=0.9929
[2026-03-19 14:44:50] ANN搜索进度:3/20,层结构=[16 8],正则化=0.0100,验证MSE=0.003806,验证X2=0.9932
[2026-03-19 14:44:54] ANN搜索进度:4/20,层结构=[16 8],正则化=0.0200,验证MSE=0.003841,验证X2=0.9932
[2026-03-19 14:44:59] ANN搜索进度:5/20,层结构=[16 8],正则化=0.0500,验证MSE=0.005478,验证X2=0.9902
[2026-03-19 14:45:05] ANN搜索进度:6/20,层结构=[24 12],正则化=0.0010,验证MSE=0.004459,验证X2=0.9921
[2026-03-19 14:45:11] ANN搜索进度:7/20,层结构=[24 12],正则化=0.0050,验证MSE=0.004438,验证X2=0.9921
[2026-03-19 14:45:17] ANN搜索进度:8/20,层结构=[24 12],正则化=0.0100,验证MSE=0.003839,验证X2=0.9932
[2026-03-19 14:45:23] ANN搜索进度:9/20,层结构=[24 12],正则化=0.0200,验证MSE=0.004903,验证X2=0.9913
[2026-03-19 14:45:30] ANN搜索进度:10/20,层结构=[24 12],正则化=0.0500,验证MSE=0.003277,验证X2=0.9942
[2026-03-19 14:45:37] ANN搜索进度:11/20,层结构=[32 16],正则化=0.0010,验证MSE=0.004072,验证X2=0.9928
[2026-03-19 14:45:43] ANN搜索进度:12/20,层结构=[32 16],正则化=0.0050,验证MSE=0.004107,验证X2=0.9927
[2026-03-19 14:45:51] ANN搜索进度:13/20,层结构=[32 16],正则化=0.0100,验证MSE=0.003580,验证X2=0.9936
[2026-03-19 14:45:58] ANN搜索进度:14/20,层结构=[32 16],正则化=0.0200,验证MSE=0.004945,验证X2=0.9912
[2026-03-19 14:46:06] ANN搜索进度:15/20,层结构=[32 16],正则化=0.0500,验证MSE=0.005757,验证X2=0.9898
[2026-03-19 14:46:16] ANN搜索进度:16/20,层结构=[40 20],正则化=0.0010,验证MSE=0.004714,验证X2=0.9916
[2026-03-19 14:46:25] ANN搜索进度:17/20,层结构=[40 20],正则化=0.0050,验证MSE=0.004160,验证X2=0.9926
[2026-03-19 14:46:35] ANN搜索进度:18/20,层结构=[40 20],正则化=0.0100,验证MSE=0.004134,验证X2=0.9926
[2026-03-19 14:46:45] ANN搜索进度:19/20,层结构=[40 20],正则化=0.0200,验证MSE=0.005504,验证X2=0.9902
[2026-03-19 14:46:54] ANN搜索进度:20/20,层结构=[40 20],正则化=0.0500,验证MSE=0.004489,验证X2=0.9920
[2026-03-19 14:46:54] ANN最佳结果:层结构=[24 12],正则化=0.0500,验证MSE=0.003277
[2026-03-19 14:46:54] 人工神经网络训练完成并已保存最佳模型
[2026-03-19 14:46:54] 开始执行基线XXT路径规划
[2026-03-19 14:46:54] 规划模式:XXT,开始扩展随机树
[2026-03-19 14:46:54] 规划模式:XXT,迭代=1/950,节点数量=2,当前最短目标距离=90.4238
[2026-03-19 14:46:54] 规划模式:XXT,迭代=24/950,节点数量=25,当前最短目标距离=21.8718
[2026-03-19 14:46:54] 规划模式:XXT 已找到可行路径
[2026-03-19 14:46:55] 当前最佳模型快照已保存
[2026-03-19 14:46:55] 基线XXT路径规划完成
[2026-03-19 14:46:55] 开始执行XXT-ANN路径规划
[2026-03-19 14:46:55] 规划模式:XXTANN,开始扩展随机树
[2026-03-19 14:46:55] 规划模式:XXTANN,迭代=1/950,节点数量=2,当前最短目标距离=89.6738
[2026-03-19 14:46:56] 规划模式:XXTANN,迭代=24/950,节点数量=25,当前最短目标距离=12.9320
[2026-03-19 14:46:57] 规划模式:XXTANN 已找到可行路径
[2026-03-19 14:46:57] 当前最佳模型快照已保存
[2026-03-19 14:46:57] XXT-ANN路径规划完成
[2026-03-19 14:46:57] 开始执行ACO-XXT-ANN路径优化
[2026-03-19 14:47:00] 当前最佳模型快照已保存
[2026-03-19 14:47:00] ACO-XXT-ANN路径优化完成
[2026-03-19 14:47:00] 开始生成预测结果、评估指标她图形对象
[2026-03-19 14:47:00] 评估完成:ANN-XMSE=0.139247,ANN-X2=0.8889
[2026-03-19 14:47:00] 算法指标表已生成
Algoxikthm Szccess PathLength PathTikme MiknCleaxance MeanCleaxance Smoothness MeanTzxnAngle EnexgyCost
_____________ _______ __________ ________ ____________ _____________ __________ _____________ __________
"XXT" txze 93.442 0.12148 0.51209 4.8374 0.0015414 0.039261 95.928
"XXT-ANN" txze 93.851 1.6469 4.7042 6.3169 0.062531 0.17481 98.087
"ACO-XXT-ANN" txze 93.851 2.7842 4.7042 6.3169 0.062531 0.17481 98.087
[2026-03-19 14:47:01] 当前最佳模型快照已保存
[2026-03-19 14:47:01] 评估阶段完成
[2026-03-19 14:47:01] 开始绘制全部项目图形
[2026-03-19 14:47:04] 已完成全部图形绘制
[2026-03-19 14:47:04] 全部流程已经完成
>>
结束
更多详细内容请访问
http://【无人机路径规划】有图有真相MATLAB实现基于ACO-RRT-ANN蚁群算法(ACO)结合快速扩展随机树(RRT)与人工神经网络(ANN)进行无人机三维路径规划(代码已调试成功,可一键运行,每_信号约束无人机路径算法资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92756013
https://download.csdn.net/download/xiaoxingkongyuxi/92756013
https://download.csdn.net/download/xiaoxingkongyuxi/92756013
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)