如何按距离分割最短路径?MATLAB现有实现优化需求
嘿,我来给你分享几个更简洁的MATLAB实现思路,能替代你当前用cumsum+accumarray的繁琐方案,让代码可读性更强、逻辑更直观:
核心需求回顾
我们需要把固定起点A的有序路径,按照**累计距离超过阈值th**的规则分割成多条子路径,已知两两距离、总距离和路径点的有序索引。
方案1:用discretize+splitapply简化分组(最推荐)
discretize可以直接根据累计距离的区间完成分组,比手动计算subs的逻辑清晰太多,搭配splitapply生成子路径的代码也更简洁:
Dmax = max(totdistance); th = Dmax/4; % 设定分割阈值 cum_dist = cumsum(distances); % 先计算全程的累计距离 % 用discretize把每个点的累计距离映射到对应分组,区间为[0, th], (th, 2th], ... groups = discretize(cum_dist, 0:th:inf); % 确保起点(第一个点)被分到第一组(避免极端情况:第一个距离就超过th时的分组偏差) groups(1) = 1; % 按组提取距离并计算子路径的累计距离,直接生成cell数组 newPaths = splitapply(@(idx) {cumsum(distances(idx))}, 1:numel(distances), groups);
这个方案的优势是代码行数少、逻辑一目了然,完全省去了原方案中nSplit和subs的手动计算,出错概率更低。而且同样支持替换为总成本/两两成本分割,只需要把distances换成对应的成本数组即可。
方案2:循环+逻辑索引(适合小数据量,最易读)
如果你的路径点数量不多,循环写法反而更直观,后续维护或调试起来也更方便:
Dmax = max(totdistance); th = Dmax/4; % 设定分割阈值 cum_dist = cumsum(distances); newPaths = {}; % 按阈值区间遍历每个子路径 for group_idx = 1:ceil(cum_dist(end)/th) % 找到当前组内的所有路径点索引 lower_bound = (group_idx-1)*th; upper_bound = group_idx*th; % 第一组要强制包含起点 if group_idx == 1 idx = [true, cum_dist(2:end) <= upper_bound]; else idx = cum_dist > lower_bound & cum_dist <= upper_bound; end % 计算当前子路径的累计距离并存入cell数组 newPaths{group_idx} = cumsum(distances(idx)); end
这种写法的每一步逻辑都非常直白,哪怕是刚接触MATLAB的人也能看懂,适合团队协作或者需要频繁调整分割规则的场景。
方案3:用find定位分割点(精准控制分割位置)
如果需要更精准地控制分割点的位置,可以先找到所有累计距离超过阈值的位置,再给每个点分配组号:
Dmax = max(totdistance); th = Dmax/4; % 设定分割阈值 cum_dist = cumsum(distances); % 找到所有需要分割的位置:累计距离首次超过k*th的点索引 split_pos = find(cum_dist > th:th:cum_dist(end)); % 初始化组号数组 groups = ones(size(distances)); current_group = 1; split_idx = 1; % 遍历每个点,分配对应的组号 for i = 1:numel(distances) if split_idx <= numel(split_pos) && i == split_pos(split_idx) current_group = current_group + 1; split_idx = split_idx + 1; end groups(i) = current_group; end % 生成子路径累计距离 newPaths = splitapply(@(d) {cumsum(d)}, distances, groups);
这个方案适合需要自定义分割规则的场景,比如你想调整分割点的偏移量,只需要修改split_pos的计算逻辑即可。
对比你原来的方案,这几个实现都更注重可读性和可维护性,其中discretize+splitapply的组合是最简洁高效的,完全可以替代原有的cumsum+accumarray写法。
内容的提问来源于stack exchange,提问作者user158013
相关产品推荐
相关产品推荐

