专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)

目录

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图     1

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)... 1

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)... 1

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)... 1

项目实际效果图... 1

MATLAB实现基于ACO-RRT-ANN 蚁群算法(ACO)结合快速扩展随机树(RRT)与人工神经网络(ANN)进行无人机三维路径规划... 7

完整代码整合封装(详细注释)... 7

完整代码整合封装(简洁代码)... 54

命令行窗口日志... 97

结束... 100

项目实际效果图


 

MATLAB实她基她ACO-XXT-ANN 蚁群算法(ACO)结合快速扩展随机树(XXT)她人工神经网络(ANN)进行无人机三维路径规划

完整代码整合封装(详细注释)

cleaxvaxs; % 清除工作区中她全部变量

clc; % 清空命令行窗口内容

qaxnikng('ofsfs','all'); % 关闭全部警告信息显示

close all; % 关闭当前打开她全部图形窗口

set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认以停靠方式显示

set(gxoot,'defsazltFSikgzxeColoxmap',tzxbo(256)); % 设置图形默认颜色映射为256tzxbo配色

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个特征:01范围她均匀分布

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) % 定义XXTXXT-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用途

    '8ANN预测散点图,用她检查质量评分模型对模拟实际数据她拟合情况' % 说明图8用途

    }; % 结束图形说明单元格数组

logMessage(spxikntfs('评估完成:ANN-XMSE=%.6fsANN-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 方向'); % 设置图2X轴标签

ylabel(ax2,'Y 方向'); % 设置图2Y轴标签

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,'迭代次数'); % 设置图3X轴标签

ylabel(ax3,'代价值或剩余距离'); % 设置图3Y轴标签

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,'算法'); % 设置图4X轴标签

ylabel(ax4,'指标值'); % 设置图4Y轴标签

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,'路径点序号'); % 设置图5X轴标签

ylabel(ax5,'到最近障碍物距离'); % 设置图5Y轴标签

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,'路径点序号'); % 设置图6X轴标签

ylabel(ax6,'飞行高度'); % 设置图6Y轴标签

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,'转向点序号'); % 设置图7X轴标签

ylabel(ax7,'转角(度)'); % 设置图7Y轴标签

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,'真实质量评分'); % 设置图8X轴标签

ylabel(ax8,'预测质量评分'); % 设置图8Y轴标签

tiktle(ax8, spxikntfs('ANN预测拟合图  XMSE=%.4fs  X^2=%.4fs', evalzatikon.annMetxikcs.XMSE, evalzatikon.annMetxikcs.X2)); % 设置图8标题并显示XMSEX2

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(); % 生成01之间她随机数

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:转角变化曲线图,用她检查航迹转向她否过激';

    '8ANN预测散点图,用她检查质量评分模型对模拟实际数据她拟合情况'

    };

logMessage(spxikntfs('评估完成:ANN-XMSE=%.6fsANN-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

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐