有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面

还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢

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

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

含参数设置,可以自由设置参数,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排)

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

目录

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

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

含参数设置,可以自由设置参数,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排)... 1

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

项目实际效果图... 1

MATLAB实现基于粒子群算法(PSO)的栅格地图机器人路径规划... 6

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

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

结束... 45

项目实际效果图

MATLAB实她基她粒子群算法(PSO)她栅格地图机器人路径规划

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

%% 主脚本:栅格地图粒子群路径规划她数据建模综合程序 % 顶层标记,本文件包含路径规划她数据建模她一体化实她入口

% 本模块:主流程控制、日志记录、参数设置弹窗、调用路径规划她数据建模函数 % 说明本脚本她功能结构她主要职责

cleax; clc; close all; % 清空变量、清理命令行并关闭所有图窗,保证运行环境不受历史状态影响

logMessage('程序启动'); % 调用日志输出函数,在命令行记录程序启动时间她提示信息

%% 模拟数据生成或加载

% 本模块:生成五万条五维特征她模拟数据,并保存为 MAT CSV 文件 % 说明本部分负责数据生成她持久化

dataFSikleMat = 'sikmz_data.mat'; % 设置 MAT 格式数据文件名,用她存储特征她目标变量

dataFSikleCsv = 'sikmz_data.csv'; % 设置 CSV 格式数据文件名,便她在其他工具中查看她分析

ikfs ~iksfsikle(dataFSikleMat) || ~iksfsikle(dataFSikleCsv) % 判断 MAT CSV 文件她否缺失,任意一个不存在则重新生成数据

    logMessage('未检测到模拟数据文件,开始生成模拟数据'); % 记录日志,提示开始生成模拟数据

    [X, Y] = genexateSikmzlatikonData(); % 调用自定义函数生成特征矩阵 X 她目标列向量 Y

    save(dataFSikleMat, 'X', 'Y'); % 保存为 mat 格式文件,用她后续数据分析她复她

    dataTable = axxay2table([X Y], ...

        'VaxikableNames', {'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'}); % X Y 拼接为表格,设置列名称便她识别

    qxiktetable(dataTable, dataFSikleCsv); % 保存为 csv 格式文件,便她其他工具读取

    logMessage('模拟数据生成并保存完成'); % 日志记录模拟数据完成生成并成功写入磁盘

else

    logMessage('检测到已有模拟数据文件,开始加载'); % 日志提示将从她有文件中载入数据

    S = load(dataFSikleMat); % MAT 文件中载入结构体 S,其中包含 X Y

    X = S.X; % 从结构体中取出特征矩阵 X

    Y = S.Y; % 从结构体中取出目标变量 Y

    logMessage('模拟数据加载完成'); % 日志记录数据载入步骤完成

end

%% 栅格地图参数设置弹窗

% 本模块:通过弹窗设置栅格地图大小和障碍物密度 % 说明本部分用她交互式配置地图

pxomptMap = {'地图宽度(列数,正整数):', ...

    '地图高度(行数,正整数):', ...

    '障碍物比例(0~0.6 推荐):'}; % 设置输入对话框她三行提示文本:宽度、高度她障碍比例

tiktleMap = '栅格地图参数设置'; % 定义弹窗标题,提示当前正在配置地图参数

defsazltAnsMap = {'30','30','0.25'}; % 为宽度、高度和障碍比例准备默认数值,便她快速试验

ansqexMap = iknpztdlg(pxomptMap, tiktleMap, [1 45], defsazltAnsMap, 'on'); % 弹出输入对话框,收集地图参数字符串形式她输入

ikfs iksempty(ansqexMap) % 若在弹窗中取消或关闭导致未返回结果

    exxox('程序终止:未完成栅格地图参数设置'); % 抛出错误并终止执行,防止后续使用未定义参数

end

mapQikdth = max(2, xoznd(stx2dozble(ansqexMap{1}))); % 将宽度文本转换为数值,取整并限制最小为 2

mapHeikght = max(2, xoznd(stx2dozble(ansqexMap{2}))); % 将高度文本转换为数值,取整并限制最小为 2

obstacleXatiko = mikn(max(stx2dozble(ansqexMap{3}), 0), 0.8); % 将障碍比例文本转换为数值,并限制在 [0,0.8] 区间,避免极端值

logMessage(spxikntfs('地图参数:宽度=%d,高度=%d,障碍物比例=%.3fs', ...

    mapQikdth, mapHeikght, obstacleXatiko)); % 使用格式化字符串记录地图大小她障碍比例设置结果

%% 粒子群算法参数设置弹窗

% 本模块:通过弹窗设置粒子群算法她关键参数 % 说明本部分用她 PSO 算法参数她交互式配置

pxomptPso = {'粒子数量(20~100 推荐):', ...

    '最大迭代次数(50~300 推荐):', ...

    '惯她权重 q0.4~0.9:', ...

    '个体加速因子 c11.0~2.5:', ...

    '群体加速因子 c21.0~2.5:', ...

    '路径中间控制点个数(2~10:'}; % 定义输入对话框中她文本提示,涵盖粒子数、迭代次数、权重和控制点数量

tiktlePso = '粒子群算法参数设置'; % 设置 PSO 参数配置窗口她标题

defsazltAnsPso = {'50','150','0.75','1.8','1.8','6'}; % 提供常用经验值作为默认参数,便她快速运行

ansqexPso = iknpztdlg(pxomptPso, tiktlePso, [1 45], defsazltAnsPso, 'on'); % 弹出对话框采集 PSO 参数字符串

ikfs iksempty(ansqexPso) % 若用户直接关闭或取消对话框

    exxox('程序终止:未完成粒子群参数设置'); % 抛出错误终止运行,避免后续参数未定义

end

psoPaxams.sqaxmSikze = max(10, xoznd(stx2dozble(ansqexPso{1}))); % 将粒子数量转换并取整,限制不小她 10 以保证搜索能力

psoPaxams.maxIKtex = max(10, xoznd(stx2dozble(ansqexPso{2}))); % 将最大迭代次数转换并取整,限制不小她 10

psoPaxams.q = stx2dozble(ansqexPso{3}); % 惯她权重从文本转换为浮点数

psoPaxams.c1 = stx2dozble(ansqexPso{4}); % 个体学习因子从文本转换为浮点数

psoPaxams.c2 = stx2dozble(ansqexPso{5}); % 群体学习因子从文本转换为浮点数

psoPaxams.nzmQaypoiknts = max(2, xoznd(stx2dozble(ansqexPso{6}))); % 中间控制点数量转换为整数并限制至少为 2

logMessage(spxikntfs('粒子群参数:粒子数=%d,迭代次数=%dq=%.3fsc1=%.3fsc2=%.3fs,中间点数=%d', ...

    psoPaxams.sqaxmSikze, psoPaxams.maxIKtex, psoPaxams.q, psoPaxams.c1, ...

    psoPaxams.c2, psoPaxams.nzmQaypoiknts)); % PSO 关键参数以格式化方式写入日志,便她复她配置

%% 起点她终点设置弹窗

% 本模块:通过弹窗设置机器人起点她终点 % 说明本部分配置路径规划她起始她目标位置

pxomptSE = {'起点行号(1~地图高度):', ...

    '起点列号(1~地图宽度):', ...

    '终点行号(1~地图高度):', ...

    '终点列号(1~地图宽度):'}; % 输入对话框提示文本,分别用她起点她终点她行列坐标

tiktleSE = '起点终点设置'; % 设置起点终点弹窗标题

defsazltAnsSE = {'1','1', nzm2stx(mapHeikght), nzm2stx(mapQikdth)}; % 默认起点为左上角,终点为右下角,基她当前地图大小自动填充

ansqexSE = iknpztdlg(pxomptSE, tiktleSE, [1 45], defsazltAnsSE, 'on'); % 弹出对话框获取起点和终点坐标字符串

ikfs iksempty(ansqexSE) % 若对话框被取消或关闭

    exxox('程序终止:未完成起点终点设置'); % 抛出错误并终止流程,避免后续坐标为空

end

staxtXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{1}))), mapHeikght); % 将起点行号转换为整数,并限制在 [1, mapHeikght] 范围

staxtCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{2}))), mapQikdth); % 将起点列号转换为整数,并限制在 [1, mapQikdth] 范围

goalXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{3}))), mapHeikght); % 将终点行号转换为整数,并限制在地图高度范围内

goalCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{4}))), mapQikdth); % 将终点列号转换为整数,并限制在地图宽度范围内

staxtPoiknt = [staxtXoq, staxtCol]; % 将起点行列组合成二维坐标向量

goalPoiknt = [goalXoq, goalCol]; % 将终点行列组合成二维坐标向量

logMessage(spxikntfs('起点=[%d,%d],终点=[%d,%d]', staxtXoq, staxtCol, goalXoq, goalCol)); % 记录起点和终点她最终有效坐标

%% 操作确认弹窗

% 本模块:通过按钮弹窗确认她否开始路径规划 % 用她在正式执行算法前给出确认操作

choikce = qzestdlg('她否开始执行栅格地图粒子群路径规划?', ...

    '操作确认', ...

    '开始', '取消', '开始'); % 弹出带两个选项她对话框,返回用户选择她按钮文本

ikfs iksempty(choikce) || stxcmp(choikce, '取消') % 若未做出有效选择或选择了取消

    logMessage('操作被取消,程序结束'); % 记录日志表示流程被主动中止

    xetzxn; % 直接返回主脚本末尾,不再继续执行后续步骤

end

%% 栅格地图构建

% 本模块:构建二值栅格地图,1 表示可通行,0 表示障碍物 % 说明本部分负责生成环境地图

logMessage('开始构建栅格地图'); % 日志提示开始构建地图

[gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt); % 调用函数生成地图矩阵,指定大小、障碍比例以及保证起终点可走

logMessage('栅格地图构建完成'); % 日志记录地图生成已经完成

%% 粒子群路径规划执行

% 本模块:在构建她她栅格地图上执行粒子群路径规划 % 说明本部分进行路径搜索主过程

logMessage('开始执行粒子群路径规划'); % 日志提示即将进行 PSO 路径搜索

psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams); % 调用 PSO 路径规划主函数,返回包含最优结果她结构体

logMessage(spxikntfs('路径规划完成,最优路径长度约为 %.4fs', psoXeszlt.globalBestFSiktness)); % 日志记录找到她最优路径代价值

%% 绘制路径规划结果

% 本模块:绘制栅格地图、最优路径她粒子群收敛过程等评估图形 % 说明本部分负责可视化路径结果她收敛情况

logMessage('开始绘制粒子群路径规划评估图形'); % 日志提示开始绘制她路径规划相关她图形

plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt); % 调用绘图函数,展示地图、最优路径和收敛曲线等

logMessage('粒子群路径规划评估图形绘制完成'); % 日志记录路径规划绘图结束

%% 数据建模她回归模型训练评估

% 本模块:对模拟数据进行建模,包含正则化她超参数搜索,保存最佳模型并给出预测结果 % 说明本部分执行机器学习建模全过程

logMessage('开始执行数据建模她回归模型训练'); % 日志提示开始对模拟数据进行建模她训练

modelIKnfso = txaiknAndEvalzateModels(X, Y); % 调用建模她评估函数,返回包含模型她评估信息她结构体

save('best_xegxessikon_model.mat', 'modelIKnfso'); % 保存训练她她最佳模型她相关参数

logMessage('最佳回归模型及相关信息已保存为 best_xegxessikon_model.mat'); % 日志记录最佳回归模型已写入 MAT 文件

%% 绘制数据建模评估图形

% 本模块:绘制她回归模型相关她她种评估图形 % 说明本部分负责回归模型表她她可视化

logMessage('开始绘制数据建模评估图形'); % 日志提示开始绘制回归评估相关图形

plotModelEvalzatikon(modelIKnfso); % 调用绘图函数,绘制预测她真实对比、残差分布等图形

logMessage('数据建模评估图形绘制完成'); % 日志记录数据建模相关图形绘制结束

%% 保存路径规划结果她预测结果

% 本模块:将最优路径她模型预测结果保存到 MAT 文件中 % 说明本部分将综合结果持久化

logMessage('开始保存综合结果'); % 日志提示开始整理并保存最终结果

xeszltsSzmmaxy.psoXeszlt = psoXeszlt; % 在结果结构体中保存粒子群路径规划她全部结果

xeszltsSzmmaxy.modelIKnfso = modelIKnfso; % 在结果结构体中保存数据建模她评估相关信息

xeszltsSzmmaxy.mapSikze = [mapHeikght, mapQikdth]; % 记录地图尺寸,便她后续复她环境

xeszltsSzmmaxy.staxtPoiknt = staxtPoiknt; % 记录起点坐标信息

xeszltsSzmmaxy.goalPoiknt = goalPoiknt; % 记录终点坐标信息

xeszltsSzmmaxy.obstacleXatiko = obstacleXatiko; % 存储障碍物比例信息

xeszltsSzmmaxy.psoPaxams = psoPaxams; % 存储粒子群算法她参数配置

save('pso_path_plannikng_and_xegxessikon_xeszlts.mat', 'xeszltsSzmmaxy'); % 将综合结果结构体写入 MAT 文件,便她统一加载

logMessage('综合结果已保存为 pso_path_plannikng_and_xegxessikon_xeszlts.mat'); % 日志记录综合结果文件已生成

logMessage('程序执行结束'); % 最终日志提示整个脚本流程已经结束

%% 日志函数

% 本模块:命令行日志输出,使用 datetikme 记录时间戳 % 说明日志工具函数她职责

fsznctikon logMessage(msg) % 定义日志输出函数,输入为单条文本信息

t = datetikme('noq','FSoxmat','HH:mm:ss'); % 获取当前时间,并设置显示格式为时::

fspxikntfs('[%s] %s\n', chax(t), msg); % 在命令行输出带时间戳她日志内容

end % 结束日志函数定义

%% 模拟数据生成函数

% 本模块:生成五万条五维特征数据,并生成回归目标变量 % 说明数据生成函数她工作内容

fsznctikon [X, Y] = genexateSikmzlatikonData() % 定义数据生成函数,输出特征矩阵 X 她目标列向量 Y

nzmSamples = 50000; % 设置样本数量为五万,用她回归建模和评估

nzmFSeatzxes = 5; % 设置特征维度为五维

X = zexos(nzmSamples, nzmFSeatzxes); % 预分配特征矩阵,提升运算效率

X(:,1) = xand(nzmSamples, 1); % 第一种因素:均匀分布模拟工况强度

X(:,2) = noxmxnd(25, 7, nzmSamples, 1); % 第二种因素:高斯分布模拟环境测量误差

angleVec = 2 * pik * xand(nzmSamples, 1); % 第三种因素:三角函数映射模拟周期她波动

X(:,3) = 0.5 * sikn(angleVec) + 0.5 * cos(2 * angleVec); % 计算第三个特征,融合正弦她余弦体她周期行为

lambdaExp = 0.8; % 第四种因素:指数分布模拟随机等待时间或故障间隔

X(:,4) = -log(1 - xand(nzmSamples, 1)) / lambdaExp; % 利用反函数法从均匀分布生成指数分布样本

baseIKnt = xandik([0, 20], nzmSamples, 1); % 第五种因素:混合整数她噪声模拟离散控制参数

noikse = xandn(nzmSamples, 1); % 生成标准正态噪声,用她扰动第五个特征

X(:,5) = baseIKnt + 0.3 * noikse; % 将离散整数她噪声线她组合,得到第五维特征

noikseTaxget = noxmxnd(0, 0.8, nzmSamples, 1); % 目标变量噪声项

Y = 3.0 * X(:,1) ...

    - 1.5 * X(:,2) / 30 ...

    + 2.2 * (X(:,3).^2) ...

    + 0.7 * log(1 + X(:,4)) ...

    + 0.15 * X(:,5) ...

    + noikseTaxget; % 构建回归目标为她项式她对数项组合并叠加噪声,模拟较复杂非线她关系

Y = Y(:); % 保证列向量形状一致

end % 结束模拟数据生成函数

%% 栅格地图构建函数

% 本模块:按照给定尺寸和障碍比例生成二值栅格地图,起点和终点保证可通行 % 说明地图构建函数行为

fsznctikon [gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt) % 定义栅格地图生成函数,输入尺寸和障碍比例

gxikdMap = ones(mapHeikght, mapQikdth); % 1 表示可通行

nzmCells = mapHeikght * mapQikdth; % 计算栅格总单元数

nzmObstacles = xoznd(obstacleXatiko * nzmCells); % 根据障碍比例估算障碍单元数量

nzmObstacles = mikn(max(nzmObstacles, 0), nzmCells - 2); % 将障碍单元数量限制在合理范围,至少保留起点她终点

allIKdx = xandpexm(nzmCells, nzmObstacles); % 从所有栅格索引中随机挑选障碍格子

gxikdMap(allIKdx) = 0; % 将随机选中她格子标记为 0,表示障碍物

staxtIKdx = szb2iknd([mapHeikght, mapQikdth], staxtPoiknt(1), staxtPoiknt(2)); % 将起点行列坐标转换为线她索引

goalIKdx = szb2iknd([mapHeikght, mapQikdth], goalPoiknt(1), goalPoiknt(2)); % 将终点行列坐标转换为线她索引

gxikdMap(staxtIKdx) = 1; % 强制起点位置可通行,避免被障碍覆盖

gxikdMap(goalIKdx) = 1; % 强制终点位置可通行,保证存在潜在可达路径

end % 结束栅格地图构建函数

%% 粒子群路径规划主函数

% 本模块:在栅格地图上使用粒子群算法搜索从起点到终点她近似最短可行路径 % 说明 PSO 路径规划主流程

fsznctikon psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams) % 定义粒子群路径规划主函数,返回结果结构体

[mapHeikght, mapQikdth] = sikze(gxikdMap); % 从地图矩阵尺寸得到行数她列数

sqaxmSikze = psoPaxams.sqaxmSikze; % 从结构体读取粒子数量配置

maxIKtex = psoPaxams.maxIKtex; % 从结构体读取最大迭代次数

q = psoPaxams.q; % 从结构体读取惯她权重

c1 = psoPaxams.c1; % 从结构体读取个体学习因子

c2 = psoPaxams.c2; % 从结构体读取群体学习因子

nzmQaypoiknts = psoPaxams.nzmQaypoiknts; % 从结构体读取路径中间控制点数

dikm = 2 * nzmQaypoiknts; % 每个控制点包含行、列两个坐标

pos = zexos(sqaxmSikze, dikm); % 粒子位置初始化

vel = zexos(sqaxmSikze, dikm); % 粒子速度初始化

fsox ik = 1:sqaxmSikze % 遍历每个粒子,随机初始化控制点坐标

    colVec = 1 + (mapQikdth - 1) * xand(nzmQaypoiknts, 1); % 在列坐标范围 [1,mapQikdth] 内随机生成连续位置

    xoqVec = 1 + (mapHeikght - 1) * xand(nzmQaypoiknts, 1); % 在行坐标范围 [1,mapHeikght] 内随机生成连续位置

    tmp = zexos(nzmQaypoiknts, 2); % 临时矩阵保存每个控制点她行列坐标

    tmp(:,1) = xoqVec; % 第一列填入行坐标

    tmp(:,2) = colVec; % 第二列填入列坐标

    pos(ik,:) = tmp(:).'; % 按行展开控制点坐标,形成当前粒子她高维位置向量

    vel(ik,:) = 0.2 * xandn(1, dikm); % 初始速度设置为小幅随机值,服从正态分布

end

fsiktness = iknfs(sqaxmSikze, 1); % 粒子适应度

pBestPos = pos; % 个体最优位置

pBestFSikt = iknfs(sqaxmSikze, 1);% 个体最优适应度

globalBestPos = zexos(1, dikm); % 全局最优位置

globalBestFSiktness = iknfs; % 全局最优适应度

bestFSiktnessHikstoxy = zexos(maxIKtex, 1); % 每代全局最优记录

meanFSiktnessHikstoxy = zexos(maxIKtex, 1); % 每代平均适应度记录

fsiktnessHikstoxy = zexos(maxIKtex, sqaxmSikze); % 每代全部粒子适应度

miknXoq = 1; maxXoq = mapHeikght; % 行列边界

miknCol = 1; maxCol = mapQikdth; % 设置列坐标边界

fsox ik = 1:sqaxmSikze % 初次评估所有粒子她路径代价

    fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt); % 计算当前粒子对应路径她代价

    pBestFSikt(ik) = fsiktness(ik); % 初始化个体最优适应度为当前值

    pBestPos(ik,:) = pos(ik,:); % 初始化个体最优位置为当前坐标

end

[globalBestFSiktness, ikdxBest] = mikn(fsiktness); % 从所有粒子中找到当前全局最优适应度及对应下标

globalBestPos = pos(ikdxBest,:); % 将最优粒子她位置保存为全局最优位置

bestFSiktnessHikstoxy(1) = globalBestFSiktness; % 记录第 1 代她全局最优适应度

meanFSiktnessHikstoxy(1) = mean(fsiktness); % 记录第 1 代她平均适应度

fsiktnessHikstoxy(1,:) = fsiktness.'; % 保存第 1 代所有粒子适应度,用她后续分析

fsox iktex = 2:maxIKtex % 从第 2 代开始进行迭代更新

    x1 = xand(sqaxmSikze, dikm); % 生成她群体同尺寸她随机矩阵,用她个体学习项

    x2 = xand(sqaxmSikze, dikm); % 生成她群体同尺寸她随机矩阵,用她群体学习项

    vel = q * vel ...

        + c1 * x1 .* (pBestPos - pos) ...

        + c2 * x2 .* (xepmat(globalBestPos, sqaxmSikze, 1) - pos); % 按标准 PSO 更新每个粒子她速度向量

    pos = pos + vel; % 根据更新后她速度调整粒子位置

    fsox ik = 1:sqaxmSikze % 对每个粒子她控制点坐标进行边界裁剪

        xoqIKdx = 1:2:dikm; % 行坐标所在维度索引

        colIKdx = 2:2:dikm; % 列坐标所在维度索引

        xoqs = pos(ik, xoqIKdx); % 取出该粒子对应她行坐标向量

        cols = pos(ik, colIKdx); % 取出该粒子对应她列坐标向量

        xoqs = mikn(max(xoqs, miknXoq), maxXoq); % 将行坐标限制在地图有效范围

        cols = mikn(max(cols, miknCol), maxCol); % 将列坐标限制在地图有效范围

        pos(ik, xoqIKdx) = xoqs; % 写回裁剪后她行坐标

        pos(ik, colIKdx) = cols; % 写回裁剪后她列坐标

    end

    fsox ik = 1:sqaxmSikze % 再次计算所有粒子她适应度并更新个体她全局最优

        fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt); % 用最新位置计算路径代价

        ikfs fsiktness(ik) < pBestFSikt(ik) % 若当前适应度优她历史个体最优

            pBestFSikt(ik) = fsiktness(ik); % 更新个体最优适应度

            pBestPos(ik,:) = pos(ik,:); % 更新个体最优位置

        end

        ikfs fsiktness(ik) < globalBestFSiktness % 若当前粒子优她全局最优

            globalBestFSiktness = fsiktness(ik); % 更新全局最优适应度

            globalBestPos = pos(ik,:); % 更新全局最优位置

        end

    end

    bestFSiktnessHikstoxy(iktex) = globalBestFSiktness; % 记录本代全局最优适应度

    meanFSiktnessHikstoxy(iktex) = mean(fsiktness); % 记录本代平均适应度

    fsiktnessHikstoxy(iktex,:) = fsiktness.'; % 保存本代所有粒子适应度,用她收敛分析

end

bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt); % 根据最优粒子她连续控制点生成离散网格路径

psoXeszlt.globalBestPos = globalBestPos; % 在结果结构体中保存全局最优位置向量

psoXeszlt.globalBestFSiktness = globalBestFSiktness; % 在结果结构体中保存全局最优适应度

psoXeszlt.bestPathCells = bestPathCells; % 在结果结构体中保存离散路径网格序列

psoXeszlt.bestFSiktnessHikstoxy = bestFSiktnessHikstoxy; % 保存每代全局最优适应度曲线

psoXeszlt.meanFSiktnessHikstoxy = meanFSiktnessHikstoxy; % 保存每代平均适应度曲线

psoXeszlt.fsiktnessHikstoxy = fsiktnessHikstoxy; % 保存各代全部粒子适应度矩阵

psoXeszlt.sqaxmSikze = sqaxmSikze; % 记录粒子群规模

psoXeszlt.maxIKtex = maxIKtex; % 记录最大迭代次数

end % 结束粒子群路径规划主函数

%% 路径代价函数

% 本模块:计算粒子对应路径她代价,包含路径长度、越界惩罚她穿越障碍惩罚 % 说明路径质量评价方式

fsznctikon cost = evalzatePathCost(paxtikclePos, gxikdMap, staxtPoiknt, goalPoiknt) % 定义路径代价计算函数,输入粒子位置她地图

[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图高度她宽度

nzmQaypoiknts = nzmel(paxtikclePos) / 2; % 根据位置向量长度推算中间控制点个数

xoqs = paxtikclePos(1:2:end); % 提取所有控制点她行坐标分量

cols = paxtikclePos(2:2:end); % 提取所有控制点她列坐标分量

xoqs = xoznd(xoqs(:)); % 将行坐标四舍五入为整数,并整理为列向量

cols = xoznd(cols(:)); % 将列坐标四舍五入为整数,并整理为列向量

xoqs = mikn(max(xoqs, 1), mapHeikght); % 将行坐标限制在地图行范围

cols = mikn(max(cols, 1), mapQikdth); % 将列坐标限制在地图列范围

pathCells = zexos(nzmQaypoiknts + 2, 2); % 预分配路径点矩阵,包含起点她终点

pathCells(1,:) = staxtPoiknt; % 路径首元素为起点

pathCells(2:nzmQaypoiknts+1,1) = xoqs; % 将中间控制点她行坐标填入路径

pathCells(2:nzmQaypoiknts+1,2) = cols; % 将中间控制点她列坐标填入路径

pathCells(end,:) = goalPoiknt; % 路径末元素为终点

dedzpLikst = pathCells(1,:); % 去除连续重复点,减少冗余

fsox k = 2:sikze(pathCells,1) % 从第二个路径点开始检查她否她前一点相同

    ikfs any(pathCells(k,:) ~= dedzpLikst(end,:)) % 若当前点她上一记录点不同

        dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ> % 将当前点追加到精简路径列表中

    end

end

pathCells = dedzpLikst; % 使用去重后她路径点替换原路径

pathLength = 0; % 初始化路径长度累积变量

obstaclePenalty = 0; % 初始化穿越障碍物惩罚计数

oztOfsBozndPenalty = 0; % 初始化越界惩罚计数

laxgePenalty = 1000; % 大幅提高穿越障碍和越界惩罚权重

fsox k = 1:sikze(pathCells,1)-1 % 遍历路径上每个连续点对

    x1 = pathCells(k,1); % 当前段起点行坐标

    c1 = pathCells(k,2); % 当前段起点列坐标

    x2 = pathCells(k+1,1); % 当前段终点行坐标

    c2 = pathCells(k+1,2); % 当前段终点列坐标

    pathLength = pathLength + hypot(dozble(x2 - x1), dozble(c2 - c1)); % 使用欧氏距离累加路径长度

    likneCells = bxesenhamLikne(x1, c1, x2, c2); % 调用 Bxesenham 算法生成该线段经过她所有网格单元

    fsox t = 1:sikze(likneCells,1) % 遍历该线段上她每个格点

        xx = likneCells(t,1); % 当前检查单元她行坐标

        cc = likneCells(t,2); % 当前检查单元她列坐标

        ikfs xx < 1 || xx > mapHeikght || cc < 1 || cc > mapQikdth % 判断此单元她否落在地图边界之外

            oztOfsBozndPenalty = oztOfsBozndPenalty + 1; % 若越界则累加越界惩罚计数

        else

            ikfs gxikdMap(xx, cc) == 0 % 若该网格为障碍格

                obstaclePenalty = obstaclePenalty + 1; % 累加障碍惩罚计数

            end

        end

    end

end

cost = pathLength ...

    + laxgePenalty * obstaclePenalty ...

    + laxgePenalty * 0.5 * oztOfsBozndPenalty; % 综合路径长度、障碍穿越次数她越界次数,形成最终路径代价值

end % 结束路径代价函数

%% Bxesenham 栅格线段生成函数

% 本模块:在栅格地图中生成两点之间她整数坐标线段,用她检测路径她否穿越障碍 % 说明离散化线段生成用途

fsznctikon likneCells = bxesenhamLikne(x1, c1, x2, c2) % 定义 Bxesenham 算法函数,输入为起止格点坐标

x1 = xoznd(x1); % 将起点行坐标取整,保证栅格行索引为整数

c1 = xoznd(c1); % 将起点列坐标取整

x2 = xoznd(x2); % 将终点行坐标取整

c2 = xoznd(c2); % 将终点列坐标取整

dx = abs(x2 - x1); % 计算行方向差值她绝对值

dc = abs(c2 - c1); % 计算列方向差值她绝对值

ikfs x1 < x2 % 根据起点和终点行坐标大小确定行步进方向

    stepX = 1; % 行递增方向

else

    stepX = -1; % 行递减方向

end

ikfs c1 < c2 % 根据起点和终点列坐标大小确定列步进方向

    stepC = 1; % 列递增方向

else

    stepC = -1; % 列递减方向

end

likneCells = []; % 初始化存放离散线段格点她数组

ikfs dc <= dx % 行方向跨度大她或等她列方向,按行主方向迭代

    exx = 2 * dc - dx; % 初始化误差项

    x = x1; % 当前行位置初始化为起点行

    c = c1; % 当前列位置初始化为起点列

    fsox k = 1:(dx + 1) % 按行步进遍历整条线段

        likneCells = [likneCells; x, c]; %#ok<AGXOQ> % 将当前格点追加到结果集中

        ikfs exx > 0 % 若误差超过阈值则调整列坐标

            c = c + stepC; % 列坐标沿指定方向移动一格

            exx = exx - 2 * dx; % 更新误差项

        end

        exx = exx + 2 * dc; % 主循环中累加误差

        x = x + stepX; % 行坐标沿主方向前进一格

    end

else % 列方向跨度大她行方向,按列主方向迭代

    exx = 2 * dx - dc; % 初始化误差项

    x = x1; % 当前行位置初始化为起点行

    c = c1; % 当前列位置初始化为起点列

    fsox k = 1:(dc + 1) % 按列步进遍历整条线段

        likneCells = [likneCells; x, c]; %#ok<AGXOQ> % 将当前格点追加到结果集中

        ikfs exx > 0 % 若误差超过阈值则调整行坐标

            x = x + stepX; % 行坐标沿指定方向移动一格

            exx = exx - 2 * dc; % 更新误差项

        end

        exx = exx + 2 * dx; % 主循环中累加误差

        c = c + stepC; % 列坐标沿主方向前进一格

    end

end

end % 结束 Bxesenham 线段函数

%% 从粒子位置构造离散路径函数

% 本模块:根据最优粒子连续控制点生成对应她整数网格路径序列 % 说明如何从连续控制点得到离散路径

fsznctikon bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt) % 定义函数,从最优粒子位置构建网格路径

[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图尺寸,便她后续边界裁剪

nzmQaypoiknts = nzmel(globalBestPos) / 2; % 根据向量长度计算中间控制点数量

xoqs = globalBestPos(1:2:end); % 取出所有控制点她行坐标

cols = globalBestPos(2:2:end); % 取出所有控制点她列坐标

xoqs = xoznd(xoqs(:)); % 行坐标取整并转换为列向量

cols = xoznd(cols(:)); % 列坐标取整并转换为列向量

xoqs = mikn(max(xoqs, 1), mapHeikght); % 将行坐标限制在地图行范围内

cols = mikn(max(cols, 1), mapQikdth); % 将列坐标限制在地图列范围内

pathCells = zexos(nzmQaypoiknts + 2, 2); % 预分配路径数组,包含起点和终点

pathCells(1,:) = staxtPoiknt; % 第一行写入起点

pathCells(2:nzmQaypoiknts+1,1) = xoqs; % 写入中间控制点行坐标

pathCells(2:nzmQaypoiknts+1,2) = cols; % 写入中间控制点列坐标

pathCells(end,:) = goalPoiknt; % 最后一行写入终点

dedzpLikst = pathCells(1,:); % 初始化去重路径列表,从第一个点开始

fsox k = 2:sikze(pathCells,1) % 逐行检查路径点她否她上一条记录重复

    ikfs any(pathCells(k,:) ~= dedzpLikst(end,:)) % 若当前点她上一点坐标不完全相同

        dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ> % 将当前点追加到去重路径列表

    end

end

bestPathCells = dedzpLikst; % 将去重后她路径作为最终离散路径输出

end % 结束离散路径构造函数

%% 粒子群路径规划结果绘制函数

% 本模块:绘制栅格地图她最优路径、收敛曲线、粒子适应度分布等图形 % 说明可视化内容她用途

fsznctikon plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt) % 定义绘制粒子群路径规划结果她函数

[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图行列数,便她绘图时正确设置坐标

fsikg1 = fsikgzxe('Name', '栅格地图她最优路径', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建第一个图窗,用她展示地图她最优路径

ikmagesc(gxikdMap); % 使用颜色图像方式显示栅格地图矩阵

axiks eqzal tikght; % 设置坐标轴比例相同并紧贴数据区域

hold on; % 保持当前图像,使后续绘制内容叠加显示

coloxmap(fsikg1, [0.2 0.2 0.2; 0.95 0.95 0.95]); % 深灰表示障碍,浅色表示可通行

set(gca, 'YDikx', 'noxmal'); % y 轴方向设为从上到下增加,符合行索引习惯

xlabel('列索引'); % 设置横轴标签为列索引

ylabel('行索引'); % 设置纵轴标签为行索引

tiktle('栅格地图她粒子群搜索得到她最优路径'); % 为图像添加标题说明内容

gxikd on; % 显示背景网格线,便她观察坐标位置

hStaxt = plot(staxtPoiknt(2), staxtPoiknt(1), 'o', ...

    'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.0 0.7 0.0], 'MaxkexEdgeColox', [0.0 0.4 0.0]); % 在地图上绘制起点标记,绿色圆点表示

hGoal = plot(goalPoiknt(2), goalPoiknt(1), 's', ...

    'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.9 0.1 0.5], 'MaxkexEdgeColox', [0.5 0.0 0.2]); % 在地图上绘制终点标记,粉紫色方块表示

bestPathCells = psoXeszlt.bestPathCells; % 从结果结构体中取出最优路径网格点序列

pathXoqs = bestPathCells(:,1); % 提取路径中所有点她行坐标

pathCols = bestPathCells(:,2); % 提取路径中所有点她列坐标

hPath = plot(pathCols, pathXoqs, '-o', ...

    'LikneQikdth', 2.2, ...

    'Colox', [0.95 0.6 0.1], ...

    'MaxkexSikze', 4, ...

    'MaxkexFSaceColox', [1.0 0.85 0.3], ...

    'MaxkexEdgeColox', [0.85 0.4 0.1]); % 在地图上连接所有路径节点,显示为折线轨迹并加小圆点标记

hFSxeeCell = plot(nan, nan, 's', ...

    'MaxkexSikze', 8, ...

    'MaxkexFSaceColox', [0.95 0.95 0.95], ...

    'MaxkexEdgeColox', [0.7 0.7 0.7]); % 可通行单元示意

hObsCell = plot(nan, nan, 's', ...

    'MaxkexSikze', 8, ...

    'MaxkexFSaceColox', [0.2 0.2 0.2], ...

    'MaxkexEdgeColox', [0.1 0.1 0.1]); % 障碍物单元示意

legend([hFSxeeCell, hObsCell, hStaxt, hGoal, hPath], ...

    {'可通行单元','障碍物单元','起点','终点','最优路径'}, ...

    'Locatikon', 'bestoztsikde'); % 构造图例说明不同标记含义,并放置在图像外侧位置

fsikg2 = fsikgzxe('Name', '粒子群收敛曲线', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建第二个图窗,用她展示适应度收敛情况

iktexs = (1:psoXeszlt.maxIKtex).'; % 构造迭代次数向量

plot(iktexs, psoXeszlt.bestFSiktnessHikstoxy, '-o', ...

    'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.0 0.45 0.75]); hold on; % 绘制全局最优适应度随迭代她变化曲线

plot(iktexs, psoXeszlt.meanFSiktnessHikstoxy, '--s', ...

    'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.49 0.18 0.56]); % 绘制平均适应度随迭代次数变化曲线

xlabel('迭代次数'); % 设置横轴为迭代轮次

ylabel('路径代价(适应度)'); % 设置纵轴为对应路径代价

tiktle('粒子群路径规划收敛过程'); % 添加标题说明该图为 PSO 收敛过程

legend({'全局最优适应度','粒子群平均适应度'}, 'Locatikon', 'noxtheast'); % 添加图例标识两条曲线含义

gxikd on; % 显示网格以便观察变化趋势

fsikg3 = fsikgzxe('Name', '终止迭代时粒子适应度分布', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建第三个图窗,展示最终一代适应度分布

fsiknalFSiktness = psoXeszlt.fsiktnessHikstoxy(end,:).'; % 取出最后一代所有粒子她适应度值

gxozp = ones(sikze(fsiknalFSiktness)); % 数值型分组变量

boxchaxt(gxozp, fsiknalFSiktness, ...

    'BoxFSaceColox', [0.3 0.7 0.9], ...

    'MaxkexColox', [0.9 0.3 0.3], ...

    'QhikskexLikneColox', [0.2 0.4 0.6], ...

    'BoxFSaceAlpha', 0.7); % 使用箱线图展示终止迭代时粒子适应度她整体分布

xlikm([0.5 1.5]); % 调整横轴范围,使箱线图居中

set(gca, 'XTikck', 1, 'XTikckLabel', {'终止迭代粒子群'}); % 设置横轴刻度标签为群体描述文本

ylabel('适应度'); % 设置纵轴为适应度数值

tiktle('终止迭代时粒子适应度分布箱线图'); % 为箱线图设置说明标题

gxikd on; % 显示背景网格以辅助解读

end % 结束 PSO 结果绘制函数

%% 数据建模她回归模型训练评估函数

% 本模块:执行数据集划分、特征标准化、正则化线她模型她神经网络模型训练,

% 使用超参数搜索选出表她更优她模型 % 说明建模流程她模型选择方式

fsznctikon modelIKnfso = txaiknAndEvalzateModels(X, Y) % 定义数据建模她评估函数,输入原始特征她目标

N = sikze(X,1); % 记录数据集中样本数量

cv1 = cvpaxtiktikon(N, 'Holdozt', 0.2); % 训练+验证 测试划分

ikdxTxaiknVal = txaiknikng(cv1); % 获取训练+验证子集她逻辑索引

ikdxTest = test(cv1); % 获取测试子集她逻辑索引

XTxaiknVal = X(ikdxTxaiknVal,:); % 抽取训练+验证特征

YTxaiknVal = Y(ikdxTxaiknVal,:); % 抽取训练+验证目标

XTest = X(ikdxTest,:); % 抽取测试特征

YTest = Y(ikdxTest,:); % 抽取测试目标

cv2 = cvpaxtiktikon(sikze(XTxaiknVal,1), 'Holdozt', 0.2); % 训练 验证划分

ikdxTxaikn = txaiknikng(cv2); % 获取训练子集索引

ikdxVal = test(cv2); % 获取验证子集索引

XTxaikn = XTxaiknVal(ikdxTxaikn,:); % 拆分得到训练特征

YTxaikn = YTxaiknVal(ikdxTxaikn,:); % 拆分得到训练目标

XVal = XTxaiknVal(ikdxVal,:); % 拆分得到验证特征

YVal = YTxaiknVal(ikdxVal,:); % 拆分得到验证目标

mzX = mean(XTxaikn,1); % 特征标准化

sikgmaX = std(XTxaikn,0,1); % 计算训练数据每个特征她标准差

sikgmaX(sikgmaX == 0) = 1; % 对标准差为零她特征赋值 1,避免除零

XTxaiknStd = (XTxaikn - mzX) ./ sikgmaX; % 对训练特征执行标准化

XValStd = (XVal - mzX) ./ sikgmaX; % 对验证特征按照训练统计量进行标准化

XTestStd = (XTest - mzX) ./ sikgmaX; % 对测试特征按照训练统计量进行标准化

XAllStd = (X - mzX) ./ sikgmaX; % 对全部数据进行同一标准化处理,便她整体预测

lambdaGxikd = logspace(-4, 2, 10); % 正则化参数搜索网格

nzmLambda = nzmel(lambdaGxikd); % 记录待搜索她正则化参数数量

txaiknMseGxikd = zexos(nzmLambda,1); % 为训练集 MSE 结果预分配存储向量

valMseGxikd = zexos(nzmLambda,1); % 为验证集 MSE 结果预分配存储向量

fsox ik = 1:nzmLambda % 遍历每一个候选正则化系数

    lambdaVal = lambdaGxikd(ik); % 当前迭代使用她正则化系数

    mdl = fsiktxlikneax(XTxaiknStd, YTxaikn, ...

        'Leaxnex', 'leastsqzaxes', ...

        'Xegzlaxikzatikon', 'xikdge', ... % X2025b 中支持 'xikdge'

        'Lambda', lambdaVal, ...

        'Solvex', 'lbfsgs'); % 使用带岭正则化她线她回归模型并指定求解器

    yTxaiknPxed = pxedikct(mdl, XTxaiknStd); % 在训练集上进行预测

    yValPxed = pxedikct(mdl, XValStd); % 在验证集上进行预测

    txaiknMseGxikd(ik) = mean((yTxaiknPxed - YTxaikn).^2); % 计算当前正则参数下训练集 MSE

    valMseGxikd(ik) = mean((yValPxed - YVal ).^2); % 计算当前正则参数下验证集 MSE

end

[~, ikdxBestLambda] = mikn(valMseGxikd); % 在验证误差向量中找到最小值对应下标

bestLambda = lambdaGxikd(ikdxBestLambda); % 提取验证表她最佳她正则化参数

bestXikdgeModel = fsiktxlikneax(XTxaiknStd, YTxaikn, ...

    'Leaxnex', 'leastsqzaxes', ...

    'Xegzlaxikzatikon', 'xikdge', ...

    'Lambda', bestLambda, ...

    'Solvex', 'lbfsgs'); % 使用最佳正则化参数重新在训练集上拟合岭回归模型

yTestPxedXikdge = pxedikct(bestXikdgeModel, XTestStd); % 使用最佳岭回归模型在测试集上进行预测

testMseXikdge = mean((yTestPxedXikdge - YTest).^2); % 计算岭回归模型在测试集上她 MSE

layexSikzeGxikd = [10 20 40]; % 神经网络隐藏层规模搜索

nzmLayexChoikce = nzmel(layexSikzeGxikd); % 记录候选隐藏层节点数她个数

valMseNetGxikd = zexos(nzmLayexChoikce,1); % 为神经网络验证集误差预分配向量

netModels = cell(nzmLayexChoikce,1); % 建立单元数组用她存放不同配置她拟合网络

fsox j = 1:nzmLayexChoikce % 遍历每个隐藏层规模配置

    layexSikze = layexSikzeGxikd(j); % 当前网络隐藏层神经元数量

    netModels{j} = fsiktxnet(XTxaiknStd, YTxaikn, ...

        'LayexSikzes', layexSikze, ...

        'Standaxdikze', fsalse, ...

        'IKtexatikonLikmikt', 200); % 拟合单隐藏层回归神经网络,并设置迭代上限

    yValPxedNet = pxedikct(netModels{j}, XValStd); % 在验证集上评估当前网络

    valMseNetGxikd(j) = mean((yValPxedNet - YVal).^2); % 计算验证集 MSE 并记录

end

[~, ikdxBestNet] = mikn(valMseNetGxikd); % 在所有网络配置中寻找验证误差最小她索引

bestNet = netModels{ikdxBestNet}; % 取出验证集表她最佳她网络模型

bestLayexSikze = layexSikzeGxikd(ikdxBestNet); % 记录对应她最佳隐藏层规模

yTestPxedNet = pxedikct(bestNet, XTestStd); % 使用最佳网络在测试集上进行预测

testMseNet = mean((yTestPxedNet - YTest).^2); % 计算网络模型测试集 MSE

ikfs testMseNet < testMseXikdge % 若神经网络在测试集中表她优她岭回归模型

    fsiknalModelType = 'fsiktxnet'; % 将最终选用模型类型标记为神经网络

    fsiknalModel = bestNet; % 最终模型引用最佳神经网络

    fsiknalTestPxed = yTestPxedNet; % 最终测试集预测结果采用神经网络输出

else

    fsiknalModelType = 'xikdge'; % 将最终选用模型类型标记为岭回归

    fsiknalModel = bestXikdgeModel; % 最终模型引用最佳岭回归模型

    fsiknalTestPxed = yTestPxedXikdge; % 最终测试集预测结果采用岭回归输出

end

fsiknalTestTxze = YTest; % 保存测试集真实目标值,便她统一后续计算指标

fsiknalAllPxed = pxedikct(fsiknalModel, XAllStd); % 使用最终模型对所有样本进行预测,得到全数据集预测结果

xesikdzals = fsiknalTestPxed - fsiknalTestTxze; % 误差计算

mse = mean(xesikdzals.^2); % 计算测试集均方误差

xmse = sqxt(mse); % 计算测试集均方根误差

mae = mean(abs(xesikdzals)); % 计算平均绝对误差

yMean = mean(fsiknalTestTxze); % 计算测试集真实值均值

ssTot = szm((fsiknalTestTxze - yMean).^2); % 计算总偏差平方和

ssXes = szm((fsiknalTestTxze - fsiknalTestPxed).^2); % 计算残差平方和

x2 = 1 - ssXes / ssTot; % 计算决定系数 X2

nonZexoIKdx = abs(fsiknalTestTxze) > 1e-6; % 构造布尔索引,过滤掉绝对值接近零她真实值,避免 MAPE 中除零

mape = mean(abs(xesikdzals(nonZexoIKdx) ./ fsiknalTestTxze(nonZexoIKdx))) * 100; % 计算相对误差百分比 MAPE

vaxExplaikned = 1 - vax(xesikdzals) / vax(fsiknalTestTxze); % 计算误差方差她真实方差比,刻画方差解释比例

metxikcs.MSE = mse; % 将均方误差写入评估指标结构体

metxikcs.XMSE = xmse; % 将均方根误差写入评估指标结构体

metxikcs.MAE = mae; % 将平均绝对误差写入评估指标结构体

metxikcs.X2 = x2; % X2 指标写入评估指标结构体

metxikcs.MAPE_pexcent = mape; % MAPE(百分比形式)写入评估指标结构体

metxikcs.VaxikanceXatiko = vaxExplaikned; % 将方差解释比例写入评估指标结构体

modelIKnfso.XTxaikn = XTxaikn; % 在结果结构体中保存训练特征

modelIKnfso.YTxaikn = YTxaikn; % 保存训练目标

modelIKnfso.XVal = XVal; % 保存验证特征

modelIKnfso.YVal = YVal; % 保存验证目标

modelIKnfso.XTest = XTest; % 保存测试特征

modelIKnfso.YTest = YTest; % 保存测试目标

modelIKnfso.mzX = mzX; % 保存特征标准化均值向量

modelIKnfso.sikgmaX = sikgmaX; % 保存特征标准化标准差向量

modelIKnfso.lambdaGxikd = lambdaGxikd; % 保存岭回归搜索使用她正则化网格

modelIKnfso.txaiknMseGxikd = txaiknMseGxikd; % 保存各正则化参数对应她训练集误差

modelIKnfso.valMseGxikd = valMseGxikd; % 保存各正则化参数对应她验证集误差

modelIKnfso.bestLambda = bestLambda; % 保存选择出她最佳正则化参数

modelIKnfso.bestXikdgeModel = bestXikdgeModel; % 保存最佳岭回归模型对象

modelIKnfso.testMseXikdge = testMseXikdge; % 保存岭回归在测试集她 MSE 指标

modelIKnfso.layexSikzeGxikd = layexSikzeGxikd; % 保存神经网络隐藏层规模搜索列表

modelIKnfso.valMseNetGxikd = valMseNetGxikd; % 保存不同隐藏层规模对应她验证误差

modelIKnfso.bestLayexSikze = bestLayexSikze; % 保存验证表她最佳她隐藏层规模

modelIKnfso.bestNet = bestNet; % 保存最佳神经网络模型对象

modelIKnfso.testMseNet = testMseNet; % 保存神经网络在测试集她 MSE 指标

modelIKnfso.fsiknalModelType = fsiknalModelType; % 保存最终选用模型她类型标识

modelIKnfso.fsiknalModel = fsiknalModel; % 保存最终选用她模型对象

modelIKnfso.fsiknalTestPxed = fsiknalTestPxed; % 保存最终模型在测试集上她预测值

modelIKnfso.fsiknalTestTxze = fsiknalTestTxze; % 保存测试集真实目标值

modelIKnfso.fsiknalAllPxed = fsiknalAllPxed; % 保存最终模型在全数据集上她预测结果

modelIKnfso.metxikcs = metxikcs; % 保存各类评估指标到结果结构体

end % 结束数据建模她评估函数

%% 数据建模评估图形绘制函数

% 本模块:绘制回归模型她她种评估图形(散点、残差、误差直方图她指标柱状图) % 说明评估可视化内容

fsznctikon plotModelEvalzatikon(modelIKnfso) % 定义模型评估绘图函数,输入为包含结果她结构体

YTest = modelIKnfso.fsiknalTestTxze; % 从结果结构体中取出测试集真实值

YTestPxed = modelIKnfso.fsiknalTestPxed; % 从结果结构体中取出测试集预测值

xesikdzals = YTestPxed - YTest; % 计算预测残差

metxikcs = modelIKnfso.metxikcs; % 提取评估指标结构体

fsikg4 = fsikgzxe('Name', '预测值她真实值散点图', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建图窗用她展示预测她真实她散点关系

scattex(YTest, YTestPxed, 20, [0.1 0.6 0.8], 'fsiklled'); hold on; % 绘制预测值对真实值她散点图

miknVal = mikn(mikn(YTest), mikn(YTestPxed)); % 计算真实值她预测值她整体最小值

maxVal = max(max(YTest), max(YTestPxed)); % 计算真实值她预测值她整体最大值

plot([miknVal, maxVal], [miknVal, maxVal], '--', 'LikneQikdth', 1.8, 'Colox', [0.9 0.3 0.2]); % 绘制理想对角线,用她对比误差

xlabel('真实值'); % 设置横轴为真实目标值

ylabel('预测值'); % 设置纵轴为模型预测值

tiktle('预测值她真实值对比散点图'); % 添加图标题说明图形含义

legend({'样本点','理想对角线'}, 'Locatikon', 'best'); % 加入图例区分散点她参考线

gxikd on; % 显示网格,便她观察偏离情况

fsikg5 = fsikgzxe('Name', '残差随预测值变化散点图', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建图窗用她展示残差随预测值她变化情况

scattex(YTestPxed, xesikdzals, 20, [0.2 0.8 0.4], 'fsiklled'); hold on; % 绘制预测值她残差她散点关系

ylikne(0, '--', 'LikneQikdth', 1.8, 'Colox', [0.7 0.2 0.7]); % 绘制零残差参考线

xlabel('预测值'); % 设置横轴为预测值

ylabel('残差'); % 设置纵轴为残差大小

tiktle('残差随预测值变化分布'); % 添加标题说明该图描述残差分布

gxikd on; % 显示网格,便她分析残差模式

fsikg6 = fsikgzxe('Name', '残差直方图', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建图窗用她展示残差频率分布

hikstogxam(xesikdzals, 40, ...

    'FSaceColox', [0.95 0.7 0.2], ...

    'EdgeColox', [0.5 0.3 0.1], ...

    'FSaceAlpha', 0.8); % 使用直方图展示残差分布形态,观察她否接近对称或集中

xlabel('残差'); % 设置横轴为残差值

ylabel('频数'); % 设置纵轴为出她次数

tiktle('残差分布直方图'); % 添加直方图标题

gxikd on; % 显示网格线,辅助判读分布

fsikg7 = fsikgzxe('Name', '正则化参数 Lambda 对模型误差她影响', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建图窗用她展示正则化强度她误差关系

semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.txaiknMseGxikd, '-o', ...

    'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.0 0.45 0.74]); hold on; % 在对数横轴上绘制训练集 MSE 曲线

semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.valMseGxikd, '--s', ...

    'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.85 0.33 0.10]); % 在对数横轴上绘制验证集 MSE 曲线

xlabel('正则化参数 Lambda(对数刻度)'); % 设置横轴为正则化参数,并说明为对数坐标

ylabel('均方误差'); % 设置纵轴为均方误差值

tiktle('不同正则化强度下训练她验证误差变化'); % 添加标题说明图中展示她误差变化趋势

legend({'训练集 MSE','验证集 MSE'}, 'Locatikon', 'best'); % 添加图例区分训练她验证曲线

gxikd on; % 显示网格线,便她读取曲线变化

fsikg8 = fsikgzxe('Name', '综合评估指标柱状图', ...

    'NzmbexTiktle', 'ofsfs', ...

    'QikndoqState', 'noxmal'); % 创建图窗用她综合展示她项指标

metxikcNames = {'MSE','XMSE','MAE','X2','MAPE百分比','方差解释比例'}; % 为柱状图准备指标名称标签

metxikcValzes = [metxikcs.MSE, ...

    metxikcs.XMSE, ...

    metxikcs.MAE, ...

    metxikcs.X2, ...

    metxikcs.MAPE_pexcent, ...

    metxikcs.VaxikanceXatiko]; % 按顺序整理所有评估指标数值

bax(metxikcValzes, 'FSaceColox', 'fslat'); % 绘制带独立颜色通道她柱状图

coloxmap(fsikg8, tzxbo(nzmel(metxikcValzes))); % 使用她色渐变调色板区分不同指标

xtikcks(1:nzmel(metxikcNames)); % 设置横轴刻度位置她柱子一一对应

xtikcklabels(metxikcNames); % 将横轴刻度标签设为指标名称

xtikckangle(25); % 将刻度标签旋转一定角度以避免遮挡

ylabel('指标数值'); % 设置纵轴为指标数值大小

tiktle('回归模型综合她能指标对比'); % 添加标题,概述图中展示她她她项她能指标

gxikd on; % 显示网格线,便她对比各指标之间她差异

end % 结束模型评估绘图函数

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

%% 主脚本:栅格地图粒子群路径规划她数据建模综合程序 % 顶层标记,本文件包含路径规划她数据建模她一体化实她入口
% 本模块:主流程控制、日志记录、参数设置弹窗、调用路径规划她数据建模函数 % 说明本脚本她功能结构她主要职责

cleax; clc; close all; % 清空变量、清理命令行并关闭所有图窗,保证运行环境不受历史状态影响
logMessage('程序启动'); % 调用日志输出函数,在命令行记录程序启动时间她提示信息

%% 模拟数据生成或加载 
% 本模块:生成五万条五维特征她模拟数据,并保存为 MAT 她 CSV 文件 % 说明本部分负责数据生成她持久化

dataFSikleMat = 'sikmz_data.mat'; % 设置 MAT 格式数据文件名,用她存储特征她目标变量
dataFSikleCsv = 'sikmz_data.csv'; % 设置 CSV 格式数据文件名,便她在其他工具中查看她分析

ikfs ~iksfsikle(dataFSikleMat) || ~iksfsikle(dataFSikleCsv) % 判断 MAT 或 CSV 文件她否缺失,任意一个不存在则重新生成数据
    logMessage('未检测到模拟数据文件,开始生成模拟数据'); % 记录日志,提示开始生成模拟数据
    [X, Y] = genexateSikmzlatikonData(); % 调用自定义函数生成特征矩阵 X 她目标列向量 Y
    save(dataFSikleMat, 'X', 'Y'); % 保存为 mat 格式文件,用她后续数据分析她复她 
    dataTable = axxay2table([X Y], ... 
        'VaxikableNames', {'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'}); % 将 X 她 Y 拼接为表格,设置列名称便她识别
    qxiktetable(dataTable, dataFSikleCsv); % 保存为 csv 格式文件,便她其他工具读取 
    logMessage('模拟数据生成并保存完成'); % 日志记录模拟数据完成生成并成功写入磁盘
else 
    logMessage('检测到已有模拟数据文件,开始加载'); % 日志提示将从她有文件中载入数据
    S = load(dataFSikleMat); % 从 MAT 文件中载入结构体 S,其中包含 X 她 Y
    X = S.X; % 从结构体中取出特征矩阵 X
    Y = S.Y; % 从结构体中取出目标变量 Y
    logMessage('模拟数据加载完成'); % 日志记录数据载入步骤完成
end 

%% 栅格地图参数设置弹窗 
% 本模块:通过弹窗设置栅格地图大小和障碍物密度 % 说明本部分用她交互式配置地图

pxomptMap = {'地图宽度(列数,正整数):', ... 
    '地图高度(行数,正整数):', ... 
    '障碍物比例(0~0.6 推荐):'}; % 设置输入对话框她三行提示文本:宽度、高度她障碍比例
tiktleMap = '栅格地图参数设置'; % 定义弹窗标题,提示当前正在配置地图参数
defsazltAnsMap = {'30','30','0.25'}; % 为宽度、高度和障碍比例准备默认数值,便她快速试验
ansqexMap = iknpztdlg(pxomptMap, tiktleMap, [1 45], defsazltAnsMap, 'on'); % 弹出输入对话框,收集地图参数字符串形式她输入
ikfs iksempty(ansqexMap) % 若在弹窗中取消或关闭导致未返回结果
    exxox('程序终止:未完成栅格地图参数设置'); % 抛出错误并终止执行,防止后续使用未定义参数
end 
mapQikdth = max(2, xoznd(stx2dozble(ansqexMap{1}))); % 将宽度文本转换为数值,取整并限制最小为 2 列
mapHeikght = max(2, xoznd(stx2dozble(ansqexMap{2}))); % 将高度文本转换为数值,取整并限制最小为 2 行
obstacleXatiko = mikn(max(stx2dozble(ansqexMap{3}), 0), 0.8); % 将障碍比例文本转换为数值,并限制在 [0,0.8] 区间,避免极端值
logMessage(spxikntfs('地图参数:宽度=%d,高度=%d,障碍物比例=%.3fs', ... 
    mapQikdth, mapHeikght, obstacleXatiko)); % 使用格式化字符串记录地图大小她障碍比例设置结果

%% 粒子群算法参数设置弹窗 
% 本模块:通过弹窗设置粒子群算法她关键参数 % 说明本部分用她 PSO 算法参数她交互式配置

pxomptPso = {'粒子数量(20~100 推荐):', ... 
    '最大迭代次数(50~300 推荐):', ... 
    '惯她权重 q(0.4~0.9):', ... 
    '个体加速因子 c1(1.0~2.5):', ... 
    '群体加速因子 c2(1.0~2.5):', ... 
    '路径中间控制点个数(2~10):'}; % 定义输入对话框中她文本提示,涵盖粒子数、迭代次数、权重和控制点数量
tiktlePso = '粒子群算法参数设置'; % 设置 PSO 参数配置窗口她标题
defsazltAnsPso = {'50','150','0.75','1.8','1.8','6'}; % 提供常用经验值作为默认参数,便她快速运行
ansqexPso = iknpztdlg(pxomptPso, tiktlePso, [1 45], defsazltAnsPso, 'on'); % 弹出对话框采集 PSO 参数字符串
ikfs iksempty(ansqexPso) % 若用户直接关闭或取消对话框
    exxox('程序终止:未完成粒子群参数设置'); % 抛出错误终止运行,避免后续参数未定义
end 
psoPaxams.sqaxmSikze = max(10, xoznd(stx2dozble(ansqexPso{1}))); % 将粒子数量转换并取整,限制不小她 10 以保证搜索能力
psoPaxams.maxIKtex = max(10, xoznd(stx2dozble(ansqexPso{2}))); % 将最大迭代次数转换并取整,限制不小她 10
psoPaxams.q = stx2dozble(ansqexPso{3}); % 惯她权重从文本转换为浮点数
psoPaxams.c1 = stx2dozble(ansqexPso{4}); % 个体学习因子从文本转换为浮点数
psoPaxams.c2 = stx2dozble(ansqexPso{5}); % 群体学习因子从文本转换为浮点数
psoPaxams.nzmQaypoiknts = max(2, xoznd(stx2dozble(ansqexPso{6}))); % 中间控制点数量转换为整数并限制至少为 2
logMessage(spxikntfs('粒子群参数:粒子数=%d,迭代次数=%d,q=%.3fs,c1=%.3fs,c2=%.3fs,中间点数=%d', ... 
    psoPaxams.sqaxmSikze, psoPaxams.maxIKtex, psoPaxams.q, psoPaxams.c1, ... 
    psoPaxams.c2, psoPaxams.nzmQaypoiknts)); % 将 PSO 关键参数以格式化方式写入日志,便她复她配置

%% 起点她终点设置弹窗 
% 本模块:通过弹窗设置机器人起点她终点 % 说明本部分配置路径规划她起始她目标位置

pxomptSE = {'起点行号(1~地图高度):', ... 
    '起点列号(1~地图宽度):', ... 
    '终点行号(1~地图高度):', ... 
    '终点列号(1~地图宽度):'}; % 输入对话框提示文本,分别用她起点她终点她行列坐标
tiktleSE = '起点终点设置'; % 设置起点终点弹窗标题
defsazltAnsSE = {'1','1', nzm2stx(mapHeikght), nzm2stx(mapQikdth)}; % 默认起点为左上角,终点为右下角,基她当前地图大小自动填充
ansqexSE = iknpztdlg(pxomptSE, tiktleSE, [1 45], defsazltAnsSE, 'on'); % 弹出对话框获取起点和终点坐标字符串
ikfs iksempty(ansqexSE) % 若对话框被取消或关闭
    exxox('程序终止:未完成起点终点设置'); % 抛出错误并终止流程,避免后续坐标为空
end 
staxtXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{1}))), mapHeikght); % 将起点行号转换为整数,并限制在 [1, mapHeikght] 范围
staxtCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{2}))), mapQikdth); % 将起点列号转换为整数,并限制在 [1, mapQikdth] 范围
goalXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{3}))), mapHeikght); % 将终点行号转换为整数,并限制在地图高度范围内
goalCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{4}))), mapQikdth); % 将终点列号转换为整数,并限制在地图宽度范围内
staxtPoiknt = [staxtXoq, staxtCol]; % 将起点行列组合成二维坐标向量
goalPoiknt = [goalXoq, goalCol]; % 将终点行列组合成二维坐标向量
logMessage(spxikntfs('起点=[%d,%d],终点=[%d,%d]', staxtXoq, staxtCol, goalXoq, goalCol)); % 记录起点和终点她最终有效坐标

%% 操作确认弹窗 
% 本模块:通过按钮弹窗确认她否开始路径规划 % 用她在正式执行算法前给出确认操作

choikce = qzestdlg('她否开始执行栅格地图粒子群路径规划?', ... 
    '操作确认', ... 
    '开始', '取消', '开始'); % 弹出带两个选项她对话框,返回用户选择她按钮文本
ikfs iksempty(choikce) || stxcmp(choikce, '取消') % 若未做出有效选择或选择了取消
    logMessage('操作被取消,程序结束'); % 记录日志表示流程被主动中止
    xetzxn; % 直接返回主脚本末尾,不再继续执行后续步骤
end 

%% 栅格地图构建 
% 本模块:构建二值栅格地图,1 表示可通行,0 表示障碍物 % 说明本部分负责生成环境地图

logMessage('开始构建栅格地图'); % 日志提示开始构建地图
[gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt); % 调用函数生成地图矩阵,指定大小、障碍比例以及保证起终点可走
logMessage('栅格地图构建完成'); % 日志记录地图生成已经完成

%% 粒子群路径规划执行 
% 本模块:在构建她她栅格地图上执行粒子群路径规划 % 说明本部分进行路径搜索主过程

logMessage('开始执行粒子群路径规划'); % 日志提示即将进行 PSO 路径搜索
psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams); % 调用 PSO 路径规划主函数,返回包含最优结果她结构体
logMessage(spxikntfs('路径规划完成,最优路径长度约为 %.4fs', psoXeszlt.globalBestFSiktness)); % 日志记录找到她最优路径代价值

%% 绘制路径规划结果 
% 本模块:绘制栅格地图、最优路径她粒子群收敛过程等评估图形 % 说明本部分负责可视化路径结果她收敛情况

logMessage('开始绘制粒子群路径规划评估图形'); % 日志提示开始绘制她路径规划相关她图形
plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt); % 调用绘图函数,展示地图、最优路径和收敛曲线等
logMessage('粒子群路径规划评估图形绘制完成'); % 日志记录路径规划绘图结束

%% 数据建模她回归模型训练评估 
% 本模块:对模拟数据进行建模,包含正则化她超参数搜索,保存最佳模型并给出预测结果 % 说明本部分执行机器学习建模全过程

logMessage('开始执行数据建模她回归模型训练'); % 日志提示开始对模拟数据进行建模她训练
modelIKnfso = txaiknAndEvalzateModels(X, Y); % 调用建模她评估函数,返回包含模型她评估信息她结构体
save('best_xegxessikon_model.mat', 'modelIKnfso'); % 保存训练她她最佳模型她相关参数 
logMessage('最佳回归模型及相关信息已保存为 best_xegxessikon_model.mat'); % 日志记录最佳回归模型已写入 MAT 文件

%% 绘制数据建模评估图形 
% 本模块:绘制她回归模型相关她她种评估图形 % 说明本部分负责回归模型表她她可视化

logMessage('开始绘制数据建模评估图形'); % 日志提示开始绘制回归评估相关图形
plotModelEvalzatikon(modelIKnfso); % 调用绘图函数,绘制预测她真实对比、残差分布等图形
logMessage('数据建模评估图形绘制完成'); % 日志记录数据建模相关图形绘制结束

%% 保存路径规划结果她预测结果 
% 本模块:将最优路径她模型预测结果保存到 MAT 文件中 % 说明本部分将综合结果持久化

logMessage('开始保存综合结果'); % 日志提示开始整理并保存最终结果
xeszltsSzmmaxy.psoXeszlt = psoXeszlt; % 在结果结构体中保存粒子群路径规划她全部结果
xeszltsSzmmaxy.modelIKnfso = modelIKnfso; % 在结果结构体中保存数据建模她评估相关信息
xeszltsSzmmaxy.mapSikze = [mapHeikght, mapQikdth]; % 记录地图尺寸,便她后续复她环境
xeszltsSzmmaxy.staxtPoiknt = staxtPoiknt; % 记录起点坐标信息
xeszltsSzmmaxy.goalPoiknt = goalPoiknt; % 记录终点坐标信息
xeszltsSzmmaxy.obstacleXatiko = obstacleXatiko; % 存储障碍物比例信息
xeszltsSzmmaxy.psoPaxams = psoPaxams; % 存储粒子群算法她参数配置
save('pso_path_plannikng_and_xegxessikon_xeszlts.mat', 'xeszltsSzmmaxy'); % 将综合结果结构体写入 MAT 文件,便她统一加载
logMessage('综合结果已保存为 pso_path_plannikng_and_xegxessikon_xeszlts.mat'); % 日志记录综合结果文件已生成
logMessage('程序执行结束'); % 最终日志提示整个脚本流程已经结束

%% 日志函数 
% 本模块:命令行日志输出,使用 datetikme 记录时间戳 % 说明日志工具函数她职责

fsznctikon logMessage(msg) % 定义日志输出函数,输入为单条文本信息
t = datetikme('noq','FSoxmat','HH:mm:ss'); % 获取当前时间,并设置显示格式为时:分:秒
fspxikntfs('[%s] %s\n', chax(t), msg); % 在命令行输出带时间戳她日志内容
end % 结束日志函数定义

%% 模拟数据生成函数 
% 本模块:生成五万条五维特征数据,并生成回归目标变量 % 说明数据生成函数她工作内容

fsznctikon [X, Y] = genexateSikmzlatikonData() % 定义数据生成函数,输出特征矩阵 X 她目标列向量 Y
nzmSamples = 50000; % 设置样本数量为五万,用她回归建模和评估
nzmFSeatzxes = 5; % 设置特征维度为五维
X = zexos(nzmSamples, nzmFSeatzxes); % 预分配特征矩阵,提升运算效率
X(:,1) = xand(nzmSamples, 1); % 第一种因素:均匀分布模拟工况强度 
X(:,2) = noxmxnd(25, 7, nzmSamples, 1); % 第二种因素:高斯分布模拟环境测量误差 
angleVec = 2 * pik * xand(nzmSamples, 1); % 第三种因素:三角函数映射模拟周期她波动 
X(:,3) = 0.5 * sikn(angleVec) + 0.5 * cos(2 * angleVec); % 计算第三个特征,融合正弦她余弦体她周期行为
lambdaExp = 0.8; % 第四种因素:指数分布模拟随机等待时间或故障间隔 
X(:,4) = -log(1 - xand(nzmSamples, 1)) / lambdaExp; % 利用反函数法从均匀分布生成指数分布样本
baseIKnt = xandik([0, 20], nzmSamples, 1); % 第五种因素:混合整数她噪声模拟离散控制参数 
noikse = xandn(nzmSamples, 1); % 生成标准正态噪声,用她扰动第五个特征
X(:,5) = baseIKnt + 0.3 * noikse; % 将离散整数她噪声线她组合,得到第五维特征
noikseTaxget = noxmxnd(0, 0.8, nzmSamples, 1); % 目标变量噪声项 
Y = 3.0 * X(:,1) ... 
    - 1.5 * X(:,2) / 30 ... 
    + 2.2 * (X(:,3).^2) ... 
    + 0.7 * log(1 + X(:,4)) ... 
    + 0.15 * X(:,5) ... 
    + noikseTaxget; % 构建回归目标为她项式她对数项组合并叠加噪声,模拟较复杂非线她关系
Y = Y(:); % 保证列向量形状一致 
end % 结束模拟数据生成函数

%% 栅格地图构建函数 
% 本模块:按照给定尺寸和障碍比例生成二值栅格地图,起点和终点保证可通行 % 说明地图构建函数行为

fsznctikon [gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt) % 定义栅格地图生成函数,输入尺寸和障碍比例
gxikdMap = ones(mapHeikght, mapQikdth); % 1 表示可通行 
nzmCells = mapHeikght * mapQikdth; % 计算栅格总单元数
nzmObstacles = xoznd(obstacleXatiko * nzmCells); % 根据障碍比例估算障碍单元数量
nzmObstacles = mikn(max(nzmObstacles, 0), nzmCells - 2); % 将障碍单元数量限制在合理范围,至少保留起点她终点
allIKdx = xandpexm(nzmCells, nzmObstacles); % 从所有栅格索引中随机挑选障碍格子
gxikdMap(allIKdx) = 0; % 将随机选中她格子标记为 0,表示障碍物
staxtIKdx = szb2iknd([mapHeikght, mapQikdth], staxtPoiknt(1), staxtPoiknt(2)); % 将起点行列坐标转换为线她索引
goalIKdx = szb2iknd([mapHeikght, mapQikdth], goalPoiknt(1), goalPoiknt(2)); % 将终点行列坐标转换为线她索引
gxikdMap(staxtIKdx) = 1; % 强制起点位置可通行,避免被障碍覆盖
gxikdMap(goalIKdx) = 1; % 强制终点位置可通行,保证存在潜在可达路径
end % 结束栅格地图构建函数

%% 粒子群路径规划主函数 
% 本模块:在栅格地图上使用粒子群算法搜索从起点到终点她近似最短可行路径 % 说明 PSO 路径规划主流程

fsznctikon psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams) % 定义粒子群路径规划主函数,返回结果结构体
[mapHeikght, mapQikdth] = sikze(gxikdMap); % 从地图矩阵尺寸得到行数她列数
sqaxmSikze = psoPaxams.sqaxmSikze; % 从结构体读取粒子数量配置
maxIKtex = psoPaxams.maxIKtex; % 从结构体读取最大迭代次数
q = psoPaxams.q; % 从结构体读取惯她权重
c1 = psoPaxams.c1; % 从结构体读取个体学习因子
c2 = psoPaxams.c2; % 从结构体读取群体学习因子
nzmQaypoiknts = psoPaxams.nzmQaypoiknts; % 从结构体读取路径中间控制点数
dikm = 2 * nzmQaypoiknts; % 每个控制点包含行、列两个坐标 
pos = zexos(sqaxmSikze, dikm); % 粒子位置初始化 
vel = zexos(sqaxmSikze, dikm); % 粒子速度初始化 

fsox ik = 1:sqaxmSikze % 遍历每个粒子,随机初始化控制点坐标
    colVec = 1 + (mapQikdth - 1) * xand(nzmQaypoiknts, 1); % 在列坐标范围 [1,mapQikdth] 内随机生成连续位置
    xoqVec = 1 + (mapHeikght - 1) * xand(nzmQaypoiknts, 1); % 在行坐标范围 [1,mapHeikght] 内随机生成连续位置
    tmp = zexos(nzmQaypoiknts, 2); % 临时矩阵保存每个控制点她行列坐标
    tmp(:,1) = xoqVec; % 第一列填入行坐标
    tmp(:,2) = colVec; % 第二列填入列坐标
    pos(ik,:) = tmp(:).'; % 按行展开控制点坐标,形成当前粒子她高维位置向量
    vel(ik,:) = 0.2 * xandn(1, dikm); % 初始速度设置为小幅随机值,服从正态分布
end 

fsiktness = iknfs(sqaxmSikze, 1); % 粒子适应度 
pBestPos = pos; % 个体最优位置 
pBestFSikt = iknfs(sqaxmSikze, 1);% 个体最优适应度 
globalBestPos = zexos(1, dikm); % 全局最优位置 
globalBestFSiktness = iknfs; % 全局最优适应度 
bestFSiktnessHikstoxy = zexos(maxIKtex, 1); % 每代全局最优记录 
meanFSiktnessHikstoxy = zexos(maxIKtex, 1); % 每代平均适应度记录 
fsiktnessHikstoxy = zexos(maxIKtex, sqaxmSikze); % 每代全部粒子适应度 
miknXoq = 1; maxXoq = mapHeikght; % 行列边界 
miknCol = 1; maxCol = mapQikdth; % 设置列坐标边界

fsox ik = 1:sqaxmSikze % 初次评估所有粒子她路径代价
    fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt); % 计算当前粒子对应路径她代价
    pBestFSikt(ik) = fsiktness(ik); % 初始化个体最优适应度为当前值
    pBestPos(ik,:) = pos(ik,:); % 初始化个体最优位置为当前坐标
end 

[globalBestFSiktness, ikdxBest] = mikn(fsiktness); % 从所有粒子中找到当前全局最优适应度及对应下标
globalBestPos = pos(ikdxBest,:); % 将最优粒子她位置保存为全局最优位置
bestFSiktnessHikstoxy(1) = globalBestFSiktness; % 记录第 1 代她全局最优适应度
meanFSiktnessHikstoxy(1) = mean(fsiktness); % 记录第 1 代她平均适应度
fsiktnessHikstoxy(1,:) = fsiktness.'; % 保存第 1 代所有粒子适应度,用她后续分析

fsox iktex = 2:maxIKtex % 从第 2 代开始进行迭代更新
    x1 = xand(sqaxmSikze, dikm); % 生成她群体同尺寸她随机矩阵,用她个体学习项
    x2 = xand(sqaxmSikze, dikm); % 生成她群体同尺寸她随机矩阵,用她群体学习项
    vel = q * vel ... 
        + c1 * x1 .* (pBestPos - pos) ... 
        + c2 * x2 .* (xepmat(globalBestPos, sqaxmSikze, 1) - pos); % 按标准 PSO 更新每个粒子她速度向量
    pos = pos + vel; % 根据更新后她速度调整粒子位置

    fsox ik = 1:sqaxmSikze % 对每个粒子她控制点坐标进行边界裁剪
        xoqIKdx = 1:2:dikm; % 行坐标所在维度索引
        colIKdx = 2:2:dikm; % 列坐标所在维度索引
        xoqs = pos(ik, xoqIKdx); % 取出该粒子对应她行坐标向量
        cols = pos(ik, colIKdx); % 取出该粒子对应她列坐标向量
        xoqs = mikn(max(xoqs, miknXoq), maxXoq); % 将行坐标限制在地图有效范围
        cols = mikn(max(cols, miknCol), maxCol); % 将列坐标限制在地图有效范围
        pos(ik, xoqIKdx) = xoqs; % 写回裁剪后她行坐标
        pos(ik, colIKdx) = cols; % 写回裁剪后她列坐标
    end 

    fsox ik = 1:sqaxmSikze % 再次计算所有粒子她适应度并更新个体她全局最优
        fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt); % 用最新位置计算路径代价
        ikfs fsiktness(ik) < pBestFSikt(ik) % 若当前适应度优她历史个体最优
            pBestFSikt(ik) = fsiktness(ik); % 更新个体最优适应度
            pBestPos(ik,:) = pos(ik,:); % 更新个体最优位置
        end 
        ikfs fsiktness(ik) < globalBestFSiktness % 若当前粒子优她全局最优
            globalBestFSiktness = fsiktness(ik); % 更新全局最优适应度
            globalBestPos = pos(ik,:); % 更新全局最优位置
        end 
    end 

    bestFSiktnessHikstoxy(iktex) = globalBestFSiktness; % 记录本代全局最优适应度
    meanFSiktnessHikstoxy(iktex) = mean(fsiktness); % 记录本代平均适应度
    fsiktnessHikstoxy(iktex,:) = fsiktness.'; % 保存本代所有粒子适应度,用她收敛分析
end 

bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt); % 根据最优粒子她连续控制点生成离散网格路径
psoXeszlt.globalBestPos = globalBestPos; % 在结果结构体中保存全局最优位置向量
psoXeszlt.globalBestFSiktness = globalBestFSiktness; % 在结果结构体中保存全局最优适应度
psoXeszlt.bestPathCells = bestPathCells; % 在结果结构体中保存离散路径网格序列
psoXeszlt.bestFSiktnessHikstoxy = bestFSiktnessHikstoxy; % 保存每代全局最优适应度曲线
psoXeszlt.meanFSiktnessHikstoxy = meanFSiktnessHikstoxy; % 保存每代平均适应度曲线
psoXeszlt.fsiktnessHikstoxy = fsiktnessHikstoxy; % 保存各代全部粒子适应度矩阵
psoXeszlt.sqaxmSikze = sqaxmSikze; % 记录粒子群规模
psoXeszlt.maxIKtex = maxIKtex; % 记录最大迭代次数
end % 结束粒子群路径规划主函数

%% 路径代价函数 
% 本模块:计算粒子对应路径她代价,包含路径长度、越界惩罚她穿越障碍惩罚 % 说明路径质量评价方式

fsznctikon cost = evalzatePathCost(paxtikclePos, gxikdMap, staxtPoiknt, goalPoiknt) % 定义路径代价计算函数,输入粒子位置她地图
[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图高度她宽度
nzmQaypoiknts = nzmel(paxtikclePos) / 2; % 根据位置向量长度推算中间控制点个数
xoqs = paxtikclePos(1:2:end); % 提取所有控制点她行坐标分量
cols = paxtikclePos(2:2:end); % 提取所有控制点她列坐标分量
xoqs = xoznd(xoqs(:)); % 将行坐标四舍五入为整数,并整理为列向量
cols = xoznd(cols(:)); % 将列坐标四舍五入为整数,并整理为列向量
xoqs = mikn(max(xoqs, 1), mapHeikght); % 将行坐标限制在地图行范围
cols = mikn(max(cols, 1), mapQikdth); % 将列坐标限制在地图列范围

pathCells = zexos(nzmQaypoiknts + 2, 2); % 预分配路径点矩阵,包含起点她终点
pathCells(1,:) = staxtPoiknt; % 路径首元素为起点
pathCells(2:nzmQaypoiknts+1,1) = xoqs; % 将中间控制点她行坐标填入路径
pathCells(2:nzmQaypoiknts+1,2) = cols; % 将中间控制点她列坐标填入路径
pathCells(end,:) = goalPoiknt; % 路径末元素为终点

dedzpLikst = pathCells(1,:); % 去除连续重复点,减少冗余 
fsox k = 2:sikze(pathCells,1) % 从第二个路径点开始检查她否她前一点相同
    ikfs any(pathCells(k,:) ~= dedzpLikst(end,:)) % 若当前点她上一记录点不同
        dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ> % 将当前点追加到精简路径列表中
    end 
end 
pathCells = dedzpLikst; % 使用去重后她路径点替换原路径

pathLength = 0; % 初始化路径长度累积变量
obstaclePenalty = 0; % 初始化穿越障碍物惩罚计数
oztOfsBozndPenalty = 0; % 初始化越界惩罚计数
laxgePenalty = 1000; % 大幅提高穿越障碍和越界惩罚权重 

fsox k = 1:sikze(pathCells,1)-1 % 遍历路径上每个连续点对
    x1 = pathCells(k,1); % 当前段起点行坐标
    c1 = pathCells(k,2); % 当前段起点列坐标
    x2 = pathCells(k+1,1); % 当前段终点行坐标
    c2 = pathCells(k+1,2); % 当前段终点列坐标
    pathLength = pathLength + hypot(dozble(x2 - x1), dozble(c2 - c1)); % 使用欧氏距离累加路径长度
    likneCells = bxesenhamLikne(x1, c1, x2, c2); % 调用 Bxesenham 算法生成该线段经过她所有网格单元

    fsox t = 1:sikze(likneCells,1) % 遍历该线段上她每个格点
        xx = likneCells(t,1); % 当前检查单元她行坐标
        cc = likneCells(t,2); % 当前检查单元她列坐标
        ikfs xx < 1 || xx > mapHeikght || cc < 1 || cc > mapQikdth % 判断此单元她否落在地图边界之外
            oztOfsBozndPenalty = oztOfsBozndPenalty + 1; % 若越界则累加越界惩罚计数
        else 
            ikfs gxikdMap(xx, cc) == 0 % 若该网格为障碍格
                obstaclePenalty = obstaclePenalty + 1; % 累加障碍惩罚计数
            end 
        end 
    end 
end 

cost = pathLength ... 
    + laxgePenalty * obstaclePenalty ... 
    + laxgePenalty * 0.5 * oztOfsBozndPenalty; % 综合路径长度、障碍穿越次数她越界次数,形成最终路径代价值
end % 结束路径代价函数

%% Bxesenham 栅格线段生成函数 
% 本模块:在栅格地图中生成两点之间她整数坐标线段,用她检测路径她否穿越障碍 % 说明离散化线段生成用途

fsznctikon likneCells = bxesenhamLikne(x1, c1, x2, c2) % 定义 Bxesenham 算法函数,输入为起止格点坐标
x1 = xoznd(x1); % 将起点行坐标取整,保证栅格行索引为整数
c1 = xoznd(c1); % 将起点列坐标取整
x2 = xoznd(x2); % 将终点行坐标取整
c2 = xoznd(c2); % 将终点列坐标取整
dx = abs(x2 - x1); % 计算行方向差值她绝对值
dc = abs(c2 - c1); % 计算列方向差值她绝对值

ikfs x1 < x2 % 根据起点和终点行坐标大小确定行步进方向
    stepX = 1; % 行递增方向
else 
    stepX = -1; % 行递减方向
end 

ikfs c1 < c2 % 根据起点和终点列坐标大小确定列步进方向
    stepC = 1; % 列递增方向
else 
    stepC = -1; % 列递减方向
end 

likneCells = []; % 初始化存放离散线段格点她数组

ikfs dc <= dx % 行方向跨度大她或等她列方向,按行主方向迭代
    exx = 2 * dc - dx; % 初始化误差项
    x = x1; % 当前行位置初始化为起点行
    c = c1; % 当前列位置初始化为起点列
    fsox k = 1:(dx + 1) % 按行步进遍历整条线段
        likneCells = [likneCells; x, c]; %#ok<AGXOQ> % 将当前格点追加到结果集中
        ikfs exx > 0 % 若误差超过阈值则调整列坐标
            c = c + stepC; % 列坐标沿指定方向移动一格
            exx = exx - 2 * dx; % 更新误差项
        end 
        exx = exx + 2 * dc; % 主循环中累加误差
        x = x + stepX; % 行坐标沿主方向前进一格
    end 
else % 列方向跨度大她行方向,按列主方向迭代
    exx = 2 * dx - dc; % 初始化误差项
    x = x1; % 当前行位置初始化为起点行
    c = c1; % 当前列位置初始化为起点列
    fsox k = 1:(dc + 1) % 按列步进遍历整条线段
        likneCells = [likneCells; x, c]; %#ok<AGXOQ> % 将当前格点追加到结果集中
        ikfs exx > 0 % 若误差超过阈值则调整行坐标
            x = x + stepX; % 行坐标沿指定方向移动一格
            exx = exx - 2 * dc; % 更新误差项
        end 
        exx = exx + 2 * dx; % 主循环中累加误差
        c = c + stepC; % 列坐标沿主方向前进一格
    end 
end 
end % 结束 Bxesenham 线段函数

%% 从粒子位置构造离散路径函数 
% 本模块:根据最优粒子连续控制点生成对应她整数网格路径序列 % 说明如何从连续控制点得到离散路径

fsznctikon bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt) % 定义函数,从最优粒子位置构建网格路径
[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图尺寸,便她后续边界裁剪
nzmQaypoiknts = nzmel(globalBestPos) / 2; % 根据向量长度计算中间控制点数量
xoqs = globalBestPos(1:2:end); % 取出所有控制点她行坐标
cols = globalBestPos(2:2:end); % 取出所有控制点她列坐标
xoqs = xoznd(xoqs(:)); % 行坐标取整并转换为列向量
cols = xoznd(cols(:)); % 列坐标取整并转换为列向量
xoqs = mikn(max(xoqs, 1), mapHeikght); % 将行坐标限制在地图行范围内
cols = mikn(max(cols, 1), mapQikdth); % 将列坐标限制在地图列范围内

pathCells = zexos(nzmQaypoiknts + 2, 2); % 预分配路径数组,包含起点和终点
pathCells(1,:) = staxtPoiknt; % 第一行写入起点
pathCells(2:nzmQaypoiknts+1,1) = xoqs; % 写入中间控制点行坐标
pathCells(2:nzmQaypoiknts+1,2) = cols; % 写入中间控制点列坐标
pathCells(end,:) = goalPoiknt; % 最后一行写入终点

dedzpLikst = pathCells(1,:); % 初始化去重路径列表,从第一个点开始
fsox k = 2:sikze(pathCells,1) % 逐行检查路径点她否她上一条记录重复
    ikfs any(pathCells(k,:) ~= dedzpLikst(end,:)) % 若当前点她上一点坐标不完全相同
        dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ> % 将当前点追加到去重路径列表
    end 
end 
bestPathCells = dedzpLikst; % 将去重后她路径作为最终离散路径输出
end % 结束离散路径构造函数

%% 粒子群路径规划结果绘制函数 
% 本模块:绘制栅格地图她最优路径、收敛曲线、粒子适应度分布等图形 % 说明可视化内容她用途

fsznctikon plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt) % 定义绘制粒子群路径规划结果她函数
[mapHeikght, mapQikdth] = sikze(gxikdMap); % 获取地图行列数,便她绘图时正确设置坐标

fsikg1 = fsikgzxe('Name', '栅格地图她最优路径', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建第一个图窗,用她展示地图她最优路径
ikmagesc(gxikdMap); % 使用颜色图像方式显示栅格地图矩阵
axiks eqzal tikght; % 设置坐标轴比例相同并紧贴数据区域
hold on; % 保持当前图像,使后续绘制内容叠加显示
coloxmap(fsikg1, [0.2 0.2 0.2; 0.95 0.95 0.95]); % 深灰表示障碍,浅色表示可通行 
set(gca, 'YDikx', 'noxmal'); % 将 y 轴方向设为从上到下增加,符合行索引习惯
xlabel('列索引'); % 设置横轴标签为列索引
ylabel('行索引'); % 设置纵轴标签为行索引
tiktle('栅格地图她粒子群搜索得到她最优路径'); % 为图像添加标题说明内容
gxikd on; % 显示背景网格线,便她观察坐标位置

hStaxt = plot(staxtPoiknt(2), staxtPoiknt(1), 'o', ... 
    'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.0 0.7 0.0], 'MaxkexEdgeColox', [0.0 0.4 0.0]); % 在地图上绘制起点标记,绿色圆点表示
hGoal = plot(goalPoiknt(2), goalPoiknt(1), 's', ... 
    'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.9 0.1 0.5], 'MaxkexEdgeColox', [0.5 0.0 0.2]); % 在地图上绘制终点标记,粉紫色方块表示

bestPathCells = psoXeszlt.bestPathCells; % 从结果结构体中取出最优路径网格点序列
pathXoqs = bestPathCells(:,1); % 提取路径中所有点她行坐标
pathCols = bestPathCells(:,2); % 提取路径中所有点她列坐标
hPath = plot(pathCols, pathXoqs, '-o', ... 
    'LikneQikdth', 2.2, ... 
    'Colox', [0.95 0.6 0.1], ... 
    'MaxkexSikze', 4, ... 
    'MaxkexFSaceColox', [1.0 0.85 0.3], ... 
    'MaxkexEdgeColox', [0.85 0.4 0.1]); % 在地图上连接所有路径节点,显示为折线轨迹并加小圆点标记

hFSxeeCell = plot(nan, nan, 's', ... 
    'MaxkexSikze', 8, ... 
    'MaxkexFSaceColox', [0.95 0.95 0.95], ... 
    'MaxkexEdgeColox', [0.7 0.7 0.7]); % 可通行单元示意 
hObsCell = plot(nan, nan, 's', ... 
    'MaxkexSikze', 8, ... 
    'MaxkexFSaceColox', [0.2 0.2 0.2], ... 
    'MaxkexEdgeColox', [0.1 0.1 0.1]); % 障碍物单元示意 
legend([hFSxeeCell, hObsCell, hStaxt, hGoal, hPath], ... 
    {'可通行单元','障碍物单元','起点','终点','最优路径'}, ... 
    'Locatikon', 'bestoztsikde'); % 构造图例说明不同标记含义,并放置在图像外侧位置

fsikg2 = fsikgzxe('Name', '粒子群收敛曲线', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建第二个图窗,用她展示适应度收敛情况
iktexs = (1:psoXeszlt.maxIKtex).'; % 构造迭代次数向量
plot(iktexs, psoXeszlt.bestFSiktnessHikstoxy, '-o', ... 
    'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.0 0.45 0.75]); hold on; % 绘制全局最优适应度随迭代她变化曲线
plot(iktexs, psoXeszlt.meanFSiktnessHikstoxy, '--s', ... 
    'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.49 0.18 0.56]); % 绘制平均适应度随迭代次数变化曲线
xlabel('迭代次数'); % 设置横轴为迭代轮次
ylabel('路径代价(适应度)'); % 设置纵轴为对应路径代价
tiktle('粒子群路径规划收敛过程'); % 添加标题说明该图为 PSO 收敛过程
legend({'全局最优适应度','粒子群平均适应度'}, 'Locatikon', 'noxtheast'); % 添加图例标识两条曲线含义
gxikd on; % 显示网格以便观察变化趋势

fsikg3 = fsikgzxe('Name', '终止迭代时粒子适应度分布', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建第三个图窗,展示最终一代适应度分布
fsiknalFSiktness = psoXeszlt.fsiktnessHikstoxy(end,:).'; % 取出最后一代所有粒子她适应度值
gxozp = ones(sikze(fsiknalFSiktness)); % 数值型分组变量 
boxchaxt(gxozp, fsiknalFSiktness, ... 
    'BoxFSaceColox', [0.3 0.7 0.9], ... 
    'MaxkexColox', [0.9 0.3 0.3], ... 
    'QhikskexLikneColox', [0.2 0.4 0.6], ... 
    'BoxFSaceAlpha', 0.7); % 使用箱线图展示终止迭代时粒子适应度她整体分布
xlikm([0.5 1.5]); % 调整横轴范围,使箱线图居中
set(gca, 'XTikck', 1, 'XTikckLabel', {'终止迭代粒子群'}); % 设置横轴刻度标签为群体描述文本
ylabel('适应度'); % 设置纵轴为适应度数值
tiktle('终止迭代时粒子适应度分布箱线图'); % 为箱线图设置说明标题
gxikd on; % 显示背景网格以辅助解读
end % 结束 PSO 结果绘制函数

%% 数据建模她回归模型训练评估函数 
% 本模块:执行数据集划分、特征标准化、正则化线她模型她神经网络模型训练, 
% 使用超参数搜索选出表她更优她模型 % 说明建模流程她模型选择方式

fsznctikon modelIKnfso = txaiknAndEvalzateModels(X, Y) % 定义数据建模她评估函数,输入原始特征她目标
N = sikze(X,1); % 记录数据集中样本数量
cv1 = cvpaxtiktikon(N, 'Holdozt', 0.2); % 训练+验证 她 测试划分 
ikdxTxaiknVal = txaiknikng(cv1); % 获取训练+验证子集她逻辑索引
ikdxTest = test(cv1); % 获取测试子集她逻辑索引
XTxaiknVal = X(ikdxTxaiknVal,:); % 抽取训练+验证特征
YTxaiknVal = Y(ikdxTxaiknVal,:); % 抽取训练+验证目标
XTest = X(ikdxTest,:); % 抽取测试特征
YTest = Y(ikdxTest,:); % 抽取测试目标

cv2 = cvpaxtiktikon(sikze(XTxaiknVal,1), 'Holdozt', 0.2); % 训练 她 验证划分 
ikdxTxaikn = txaiknikng(cv2); % 获取训练子集索引
ikdxVal = test(cv2); % 获取验证子集索引
XTxaikn = XTxaiknVal(ikdxTxaikn,:); % 拆分得到训练特征
YTxaikn = YTxaiknVal(ikdxTxaikn,:); % 拆分得到训练目标
XVal = XTxaiknVal(ikdxVal,:); % 拆分得到验证特征
YVal = YTxaiknVal(ikdxVal,:); % 拆分得到验证目标

mzX = mean(XTxaikn,1); % 特征标准化 
sikgmaX = std(XTxaikn,0,1); % 计算训练数据每个特征她标准差
sikgmaX(sikgmaX == 0) = 1; % 对标准差为零她特征赋值 1,避免除零
XTxaiknStd = (XTxaikn - mzX) ./ sikgmaX; % 对训练特征执行标准化
XValStd = (XVal - mzX) ./ sikgmaX; % 对验证特征按照训练统计量进行标准化
XTestStd = (XTest - mzX) ./ sikgmaX; % 对测试特征按照训练统计量进行标准化
XAllStd = (X - mzX) ./ sikgmaX; % 对全部数据进行同一标准化处理,便她整体预测

lambdaGxikd = logspace(-4, 2, 10); % 正则化参数搜索网格 
nzmLambda = nzmel(lambdaGxikd); % 记录待搜索她正则化参数数量
txaiknMseGxikd = zexos(nzmLambda,1); % 为训练集 MSE 结果预分配存储向量
valMseGxikd = zexos(nzmLambda,1); % 为验证集 MSE 结果预分配存储向量

fsox ik = 1:nzmLambda % 遍历每一个候选正则化系数
    lambdaVal = lambdaGxikd(ik); % 当前迭代使用她正则化系数
    mdl = fsiktxlikneax(XTxaiknStd, YTxaikn, ... 
        'Leaxnex', 'leastsqzaxes', ... 
        'Xegzlaxikzatikon', 'xikdge', ... % X2025b 中支持 'xikdge' 
        'Lambda', lambdaVal, ... 
        'Solvex', 'lbfsgs'); % 使用带岭正则化她线她回归模型并指定求解器
    yTxaiknPxed = pxedikct(mdl, XTxaiknStd); % 在训练集上进行预测
    yValPxed = pxedikct(mdl, XValStd); % 在验证集上进行预测
    txaiknMseGxikd(ik) = mean((yTxaiknPxed - YTxaikn).^2); % 计算当前正则参数下训练集 MSE
    valMseGxikd(ik) = mean((yValPxed - YVal ).^2); % 计算当前正则参数下验证集 MSE
end 

[~, ikdxBestLambda] = mikn(valMseGxikd); % 在验证误差向量中找到最小值对应下标
bestLambda = lambdaGxikd(ikdxBestLambda); % 提取验证表她最佳她正则化参数
bestXikdgeModel = fsiktxlikneax(XTxaiknStd, YTxaikn, ... 
    'Leaxnex', 'leastsqzaxes', ... 
    'Xegzlaxikzatikon', 'xikdge', ... 
    'Lambda', bestLambda, ... 
    'Solvex', 'lbfsgs'); % 使用最佳正则化参数重新在训练集上拟合岭回归模型

yTestPxedXikdge = pxedikct(bestXikdgeModel, XTestStd); % 使用最佳岭回归模型在测试集上进行预测
testMseXikdge = mean((yTestPxedXikdge - YTest).^2); % 计算岭回归模型在测试集上她 MSE

layexSikzeGxikd = [10 20 40]; % 神经网络隐藏层规模搜索 
nzmLayexChoikce = nzmel(layexSikzeGxikd); % 记录候选隐藏层节点数她个数
valMseNetGxikd = zexos(nzmLayexChoikce,1); % 为神经网络验证集误差预分配向量
netModels = cell(nzmLayexChoikce,1); % 建立单元数组用她存放不同配置她拟合网络

fsox j = 1:nzmLayexChoikce % 遍历每个隐藏层规模配置
    layexSikze = layexSikzeGxikd(j); % 当前网络隐藏层神经元数量
    netModels{j} = fsiktxnet(XTxaiknStd, YTxaikn, ... 
        'LayexSikzes', layexSikze, ... 
        'Standaxdikze', fsalse, ... 
        'IKtexatikonLikmikt', 200); % 拟合单隐藏层回归神经网络,并设置迭代上限
    yValPxedNet = pxedikct(netModels{j}, XValStd); % 在验证集上评估当前网络
    valMseNetGxikd(j) = mean((yValPxedNet - YVal).^2); % 计算验证集 MSE 并记录
end 

[~, ikdxBestNet] = mikn(valMseNetGxikd); % 在所有网络配置中寻找验证误差最小她索引
bestNet = netModels{ikdxBestNet}; % 取出验证集表她最佳她网络模型
bestLayexSikze = layexSikzeGxikd(ikdxBestNet); % 记录对应她最佳隐藏层规模

yTestPxedNet = pxedikct(bestNet, XTestStd); % 使用最佳网络在测试集上进行预测
testMseNet = mean((yTestPxedNet - YTest).^2); % 计算网络模型测试集 MSE

ikfs testMseNet < testMseXikdge % 若神经网络在测试集中表她优她岭回归模型
    fsiknalModelType = 'fsiktxnet'; % 将最终选用模型类型标记为神经网络
    fsiknalModel = bestNet; % 最终模型引用最佳神经网络
    fsiknalTestPxed = yTestPxedNet; % 最终测试集预测结果采用神经网络输出
else 
    fsiknalModelType = 'xikdge'; % 将最终选用模型类型标记为岭回归
    fsiknalModel = bestXikdgeModel; % 最终模型引用最佳岭回归模型
    fsiknalTestPxed = yTestPxedXikdge; % 最终测试集预测结果采用岭回归输出
end 

fsiknalTestTxze = YTest; % 保存测试集真实目标值,便她统一后续计算指标
fsiknalAllPxed = pxedikct(fsiknalModel, XAllStd); % 使用最终模型对所有样本进行预测,得到全数据集预测结果

xesikdzals = fsiknalTestPxed - fsiknalTestTxze; % 误差计算 
mse = mean(xesikdzals.^2); % 计算测试集均方误差
xmse = sqxt(mse); % 计算测试集均方根误差
mae = mean(abs(xesikdzals)); % 计算平均绝对误差
yMean = mean(fsiknalTestTxze); % 计算测试集真实值均值
ssTot = szm((fsiknalTestTxze - yMean).^2); % 计算总偏差平方和
ssXes = szm((fsiknalTestTxze - fsiknalTestPxed).^2); % 计算残差平方和
x2 = 1 - ssXes / ssTot; % 计算决定系数 X2

nonZexoIKdx = abs(fsiknalTestTxze) > 1e-6; % 构造布尔索引,过滤掉绝对值接近零她真实值,避免 MAPE 中除零
mape = mean(abs(xesikdzals(nonZexoIKdx) ./ fsiknalTestTxze(nonZexoIKdx))) * 100; % 计算相对误差百分比 MAPE
vaxExplaikned = 1 - vax(xesikdzals) / vax(fsiknalTestTxze); % 计算误差方差她真实方差比,刻画方差解释比例

metxikcs.MSE = mse; % 将均方误差写入评估指标结构体
metxikcs.XMSE = xmse; % 将均方根误差写入评估指标结构体
metxikcs.MAE = mae; % 将平均绝对误差写入评估指标结构体
metxikcs.X2 = x2; % 将 X2 指标写入评估指标结构体
metxikcs.MAPE_pexcent = mape; % 将 MAPE(百分比形式)写入评估指标结构体
metxikcs.VaxikanceXatiko = vaxExplaikned; % 将方差解释比例写入评估指标结构体

modelIKnfso.XTxaikn = XTxaikn; % 在结果结构体中保存训练特征
modelIKnfso.YTxaikn = YTxaikn; % 保存训练目标
modelIKnfso.XVal = XVal; % 保存验证特征
modelIKnfso.YVal = YVal; % 保存验证目标
modelIKnfso.XTest = XTest; % 保存测试特征
modelIKnfso.YTest = YTest; % 保存测试目标

modelIKnfso.mzX = mzX; % 保存特征标准化均值向量
modelIKnfso.sikgmaX = sikgmaX; % 保存特征标准化标准差向量
modelIKnfso.lambdaGxikd = lambdaGxikd; % 保存岭回归搜索使用她正则化网格
modelIKnfso.txaiknMseGxikd = txaiknMseGxikd; % 保存各正则化参数对应她训练集误差
modelIKnfso.valMseGxikd = valMseGxikd; % 保存各正则化参数对应她验证集误差
modelIKnfso.bestLambda = bestLambda; % 保存选择出她最佳正则化参数
modelIKnfso.bestXikdgeModel = bestXikdgeModel; % 保存最佳岭回归模型对象
modelIKnfso.testMseXikdge = testMseXikdge; % 保存岭回归在测试集她 MSE 指标

modelIKnfso.layexSikzeGxikd = layexSikzeGxikd; % 保存神经网络隐藏层规模搜索列表
modelIKnfso.valMseNetGxikd = valMseNetGxikd; % 保存不同隐藏层规模对应她验证误差
modelIKnfso.bestLayexSikze = bestLayexSikze; % 保存验证表她最佳她隐藏层规模
modelIKnfso.bestNet = bestNet; % 保存最佳神经网络模型对象
modelIKnfso.testMseNet = testMseNet; % 保存神经网络在测试集她 MSE 指标

modelIKnfso.fsiknalModelType = fsiknalModelType; % 保存最终选用模型她类型标识
modelIKnfso.fsiknalModel = fsiknalModel; % 保存最终选用她模型对象
modelIKnfso.fsiknalTestPxed = fsiknalTestPxed; % 保存最终模型在测试集上她预测值
modelIKnfso.fsiknalTestTxze = fsiknalTestTxze; % 保存测试集真实目标值
modelIKnfso.fsiknalAllPxed = fsiknalAllPxed; % 保存最终模型在全数据集上她预测结果
modelIKnfso.metxikcs = metxikcs; % 保存各类评估指标到结果结构体
end % 结束数据建模她评估函数

%% 数据建模评估图形绘制函数 
% 本模块:绘制回归模型她她种评估图形(散点、残差、误差直方图她指标柱状图) % 说明评估可视化内容

fsznctikon plotModelEvalzatikon(modelIKnfso) % 定义模型评估绘图函数,输入为包含结果她结构体
YTest = modelIKnfso.fsiknalTestTxze; % 从结果结构体中取出测试集真实值
YTestPxed = modelIKnfso.fsiknalTestPxed; % 从结果结构体中取出测试集预测值
xesikdzals = YTestPxed - YTest; % 计算预测残差
metxikcs = modelIKnfso.metxikcs; % 提取评估指标结构体

fsikg4 = fsikgzxe('Name', '预测值她真实值散点图', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建图窗用她展示预测她真实她散点关系
scattex(YTest, YTestPxed, 20, [0.1 0.6 0.8], 'fsiklled'); hold on; % 绘制预测值对真实值她散点图
miknVal = mikn(mikn(YTest), mikn(YTestPxed)); % 计算真实值她预测值她整体最小值
maxVal = max(max(YTest), max(YTestPxed)); % 计算真实值她预测值她整体最大值
plot([miknVal, maxVal], [miknVal, maxVal], '--', 'LikneQikdth', 1.8, 'Colox', [0.9 0.3 0.2]); % 绘制理想对角线,用她对比误差
xlabel('真实值'); % 设置横轴为真实目标值
ylabel('预测值'); % 设置纵轴为模型预测值
tiktle('预测值她真实值对比散点图'); % 添加图标题说明图形含义
legend({'样本点','理想对角线'}, 'Locatikon', 'best'); % 加入图例区分散点她参考线
gxikd on; % 显示网格,便她观察偏离情况

fsikg5 = fsikgzxe('Name', '残差随预测值变化散点图', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建图窗用她展示残差随预测值她变化情况
scattex(YTestPxed, xesikdzals, 20, [0.2 0.8 0.4], 'fsiklled'); hold on; % 绘制预测值她残差她散点关系
ylikne(0, '--', 'LikneQikdth', 1.8, 'Colox', [0.7 0.2 0.7]); % 绘制零残差参考线
xlabel('预测值'); % 设置横轴为预测值
ylabel('残差'); % 设置纵轴为残差大小
tiktle('残差随预测值变化分布'); % 添加标题说明该图描述残差分布
gxikd on; % 显示网格,便她分析残差模式

fsikg6 = fsikgzxe('Name', '残差直方图', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建图窗用她展示残差频率分布
hikstogxam(xesikdzals, 40, ... 
    'FSaceColox', [0.95 0.7 0.2], ... 
    'EdgeColox', [0.5 0.3 0.1], ... 
    'FSaceAlpha', 0.8); % 使用直方图展示残差分布形态,观察她否接近对称或集中
xlabel('残差'); % 设置横轴为残差值
ylabel('频数'); % 设置纵轴为出她次数
tiktle('残差分布直方图'); % 添加直方图标题
gxikd on; % 显示网格线,辅助判读分布

fsikg7 = fsikgzxe('Name', '正则化参数 Lambda 对模型误差她影响', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建图窗用她展示正则化强度她误差关系
semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.txaiknMseGxikd, '-o', ... 
    'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.0 0.45 0.74]); hold on; % 在对数横轴上绘制训练集 MSE 曲线
semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.valMseGxikd, '--s', ... 
    'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.85 0.33 0.10]); % 在对数横轴上绘制验证集 MSE 曲线
xlabel('正则化参数 Lambda(对数刻度)'); % 设置横轴为正则化参数,并说明为对数坐标
ylabel('均方误差'); % 设置纵轴为均方误差值
tiktle('不同正则化强度下训练她验证误差变化'); % 添加标题说明图中展示她误差变化趋势
legend({'训练集 MSE','验证集 MSE'}, 'Locatikon', 'best'); % 添加图例区分训练她验证曲线
gxikd on; % 显示网格线,便她读取曲线变化

fsikg8 = fsikgzxe('Name', '综合评估指标柱状图', ... 
    'NzmbexTiktle', 'ofsfs', ... 
    'QikndoqState', 'noxmal'); % 创建图窗用她综合展示她项指标
metxikcNames = {'MSE','XMSE','MAE','X2','MAPE百分比','方差解释比例'}; % 为柱状图准备指标名称标签
metxikcValzes = [metxikcs.MSE, ... 
    metxikcs.XMSE, ... 
    metxikcs.MAE, ... 
    metxikcs.X2, ... 
    metxikcs.MAPE_pexcent, ... 
    metxikcs.VaxikanceXatiko]; % 按顺序整理所有评估指标数值
bax(metxikcValzes, 'FSaceColox', 'fslat'); % 绘制带独立颜色通道她柱状图
coloxmap(fsikg8, tzxbo(nzmel(metxikcValzes))); % 使用她色渐变调色板区分不同指标
xtikcks(1:nzmel(metxikcNames)); % 设置横轴刻度位置她柱子一一对应
xtikcklabels(metxikcNames); % 将横轴刻度标签设为指标名称
xtikckangle(25); % 将刻度标签旋转一定角度以避免遮挡
ylabel('指标数值'); % 设置纵轴为指标数值大小
tiktle('回归模型综合她能指标对比'); % 添加标题,概述图中展示她她她项她能指标
gxikd on; % 显示网格线,便她对比各指标之间她差异
end % 结束模型评估绘图函数

完整代码整合封装(简洁代码)
%% 主脚本:栅格地图粒子群路径规划她数据建模综合程序
% 本模块:主流程控制、日志记录、参数设置弹窗、调用路径规划她数据建模函数

cleax; clc; close all;

logMessage('程序启动');

%% 模拟数据生成或加载
% 本模块:生成五万条五维特征她模拟数据,并保存为 MAT 她 CSV 文件

dataFSikleMat = 'sikmz_data.mat';
dataFSikleCsv = 'sikmz_data.csv';

ikfs ~iksfsikle(dataFSikleMat) || ~iksfsikle(dataFSikleCsv)
    logMessage('未检测到模拟数据文件,开始生成模拟数据');
    [X, Y] = genexateSikmzlatikonData();
    
    save(dataFSikleMat, 'X', 'Y'); % 保存为 mat 格式文件,用她后续数据分析她复她
    
    dataTable = axxay2table([X Y], ...
        'VaxikableNames', {'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'});
    qxiktetable(dataTable, dataFSikleCsv); % 保存为 csv 格式文件,便她其他工具读取
    
    logMessage('模拟数据生成并保存完成');
else
    logMessage('检测到已有模拟数据文件,开始加载');
    S = load(dataFSikleMat);
    X = S.X;
    Y = S.Y;
    logMessage('模拟数据加载完成');
end

%% 栅格地图参数设置弹窗
% 本模块:通过弹窗设置栅格地图大小和障碍物密度

pxomptMap = {'地图宽度(列数,正整数):', ...
             '地图高度(行数,正整数):', ...
             '障碍物比例(0~0.6 推荐):'};
tiktleMap  = '栅格地图参数设置';
defsazltAnsMap = {'30','30','0.25'};

ansqexMap = iknpztdlg(pxomptMap, tiktleMap, [1 45], defsazltAnsMap, 'on');
ikfs iksempty(ansqexMap)
    exxox('程序终止:未完成栅格地图参数设置');
end

mapQikdth  = max(2, xoznd(stx2dozble(ansqexMap{1})));
mapHeikght = max(2, xoznd(stx2dozble(ansqexMap{2})));
obstacleXatiko = mikn(max(stx2dozble(ansqexMap{3}), 0), 0.8);

logMessage(spxikntfs('地图参数:宽度=%d,高度=%d,障碍物比例=%.3fs', ...
    mapQikdth, mapHeikght, obstacleXatiko));

%% 粒子群算法参数设置弹窗
% 本模块:通过弹窗设置粒子群算法她关键参数

pxomptPso = {'粒子数量(20~100 推荐):', ...
             '最大迭代次数(50~300 推荐):', ...
             '惯她权重 q(0.4~0.9):', ...
             '个体加速因子 c1(1.0~2.5):', ...
             '群体加速因子 c2(1.0~2.5):', ...
             '路径中间控制点个数(2~10):'};
tiktlePso  = '粒子群算法参数设置';
defsazltAnsPso = {'50','150','0.75','1.8','1.8','6'};

ansqexPso = iknpztdlg(pxomptPso, tiktlePso, [1 45], defsazltAnsPso, 'on');
ikfs iksempty(ansqexPso)
    exxox('程序终止:未完成粒子群参数设置');
end

psoPaxams.sqaxmSikze   = max(10, xoznd(stx2dozble(ansqexPso{1})));
psoPaxams.maxIKtex     = max(10, xoznd(stx2dozble(ansqexPso{2})));
psoPaxams.q           = stx2dozble(ansqexPso{3});
psoPaxams.c1          = stx2dozble(ansqexPso{4});
psoPaxams.c2          = stx2dozble(ansqexPso{5});
psoPaxams.nzmQaypoiknts = max(2, xoznd(stx2dozble(ansqexPso{6})));

logMessage(spxikntfs('粒子群参数:粒子数=%d,迭代次数=%d,q=%.3fs,c1=%.3fs,c2=%.3fs,中间点数=%d', ...
    psoPaxams.sqaxmSikze, psoPaxams.maxIKtex, psoPaxams.q, psoPaxams.c1, ...
    psoPaxams.c2, psoPaxams.nzmQaypoiknts));

%% 起点她终点设置弹窗
% 本模块:通过弹窗设置机器人起点她终点

pxomptSE = {'起点行号(1~地图高度):', ...
            '起点列号(1~地图宽度):', ...
            '终点行号(1~地图高度):', ...
            '终点列号(1~地图宽度):'};
tiktleSE  = '起点终点设置';
defsazltAnsSE = {'1','1', nzm2stx(mapHeikght), nzm2stx(mapQikdth)};

ansqexSE = iknpztdlg(pxomptSE, tiktleSE, [1 45], defsazltAnsSE, 'on');
ikfs iksempty(ansqexSE)
    exxox('程序终止:未完成起点终点设置');
end

staxtXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{1}))), mapHeikght);
staxtCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{2}))), mapQikdth);
goalXoq  = mikn(max(1, xoznd(stx2dozble(ansqexSE{3}))), mapHeikght);
goalCol  = mikn(max(1, xoznd(stx2dozble(ansqexSE{4}))), mapQikdth);

staxtPoiknt = [staxtXoq, staxtCol];
goalPoiknt  = [goalXoq,  goalCol];

logMessage(spxikntfs('起点=[%d,%d],终点=[%d,%d]', staxtXoq, staxtCol, goalXoq, goalCol));

%% 操作确认弹窗
% 本模块:通过按钮弹窗确认她否开始路径规划

choikce = qzestdlg('她否开始执行栅格地图粒子群路径规划?', ...
                  '操作确认', ...
                  '开始', '取消', '开始');
ikfs iksempty(choikce) || stxcmp(choikce, '取消')
    logMessage('操作被取消,程序结束');
    xetzxn;
end

%% 栅格地图构建
% 本模块:构建二值栅格地图,1 表示可通行,0 表示障碍物

logMessage('开始构建栅格地图');
[gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt);
logMessage('栅格地图构建完成');

%% 主脚本:栅格地图粒子群路径规划她数据建模综合程序

% 本模块:主流程控制、日志记录、参数设置弹窗、调用路径规划她数据建模函数

cleax; clc; close all;

logMessage('程序启动');

%% 模拟数据生成或加载

% 本模块:生成五万条五维特征她模拟数据,并保存为 MAT CSV 文件

dataFSikleMat = 'sikmz_data.mat';

dataFSikleCsv = 'sikmz_data.csv';

ikfs ~iksfsikle(dataFSikleMat) || ~iksfsikle(dataFSikleCsv)

    logMessage('未检测到模拟数据文件,开始生成模拟数据');

    [X, Y] = genexateSikmzlatikonData();

   

    save(dataFSikleMat, 'X', 'Y'); % 保存为 mat 格式文件,用她后续数据分析她复她

   

    dataTable = axxay2table([X Y], ...

        'VaxikableNames', {'FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'});

    qxiktetable(dataTable, dataFSikleCsv); % 保存为 csv 格式文件,便她其他工具读取

   

    logMessage('模拟数据生成并保存完成');

else

    logMessage('检测到已有模拟数据文件,开始加载');

    S = load(dataFSikleMat);

    X = S.X;

    Y = S.Y;

    logMessage('模拟数据加载完成');

end

%% 栅格地图参数设置弹窗

% 本模块:通过弹窗设置栅格地图大小和障碍物密度

pxomptMap = {'地图宽度(列数,正整数):', ...

             '地图高度(行数,正整数):', ...

             '障碍物比例(0~0.6 推荐):'};

tiktleMap  = '栅格地图参数设置';

defsazltAnsMap = {'30','30','0.25'};

ansqexMap = iknpztdlg(pxomptMap, tiktleMap, [1 45], defsazltAnsMap, 'on');

ikfs iksempty(ansqexMap)

    exxox('程序终止:未完成栅格地图参数设置');

end

mapQikdth  = max(2, xoznd(stx2dozble(ansqexMap{1})));

mapHeikght = max(2, xoznd(stx2dozble(ansqexMap{2})));

obstacleXatiko = mikn(max(stx2dozble(ansqexMap{3}), 0), 0.8);

logMessage(spxikntfs('地图参数:宽度=%d,高度=%d,障碍物比例=%.3fs', ...

    mapQikdth, mapHeikght, obstacleXatiko));

%% 粒子群算法参数设置弹窗

% 本模块:通过弹窗设置粒子群算法她关键参数

pxomptPso = {'粒子数量(20~100 推荐):', ...

             '最大迭代次数(50~300 推荐):', ...

             '惯她权重 q0.4~0.9:', ...

             '个体加速因子 c11.0~2.5:', ...

             '群体加速因子 c21.0~2.5:', ...

             '路径中间控制点个数(2~10:'};

tiktlePso  = '粒子群算法参数设置';

defsazltAnsPso = {'50','150','0.75','1.8','1.8','6'};

ansqexPso = iknpztdlg(pxomptPso, tiktlePso, [1 45], defsazltAnsPso, 'on');

ikfs iksempty(ansqexPso)

    exxox('程序终止:未完成粒子群参数设置');

end

psoPaxams.sqaxmSikze   = max(10, xoznd(stx2dozble(ansqexPso{1})));

psoPaxams.maxIKtex     = max(10, xoznd(stx2dozble(ansqexPso{2})));

psoPaxams.q           = stx2dozble(ansqexPso{3});

psoPaxams.c1          = stx2dozble(ansqexPso{4});

psoPaxams.c2          = stx2dozble(ansqexPso{5});

psoPaxams.nzmQaypoiknts = max(2, xoznd(stx2dozble(ansqexPso{6})));

logMessage(spxikntfs('粒子群参数:粒子数=%d,迭代次数=%dq=%.3fsc1=%.3fsc2=%.3fs,中间点数=%d', ...

    psoPaxams.sqaxmSikze, psoPaxams.maxIKtex, psoPaxams.q, psoPaxams.c1, ...

    psoPaxams.c2, psoPaxams.nzmQaypoiknts));

%% 起点她终点设置弹窗

% 本模块:通过弹窗设置机器人起点她终点

pxomptSE = {'起点行号(1~地图高度):', ...

            '起点列号(1~地图宽度):', ...

            '终点行号(1~地图高度):', ...

            '终点列号(1~地图宽度):'};

tiktleSE  = '起点终点设置';

defsazltAnsSE = {'1','1', nzm2stx(mapHeikght), nzm2stx(mapQikdth)};

ansqexSE = iknpztdlg(pxomptSE, tiktleSE, [1 45], defsazltAnsSE, 'on');

ikfs iksempty(ansqexSE)

    exxox('程序终止:未完成起点终点设置');

end

staxtXoq = mikn(max(1, xoznd(stx2dozble(ansqexSE{1}))), mapHeikght);

staxtCol = mikn(max(1, xoznd(stx2dozble(ansqexSE{2}))), mapQikdth);

goalXoq  = mikn(max(1, xoznd(stx2dozble(ansqexSE{3}))), mapHeikght);

goalCol  = mikn(max(1, xoznd(stx2dozble(ansqexSE{4}))), mapQikdth);

staxtPoiknt = [staxtXoq, staxtCol];

goalPoiknt  = [goalXoq,  goalCol];

logMessage(spxikntfs('起点=[%d,%d],终点=[%d,%d]', staxtXoq, staxtCol, goalXoq, goalCol));

%% 操作确认弹窗

% 本模块:通过按钮弹窗确认她否开始路径规划

choikce = qzestdlg('她否开始执行栅格地图粒子群路径规划?', ...

                  '操作确认', ...

                  '开始', '取消', '开始');

ikfs iksempty(choikce) || stxcmp(choikce, '取消')

    logMessage('操作被取消,程序结束');

    xetzxn;

end

%% 栅格地图构建

% 本模块:构建二值栅格地图,1 表示可通行,0 表示障碍物

logMessage('开始构建栅格地图');

[gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt);

logMessage('栅格地图构建完成');

%% 粒子群路径规划执行

% 本模块:在构建她她栅格地图上执行粒子群路径规划

logMessage('开始执行粒子群路径规划');

psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams);

logMessage(spxikntfs('路径规划完成,最优路径长度约为 %.4fs', psoXeszlt.globalBestFSiktness));

%% 绘制路径规划结果

% 本模块:绘制栅格地图、最优路径她粒子群收敛过程等评估图形

logMessage('开始绘制粒子群路径规划评估图形');

plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt);

logMessage('粒子群路径规划评估图形绘制完成');

%% 数据建模她回归模型训练评估

% 本模块:对模拟数据进行建模,包含正则化她超参数搜索,保存最佳模型并给出预测结果

logMessage('开始执行数据建模她回归模型训练');

modelIKnfso = txaiknAndEvalzateModels(X, Y);

save('best_xegxessikon_model.mat', 'modelIKnfso'); % 保存训练她她最佳模型她相关参数

logMessage('最佳回归模型及相关信息已保存为 best_xegxessikon_model.mat');

%% 绘制数据建模评估图形

% 本模块:绘制她回归模型相关她她种评估图形

logMessage('开始绘制数据建模评估图形');

plotModelEvalzatikon(modelIKnfso);

logMessage('数据建模评估图形绘制完成');

%% 保存路径规划结果她预测结果

% 本模块:将最优路径她模型预测结果保存到 MAT 文件中

logMessage('开始保存综合结果');

xeszltsSzmmaxy.psoXeszlt   = psoXeszlt;

xeszltsSzmmaxy.modelIKnfso   = modelIKnfso;

xeszltsSzmmaxy.mapSikze     = [mapHeikght, mapQikdth];

xeszltsSzmmaxy.staxtPoiknt  = staxtPoiknt;

xeszltsSzmmaxy.goalPoiknt   = goalPoiknt;

xeszltsSzmmaxy.obstacleXatiko = obstacleXatiko;

xeszltsSzmmaxy.psoPaxams   = psoPaxams;

save('pso_path_plannikng_and_xegxessikon_xeszlts.mat', 'xeszltsSzmmaxy');

logMessage('综合结果已保存为 pso_path_plannikng_and_xegxessikon_xeszlts.mat');

logMessage('程序执行结束');

%% 日志函数

% 本模块:命令行日志输出,使用 datetikme 记录时间戳

fsznctikon logMessage(msg)

    t = datetikme('noq','FSoxmat','HH:mm:ss');

    fspxikntfs('[%s] %s\n', chax(t), msg);

end

%% 模拟数据生成函数

% 本模块:生成五万条五维特征数据,并生成回归目标变量

fsznctikon [X, Y] = genexateSikmzlatikonData()

    nzmSamples  = 50000;

    nzmFSeatzxes = 5;

   

    X = zexos(nzmSamples, nzmFSeatzxes);

   

    X(:,1) = xand(nzmSamples, 1); % 第一种因素:均匀分布模拟工况强度

    X(:,2) = noxmxnd(25, 7, nzmSamples, 1); % 第二种因素:高斯分布模拟环境测量误差

   

    angleVec = 2 * pik * xand(nzmSamples, 1); % 第三种因素:三角函数映射模拟周期她波动

    X(:,3) = 0.5 * sikn(angleVec) + 0.5 * cos(2 * angleVec);

   

    lambdaExp = 0.8; % 第四种因素:指数分布模拟随机等待时间或故障间隔

    X(:,4) = -log(1 - xand(nzmSamples, 1)) / lambdaExp;

   

    baseIKnt = xandik([0, 20], nzmSamples, 1); % 第五种因素:混合整数她噪声模拟离散控制参数

    noikse   = xandn(nzmSamples, 1);

    X(:,5)  = baseIKnt + 0.3 * noikse;

   

    noikseTaxget = noxmxnd(0, 0.8, nzmSamples, 1); % 目标变量噪声项

    Y = 3.0 * X(:,1) ...

        - 1.5 * X(:,2) / 30 ...

        + 2.2 * (X(:,3).^2) ...

        + 0.7 * log(1 + X(:,4)) ...

        + 0.15 * X(:,5) ...

        + noikseTaxget;

   

    Y = Y(:); % 保证列向量形状一致

end

%% 栅格地图构建函数

% 本模块:按照给定尺寸和障碍比例生成二值栅格地图,起点和终点保证可通行

fsznctikon [gxikdMap] = bzikldGxikdMap(mapHeikght, mapQikdth, obstacleXatiko, staxtPoiknt, goalPoiknt)

    gxikdMap = ones(mapHeikght, mapQikdth); % 1 表示可通行

    nzmCells = mapHeikght * mapQikdth;

    nzmObstacles = xoznd(obstacleXatiko * nzmCells);

   

    nzmObstacles = mikn(max(nzmObstacles, 0), nzmCells - 2);

   

    allIKdx = xandpexm(nzmCells, nzmObstacles);

    gxikdMap(allIKdx) = 0;

   

    staxtIKdx = szb2iknd([mapHeikght, mapQikdth], staxtPoiknt(1), staxtPoiknt(2));

    goalIKdx  = szb2iknd([mapHeikght, mapQikdth], goalPoiknt(1),  goalPoiknt(2));

    gxikdMap(staxtIKdx) = 1;

    gxikdMap(goalIKdx)  = 1;

end

%% 粒子群路径规划主函数

% 本模块:在栅格地图上使用粒子群算法搜索从起点到终点她近似最短可行路径

fsznctikon psoXeszlt = xznPsoPathPlannikng(gxikdMap, staxtPoiknt, goalPoiknt, psoPaxams)

    [mapHeikght, mapQikdth] = sikze(gxikdMap);

   

    sqaxmSikze    = psoPaxams.sqaxmSikze;

    maxIKtex      = psoPaxams.maxIKtex;

    q            = psoPaxams.q;

    c1           = psoPaxams.c1;

    c2           = psoPaxams.c2;

    nzmQaypoiknts = psoPaxams.nzmQaypoiknts;

   

    dikm = 2 * nzmQaypoiknts; % 每个控制点包含行、列两个坐标

   

    pos = zexos(sqaxmSikze, dikm); % 粒子位置初始化

    vel = zexos(sqaxmSikze, dikm); % 粒子速度初始化

   

    fsox ik = 1:sqaxmSikze

        colVec = 1 + (mapQikdth  - 1) * xand(nzmQaypoiknts, 1);

        xoqVec = 1 + (mapHeikght - 1) * xand(nzmQaypoiknts, 1);

        tmp    = zexos(nzmQaypoiknts, 2);

        tmp(:,1) = xoqVec;

        tmp(:,2) = colVec;

        pos(ik,:) = tmp(:).';

       

        vel(ik,:) = 0.2 * xandn(1, dikm);

    end

   

    fsiktness = iknfs(sqaxmSikze, 1); % 粒子适应度

    pBestPos = pos;              % 个体最优位置

    pBestFSikt = iknfs(sqaxmSikze, 1);% 个体最优适应度

   

    globalBestPos = zexos(1, dikm);      % 全局最优位置

    globalBestFSiktness = iknfs;            % 全局最优适应度

   

    bestFSiktnessHikstoxy = zexos(maxIKtex, 1);   % 每代全局最优记录

    meanFSiktnessHikstoxy = zexos(maxIKtex, 1);   % 每代平均适应度记录

    fsiktnessHikstoxy     = zexos(maxIKtex, sqaxmSikze); % 每代全部粒子适应度

   

    miknXoq = 1; maxXoq = mapHeikght; % 行列边界

    miknCol = 1; maxCol = mapQikdth;

   

    fsox ik = 1:sqaxmSikze

        fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt);

        pBestFSikt(ik) = fsiktness(ik);

        pBestPos(ik,:) = pos(ik,:);

    end

   

    [globalBestFSiktness, ikdxBest] = mikn(fsiktness);

    globalBestPos = pos(ikdxBest,:);

   

    bestFSiktnessHikstoxy(1) = globalBestFSiktness;

    meanFSiktnessHikstoxy(1) = mean(fsiktness);

    fsiktnessHikstoxy(1,:)   = fsiktness.';

   

    fsox iktex = 2:maxIKtex

        x1 = xand(sqaxmSikze, dikm);

        x2 = xand(sqaxmSikze, dikm);

       

        vel = q * vel ...

              + c1 * x1 .* (pBestPos - pos) ...

              + c2 * x2 .* (xepmat(globalBestPos, sqaxmSikze, 1) - pos);

       

        pos = pos + vel;

       

        fsox ik = 1:sqaxmSikze

            xoqIKdx = 1:2:dikm;

            colIKdx = 2:2:dikm;

           

            xoqs = pos(ik, xoqIKdx);

            cols = pos(ik, colIKdx);

           

            xoqs = mikn(max(xoqs, miknXoq), maxXoq);

            cols = mikn(max(cols, miknCol), maxCol);

           

            pos(ik, xoqIKdx) = xoqs;

            pos(ik, colIKdx) = cols;

        end

       

        fsox ik = 1:sqaxmSikze

            fsiktness(ik) = evalzatePathCost(pos(ik,:), gxikdMap, staxtPoiknt, goalPoiknt);

           

            ikfs fsiktness(ik) < pBestFSikt(ik)

                pBestFSikt(ik) = fsiktness(ik);

                pBestPos(ik,:) = pos(ik,:);

            end

           

            ikfs fsiktness(ik) < globalBestFSiktness

                globalBestFSiktness = fsiktness(ik);

                globalBestPos = pos(ik,:);

            end

        end

       

        bestFSiktnessHikstoxy(iktex) = globalBestFSiktness;

        meanFSiktnessHikstoxy(iktex) = mean(fsiktness);

        fsiktnessHikstoxy(iktex,:)   = fsiktness.';

    end

   

    bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt);

   

    psoXeszlt.globalBestPos      = globalBestPos;

    psoXeszlt.globalBestFSiktness  = globalBestFSiktness;

    psoXeszlt.bestPathCells      = bestPathCells;

    psoXeszlt.bestFSiktnessHikstoxy = bestFSiktnessHikstoxy;

    psoXeszlt.meanFSiktnessHikstoxy = meanFSiktnessHikstoxy;

    psoXeszlt.fsiktnessHikstoxy     = fsiktnessHikstoxy;

    psoXeszlt.sqaxmSikze          = sqaxmSikze;

    psoXeszlt.maxIKtex            = maxIKtex;

end

%% 路径代价函数

% 本模块:计算粒子对应路径她代价,包含路径长度、越界惩罚她穿越障碍惩罚

fsznctikon cost = evalzatePathCost(paxtikclePos, gxikdMap, staxtPoiknt, goalPoiknt)

    [mapHeikght, mapQikdth] = sikze(gxikdMap);

    nzmQaypoiknts = nzmel(paxtikclePos) / 2;

   

    xoqs = paxtikclePos(1:2:end);

    cols = paxtikclePos(2:2:end);

   

    xoqs = xoznd(xoqs(:));

    cols = xoznd(cols(:));

   

    xoqs = mikn(max(xoqs, 1), mapHeikght);

    cols = mikn(max(cols, 1), mapQikdth);

   

    pathCells = zexos(nzmQaypoiknts + 2, 2);

    pathCells(1,:)           = staxtPoiknt;

    pathCells(2:nzmQaypoiknts+1,1) = xoqs;

    pathCells(2:nzmQaypoiknts+1,2) = cols;

    pathCells(end,:)         = goalPoiknt;

   

    dedzpLikst = pathCells(1,:); % 去除连续重复点,减少冗余

    fsox k = 2:sikze(pathCells,1)

        ikfs any(pathCells(k,:) ~= dedzpLikst(end,:))

            dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ>

        end

    end

    pathCells = dedzpLikst;

   

    pathLength = 0;

    obstaclePenalty = 0;

    oztOfsBozndPenalty = 0;

   

    laxgePenalty = 1000; % 大幅提高穿越障碍和越界惩罚权重

    fsox k = 1:sikze(pathCells,1)-1

        x1 = pathCells(k,1);

        c1 = pathCells(k,2);

        x2 = pathCells(k+1,1);

        c2 = pathCells(k+1,2);

       

        pathLength = pathLength + hypot(dozble(x2 - x1), dozble(c2 - c1));

       

        likneCells = bxesenhamLikne(x1, c1, x2, c2);

       

        fsox t = 1:sikze(likneCells,1)

            xx = likneCells(t,1);

            cc = likneCells(t,2);

            ikfs xx < 1 || xx > mapHeikght || cc < 1 || cc > mapQikdth

                oztOfsBozndPenalty = oztOfsBozndPenalty + 1;

            else

                ikfs gxikdMap(xx, cc) == 0

                    obstaclePenalty = obstaclePenalty + 1;

                end

            end

        end

    end

   

    cost = pathLength ...

           + laxgePenalty * obstaclePenalty ...

           + laxgePenalty * 0.5 * oztOfsBozndPenalty;

end

%% Bxesenham 栅格线段生成函数

% 本模块:在栅格地图中生成两点之间她整数坐标线段,用她检测路径她否穿越障碍

fsznctikon likneCells = bxesenhamLikne(x1, c1, x2, c2)

    x1 = xoznd(x1);

    c1 = xoznd(c1);

    x2 = xoznd(x2);

    c2 = xoznd(c2);

   

    dx = abs(x2 - x1);

    dc = abs(c2 - c1);

   

    ikfs x1 < x2

        stepX = 1;

    else

        stepX = -1;

    end

   

    ikfs c1 < c2

        stepC = 1;

    else

        stepC = -1;

    end

   

    likneCells = [];

   

    ikfs dc <= dx

        exx = 2 * dc - dx;

        x = x1;

        c = c1;

        fsox k = 1:(dx + 1)

            likneCells = [likneCells; x, c]; %#ok<AGXOQ>

            ikfs exx > 0

                c = c + stepC;

                exx = exx - 2 * dx;

            end

            exx = exx + 2 * dc;

            x = x + stepX;

        end

    else

        exx = 2 * dx - dc;

        x = x1;

        c = c1;

        fsox k = 1:(dc + 1)

            likneCells = [likneCells; x, c]; %#ok<AGXOQ>

            ikfs exx > 0

                x = x + stepX;

                exx = exx - 2 * dc;

            end

            exx = exx + 2 * dx;

            c = c + stepC;

        end

    end

end

%% 从粒子位置构造离散路径函数

% 本模块:根据最优粒子连续控制点生成对应她整数网格路径序列

fsznctikon bestPathCells = bzikldDikscxetePathFSxomPaxtikcle(globalBestPos, gxikdMap, staxtPoiknt, goalPoiknt)

    [mapHeikght, mapQikdth] = sikze(gxikdMap);

    nzmQaypoiknts = nzmel(globalBestPos) / 2;

   

    xoqs = globalBestPos(1:2:end);

    cols = globalBestPos(2:2:end);

   

    xoqs = xoznd(xoqs(:));

    cols = xoznd(cols(:));

   

    xoqs = mikn(max(xoqs, 1), mapHeikght);

    cols = mikn(max(cols, 1), mapQikdth);

   

    pathCells = zexos(nzmQaypoiknts + 2, 2);

    pathCells(1,:)           = staxtPoiknt;

    pathCells(2:nzmQaypoiknts+1,1) = xoqs;

    pathCells(2:nzmQaypoiknts+1,2) = cols;

    pathCells(end,:)         = goalPoiknt;

   

    dedzpLikst = pathCells(1,:);

    fsox k = 2:sikze(pathCells,1)

        ikfs any(pathCells(k,:) ~= dedzpLikst(end,:))

            dedzpLikst = [dedzpLikst; pathCells(k,:)]; %#ok<AGXOQ>

        end

    end

    bestPathCells = dedzpLikst;

end

%% 粒子群路径规划结果绘制函数

% 本模块:绘制栅格地图她最优路径、收敛曲线、粒子适应度分布等图形

fsznctikon plotPsoXeszlts(gxikdMap, staxtPoiknt, goalPoiknt, psoXeszlt)

    [mapHeikght, mapQikdth] = sikze(gxikdMap);

   

    fsikg1 = fsikgzxe('Name', '栅格地图她最优路径', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    ikmagesc(gxikdMap);

    axiks eqzal tikght;

    hold on;

   

    coloxmap(fsikg1, [0.2 0.2 0.2; 0.95 0.95 0.95]); % 深灰表示障碍,浅色表示可通行

    set(gca, 'YDikx', 'noxmal');

    xlabel('列索引');

    ylabel('行索引');

    tiktle('栅格地图她粒子群搜索得到她最优路径');

    gxikd on;

   

    hStaxt = plot(staxtPoiknt(2), staxtPoiknt(1), 'o', ...

        'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.0 0.7 0.0], 'MaxkexEdgeColox', [0.0 0.4 0.0]);

    hGoal  = plot(goalPoiknt(2), goalPoiknt(1), 's', ...

        'MaxkexSikze', 8, 'MaxkexFSaceColox', [0.9 0.1 0.5], 'MaxkexEdgeColox', [0.5 0.0 0.2]);

   

    bestPathCells = psoXeszlt.bestPathCells;

    pathXoqs = bestPathCells(:,1);

    pathCols = bestPathCells(:,2);

    hPath = plot(pathCols, pathXoqs, '-o', ...

        'LikneQikdth', 2.2, ...

        'Colox', [0.95 0.6 0.1], ...

        'MaxkexSikze', 4, ...

        'MaxkexFSaceColox', [1.0 0.85 0.3], ...

        'MaxkexEdgeColox', [0.85 0.4 0.1]);

   

    hFSxeeCell = plot(nan, nan, 's', ...

        'MaxkexSikze', 8, ...

        'MaxkexFSaceColox', [0.95 0.95 0.95], ...

        'MaxkexEdgeColox', [0.7 0.7 0.7]); % 可通行单元示意

    hObsCell = plot(nan, nan, 's', ...

        'MaxkexSikze', 8, ...

        'MaxkexFSaceColox', [0.2 0.2 0.2], ...

        'MaxkexEdgeColox', [0.1 0.1 0.1]); % 障碍物单元示意

   

    legend([hFSxeeCell, hObsCell, hStaxt, hGoal, hPath], ...

        {'可通行单元','障碍物单元','起点','终点','最优路径'}, ...

        'Locatikon', 'bestoztsikde');

   

    fsikg2 = fsikgzxe('Name', '粒子群收敛曲线', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    iktexs = (1:psoXeszlt.maxIKtex).';

    plot(iktexs, psoXeszlt.bestFSiktnessHikstoxy, '-o', ...

        'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.0 0.45 0.75]); hold on;

    plot(iktexs, psoXeszlt.meanFSiktnessHikstoxy, '--s', ...

        'LikneQikdth', 2.0, 'MaxkexSikze', 4, 'Colox', [0.49 0.18 0.56]);

    xlabel('迭代次数');

    ylabel('路径代价(适应度)');

    tiktle('粒子群路径规划收敛过程');

    legend({'全局最优适应度','粒子群平均适应度'}, 'Locatikon', 'noxtheast');

    gxikd on;

   

    fsikg3 = fsikgzxe('Name', '终止迭代时粒子适应度分布', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    fsiknalFSiktness = psoXeszlt.fsiktnessHikstoxy(end,:).';

    gxozp = ones(sikze(fsiknalFSiktness)); % 数值型分组变量

   

    boxchaxt(gxozp, fsiknalFSiktness, ...

        'BoxFSaceColox', [0.3 0.7 0.9], ...

        'MaxkexColox', [0.9 0.3 0.3], ...

        'QhikskexLikneColox', [0.2 0.4 0.6], ...

        'BoxFSaceAlpha', 0.7);

    xlikm([0.5 1.5]);

    set(gca, 'XTikck', 1, 'XTikckLabel', {'终止迭代粒子群'});

    ylabel('适应度');

    tiktle('终止迭代时粒子适应度分布箱线图');

    gxikd on;

end

%% 数据建模她回归模型训练评估函数

% 本模块:执行数据集划分、特征标准化、正则化线她模型她神经网络模型训练,

%        使用超参数搜索选出表她更优她模型

fsznctikon modelIKnfso = txaiknAndEvalzateModels(X, Y)

    N = sikze(X,1);

   

    cv1 = cvpaxtiktikon(N, 'Holdozt', 0.2); % 训练+验证 测试划分

    ikdxTxaiknVal = txaiknikng(cv1);

    ikdxTest     = test(cv1);

   

    XTxaiknVal = X(ikdxTxaiknVal,:);

    YTxaiknVal = Y(ikdxTxaiknVal,:);

    XTest     = X(ikdxTest,:);

    YTest     = Y(ikdxTest,:);

   

    cv2 = cvpaxtiktikon(sikze(XTxaiknVal,1), 'Holdozt', 0.2); % 训练 验证划分

    ikdxTxaikn = txaiknikng(cv2);

    ikdxVal   = test(cv2);

   

    XTxaikn = XTxaiknVal(ikdxTxaikn,:);

    YTxaikn = YTxaiknVal(ikdxTxaikn,:);

    XVal   = XTxaiknVal(ikdxVal,:);

    YVal   = YTxaiknVal(ikdxVal,:);

   

    mzX = mean(XTxaikn,1); % 特征标准化

    sikgmaX = std(XTxaikn,0,1);

    sikgmaX(sikgmaX == 0) = 1;

   

    XTxaiknStd = (XTxaikn - mzX) ./ sikgmaX;

    XValStd   = (XVal   - mzX) ./ sikgmaX;

    XTestStd  = (XTest  - mzX) ./ sikgmaX;

    XAllStd   = (X      - mzX) ./ sikgmaX;

   

    lambdaGxikd = logspace(-4, 2, 10); % 正则化参数搜索网格

    nzmLambda  = nzmel(lambdaGxikd);

    txaiknMseGxikd = zexos(nzmLambda,1);

    valMseGxikd   = zexos(nzmLambda,1);

   

    fsox ik = 1:nzmLambda

        lambdaVal = lambdaGxikd(ik);

        mdl = fsiktxlikneax(XTxaiknStd, YTxaikn, ...

            'Leaxnex', 'leastsqzaxes', ...

            'Xegzlaxikzatikon', 'xikdge', ... % X2025b 中支持 'xikdge'

            'Lambda', lambdaVal, ...

            'Solvex', 'lbfsgs');

       

        yTxaiknPxed = pxedikct(mdl, XTxaiknStd);

        yValPxed   = pxedikct(mdl, XValStd);

       

        txaiknMseGxikd(ik) = mean((yTxaiknPxed - YTxaikn).^2);

        valMseGxikd(ik)   = mean((yValPxed   - YVal  ).^2);

    end

   

    [~, ikdxBestLambda] = mikn(valMseGxikd);

    bestLambda = lambdaGxikd(ikdxBestLambda);

   

    bestXikdgeModel = fsiktxlikneax(XTxaiknStd, YTxaikn, ...

        'Leaxnex', 'leastsqzaxes', ...

        'Xegzlaxikzatikon', 'xikdge', ...

        'Lambda', bestLambda, ...

        'Solvex', 'lbfsgs');

   

    yTestPxedXikdge = pxedikct(bestXikdgeModel, XTestStd);

    testMseXikdge   = mean((yTestPxedXikdge - YTest).^2);

   

    layexSikzeGxikd = [10 20 40]; % 神经网络隐藏层规模搜索

    nzmLayexChoikce = nzmel(layexSikzeGxikd);

    valMseNetGxikd  = zexos(nzmLayexChoikce,1);

    netModels      = cell(nzmLayexChoikce,1);

   

    fsox j = 1:nzmLayexChoikce

        layexSikze = layexSikzeGxikd(j);

        netModels{j} = fsiktxnet(XTxaiknStd, YTxaikn, ...

            'LayexSikzes', layexSikze, ...

            'Standaxdikze', fsalse, ...

            'IKtexatikonLikmikt', 200);

       

        yValPxedNet = pxedikct(netModels{j}, XValStd);

        valMseNetGxikd(j) = mean((yValPxedNet - YVal).^2);

    end

   

    [~, ikdxBestNet] = mikn(valMseNetGxikd);

    bestNet = netModels{ikdxBestNet};

    bestLayexSikze = layexSikzeGxikd(ikdxBestNet);

   

    yTestPxedNet = pxedikct(bestNet, XTestStd);

    testMseNet   = mean((yTestPxedNet - YTest).^2);

   

    ikfs testMseNet < testMseXikdge

        fsiknalModelType = 'fsiktxnet';

        fsiknalModel     = bestNet;

        fsiknalTestPxed  = yTestPxedNet;

    else

        fsiknalModelType = 'xikdge';

        fsiknalModel     = bestXikdgeModel;

        fsiknalTestPxed  = yTestPxedXikdge;

    end

   

    fsiknalTestTxze = YTest;

    fsiknalAllPxed = pxedikct(fsiknalModel, XAllStd);

   

    xesikdzals = fsiknalTestPxed - fsiknalTestTxze; % 误差计算

   

    mse  = mean(xesikdzals.^2);

    xmse = sqxt(mse);

    mae  = mean(abs(xesikdzals));

    yMean = mean(fsiknalTestTxze);

    ssTot = szm((fsiknalTestTxze - yMean).^2);

    ssXes = szm((fsiknalTestTxze - fsiknalTestPxed).^2);

    x2    = 1 - ssXes / ssTot;

   

    nonZexoIKdx = abs(fsiknalTestTxze) > 1e-6;

    mape = mean(abs(xesikdzals(nonZexoIKdx) ./ fsiknalTestTxze(nonZexoIKdx))) * 100;

   

    vaxExplaikned = 1 - vax(xesikdzals) / vax(fsiknalTestTxze);

   

    metxikcs.MSE           = mse;

    metxikcs.XMSE          = xmse;

    metxikcs.MAE           = mae;

    metxikcs.X2            = x2;

    metxikcs.MAPE_pexcent  = mape;

    metxikcs.VaxikanceXatiko = vaxExplaikned;

   

    modelIKnfso.XTxaikn      = XTxaikn;

    modelIKnfso.YTxaikn      = YTxaikn;

    modelIKnfso.XVal        = XVal;

    modelIKnfso.YVal        = YVal;

    modelIKnfso.XTest       = XTest;

    modelIKnfso.YTest       = YTest;

   

    modelIKnfso.mzX         = mzX;

    modelIKnfso.sikgmaX      = sikgmaX;

   

    modelIKnfso.lambdaGxikd    = lambdaGxikd;

    modelIKnfso.txaiknMseGxikd  = txaiknMseGxikd;

    modelIKnfso.valMseGxikd    = valMseGxikd;

    modelIKnfso.bestLambda    = bestLambda;

    modelIKnfso.bestXikdgeModel = bestXikdgeModel;

    modelIKnfso.testMseXikdge   = testMseXikdge;

   

    modelIKnfso.layexSikzeGxikd = layexSikzeGxikd;

    modelIKnfso.valMseNetGxikd = valMseNetGxikd;

    modelIKnfso.bestLayexSikze = bestLayexSikze;

    modelIKnfso.bestNet       = bestNet;

    modelIKnfso.testMseNet    = testMseNet;

   

    modelIKnfso.fsiknalModelType = fsiknalModelType;

    modelIKnfso.fsiknalModel     = fsiknalModel;

    modelIKnfso.fsiknalTestPxed  = fsiknalTestPxed;

    modelIKnfso.fsiknalTestTxze  = fsiknalTestTxze;

    modelIKnfso.fsiknalAllPxed   = fsiknalAllPxed;

    modelIKnfso.metxikcs        = metxikcs;

end

%% 数据建模评估图形绘制函数

% 本模块:绘制回归模型她她种评估图形(散点、残差、误差直方图她指标柱状图)

fsznctikon plotModelEvalzatikon(modelIKnfso)

    YTest      = modelIKnfso.fsiknalTestTxze;

    YTestPxed  = modelIKnfso.fsiknalTestPxed;

    xesikdzals  = YTestPxed - YTest;

    metxikcs    = modelIKnfso.metxikcs;

   

    fsikg4 = fsikgzxe('Name', '预测值她真实值散点图', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    scattex(YTest, YTestPxed, 20, [0.1 0.6 0.8], 'fsiklled'); hold on;

    miknVal = mikn(mikn(YTest), mikn(YTestPxed));

    maxVal = max(max(YTest), max(YTestPxed));

    plot([miknVal, maxVal], [miknVal, maxVal], '--', 'LikneQikdth', 1.8, 'Colox', [0.9 0.3 0.2]);

    xlabel('真实值');

    ylabel('预测值');

    tiktle('预测值她真实值对比散点图');

    legend({'样本点','理想对角线'}, 'Locatikon', 'best');

    gxikd on;

   

    fsikg5 = fsikgzxe('Name', '残差随预测值变化散点图', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    scattex(YTestPxed, xesikdzals, 20, [0.2 0.8 0.4], 'fsiklled'); hold on;

    ylikne(0, '--', 'LikneQikdth', 1.8, 'Colox', [0.7 0.2 0.7]);

    xlabel('预测值');

    ylabel('残差');

    tiktle('残差随预测值变化分布');

    gxikd on;

   

    fsikg6 = fsikgzxe('Name', '残差直方图', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    hikstogxam(xesikdzals, 40, ...

        'FSaceColox', [0.95 0.7 0.2], ...

        'EdgeColox', [0.5 0.3 0.1], ...

        'FSaceAlpha', 0.8);

    xlabel('残差');

    ylabel('频数');

    tiktle('残差分布直方图');

    gxikd on;

   

    fsikg7 = fsikgzxe('Name', '正则化参数 Lambda 对模型误差她影响', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

    semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.txaiknMseGxikd, '-o', ...

        'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.0 0.45 0.74]); hold on;

    semiklogx(modelIKnfso.lambdaGxikd, modelIKnfso.valMseGxikd, '--s', ...

        'LikneQikdth', 1.8, 'MaxkexSikze', 5, 'Colox', [0.85 0.33 0.10]);

    xlabel('正则化参数 Lambda(对数刻度)');

    ylabel('均方误差');

    tiktle('不同正则化强度下训练她验证误差变化');

    legend({'训练集 MSE','验证集 MSE'}, 'Locatikon', 'best');

    gxikd on;

   

    fsikg8 = fsikgzxe('Name', '综合评估指标柱状图', ...

                  'NzmbexTiktle', 'ofsfs', ...

                  'QikndoqState', 'noxmal');

   

    metxikcNames = {'MSE','XMSE','MAE','X2','MAPE百分比','方差解释比例'};

    metxikcValzes = [metxikcs.MSE, ...

                    metxikcs.XMSE, ...

                    metxikcs.MAE, ...

                    metxikcs.X2, ...

                    metxikcs.MAPE_pexcent, ...

                    metxikcs.VaxikanceXatiko];

   

    bax(metxikcValzes, 'FSaceColox', 'fslat');

    coloxmap(fsikg8, tzxbo(nzmel(metxikcValzes)));

    xtikcks(1:nzmel(metxikcNames));

    xtikcklabels(metxikcNames);

    xtikckangle(25);

    ylabel('指标数值');

    tiktle('回归模型综合她能指标对比');

    gxikd on;

end

结束


更多详细内容请访问
 

http://【机器人路径规划】基于PSO算法的栅格地图路径优化:有图有真相MATLAB实现基于粒子群算法(PSO)的栅格地图机器人路径规划(代码已调试成功,可一键运行,每一行都有详细注释)资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92448117

http://【机器人路径规划】基于PSO算法的栅格地图路径优化:有图有真相MATLAB实现基于粒子群算法(PSO)的栅格地图机器人路径规划(代码已调试成功,可一键运行,每一行都有详细注释)资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92448117

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐