粒子群算法实战:用Matlab解决旅行商问题(TSP)的完整代码解析
你是否曾面对一张布满城市节点的地图,思考如何规划一条最短的路径,让旅行商能够访问所有城市并最终回到起点?这就是经典的旅行商问题。它不仅是算法竞赛的常客,更是物流配送、电路板钻孔、基因测序等众多工业场景的核心优化难题。当城市数量超过20个时,精确求解的计算量就会变得极其庞大,这时,我们便需要借助智能优化算法的力量。
在众多启发式算法中,粒子群算法以其概念直观、参数较少、易于实现的特点脱颖而出。它模拟鸟群觅食的社会行为,通过个体与群体信息的交互,在复杂的解空间中高效搜寻优质解。今天,我们不谈空洞的理论,而是直接切入实战,手把手带你用Matlab构建一个完整的粒子群算法求解器,攻克TSP问题。无论你是希望将算法应用于课程设计的学生,还是寻求优化方案解决实际路径规划的工程师,这篇文章都将为你提供从原理到代码、从调参到避坑的完整指南。
1. 理解核心:粒子群算法如何适配旅行商问题
在将算法应用于具体问题前,我们必须先建立一个清晰的认知:标准粒子群算法处理的是连续空间优化问题,而TSP的解是离散的(城市的访问顺序)。这中间的鸿沟,需要我们通过巧妙的编码和解码策略来跨越。
粒子位置的编码艺术 在连续优化中,一个粒子的位置可能是一个三维坐标 [x, y, z]。在TSP中,一个粒子的位置代表一条完整的访问路径。最常用的编码方式是基于序号的排列编码。假设有5个城市,编号为1到5。一个合法的粒子位置(即一条路径)可以是 [3, 1, 4, 2, 5],这表示旅行商从城市3出发,依次访问城市1、4、2、5,最后需要回到城市3形成闭环。
注意:这种编码方式下,“位置”本身是一个排列,其“差值”和“速度”在离散空间中没有直接的物理意义。因此,我们需要重新定义粒子群算法中的速度更新和位置更新操作。
重新定义“速度”与“位置更新” 传统粒子群公式 v = w*v + c1*r1*(pbest - x) + c2*r2*(gbest - x) 和 x = x + v 在这里不再适用。我们需要将“速度”理解为引导当前路径向个体历史最优路径和群体历史最优路径靠拢的一系列交换操作。
一种有效的策略是,将速度 v 定义为一个交换序列(Swap Sequence)。例如,从当前路径 x 变换到目标路径 pbest,可以通过执行一系列两两城市位置的交换来实现。这个交换序列就是“社会认知”或“自我认知”部分的一种体现。最终的速度更新,是惯性部分、自我认知部分和社会认知部分所对应的交换序列的合并。
适应度函数:路径的总距离 这是驱动整个算法进化的引擎。适应度函数计算给定路径顺序下,旅行商需要行走的总距离。距离越短,适应度越高(在求最小值问题中,我们通常将适应度取为距离的倒数,或直接对距离取负值)。计算总距离需要城市间的距离矩阵 D,其中 D(i, j) 表示城市i到城市j的距离。
% 假设城市坐标存储在 cities(n, 2) 矩阵中,路径存储在 path(1:n) 中
function total_dist = CalculateDistance(cities, path)
n = length(path);
total_dist = 0;
for i = 1:n-1
city_from = path(i);
city_to = path(i+1);
total_dist = total_dist + norm(cities(city_from, :) - cities(city_to, :));
end
% 加上从最后一个城市回到起点的距离
total_dist = total_dist + norm(cities(path(end), :) - cities(path(1), :));
end
理解了这些核心概念,我们就为后续的代码实现打下了坚实的基础。接下来,我们将进入具体的算法实现环节。
2. 构建求解器:Matlab代码逐行拆解
我们将构建一个模块化的粒子群算法求解TSP的程序。整个程序结构清晰,分为参数初始化、种群初始化、迭代循环和结果展示四个主要部分。
2.1 算法参数与问题初始化 首先,我们需要定义算法运行所需的各项参数,并准备好TSP问题的数据(这里我们使用随机生成的城市坐标作为示例)。
%% 1. 问题定义与参数设置
clear; clc;
% TSP问题参数
num_cities = 30; % 城市数量
% 随机生成城市坐标(范围0~100)
cities = 100 * rand(num_cities, 2);
% 计算距离矩阵(对称矩阵)
dist_matrix = zeros(num_cities);
for i = 1:num_cities
for j = i+1:num_cities
dist = norm(cities(i,:) - cities(j,:));
dist_matrix(i, j) = dist;
dist_matrix(j, i)

的完整代码解析&spm=1001.2101.3001.5002&articleId=152995139&d=1&t=3&u=68dfec31ab0045dcb0509b52136832aa)
2万+

被折叠的 条评论
为什么被折叠?



