您的位置:首页 > 其它

基于 PSO 算法解决 TSP 项目

2018-01-27 02:36 204 查看
PSO (Particle Swarm Optimization) 算法即粒子群优化算法,源于对鸟群捕食行为的学习。基本思想是:个体获取的局部信息提供给群体,群体根据所有局部信息获得一个动态的全局最优解,每个个体再根据这个全局最优解调整自身的局部最优解,这个过程进行迭代,直到达到终止条件。

TSP (Traveling Salesman Problem) 即旅行商问题,简单来说就是:给定 n 个城市的位置,求一条访问各个城市一次的最短路径,TSP 也是一个组合优化问题。
PSO 算法基础公式



这里,Vj 代表每个粒子的速度;w 是惯性权重系数,有利于算法的收敛;c1 和 c2 分别为局部加速权重系数和全局加速权重系数,决定了下一代的局部速度取决于局部最优解多一些,还是全局最优解多一些;r1 和 r2 是两个 0~1 中间的随机数,也是为了算法收敛。

下面是我在 report 里做的 PSO 算法运行流程图:


PSO
算法流程图

但很明显,PSO 算法更适合用来解决连续优化问题,而旅行商问题是一个组合优化问题。经过大量的论文学习和讨论后,使用了一种改进的 PSO 算法,引入了交换子和交换序的概念。

假设在一个旅行商问题中,有 n 个城市节点,那么这个问题的解序列可记为 S = (ai), i = 1, 2, …, n. 那么 SO(i1, i2) 就是一个交换子,i1 和 i2 表示城市节点 a1 和 a2. 若对解序列进行 S’ = S + SO(i1, i2) 的运算,就是将解序列 S 中 a1 和 a2 的位置进行调换。多个交换子的序列 SS = (SO1, SO2, …, SOn) 就是一个交换序,其中交换子的顺序是有意义的,不同的顺序可能产生不同的解序列。

放在这个具体路线规划问题中,就是先将所有城市节点随机排列,得到一个解序列,然后对城市节点进行逐个调换,将调换前后的路径长度进行对比,如果变好则更新全局最优解,否则继续寻找更佳的交换子和交换序,在这一过程中,w 系数就起到了收敛的作用,它会使我们进行调换的局部解序列越来越短。
核心程序

private void particle(int i) {
ArrayList<SO> Vi;
int len;
int j;
float ra;
float rb;
ArrayList<SO> Vii = new ArrayList<SO>();

// refresh velocity
// Vii=wVi+ra(Pid-Xid)+rb(Pgd-Xid)
Vi = listV.get(i);

// wVi+表示获取Vi中size*w取整个交换序列
len = (int) (Vi.size() * w);

for (j = 0; j < len; j++) {
Vii.add(Vi.get(j));
}

// Pid-Xid
ArrayList<SO> a = minus(Pd[i], oPopulation[i]);
ra = random.nextFloat();

// ra(Pid-Xid)
len = (int) (a.size() * ra);

for (j = 0; j < len; j++) {
Vii.add(a.get(j));
}

// Pgd-Xid
ArrayList<SO> b = minus(Pgd, oPopulation[i]);
rb = random.nextFloat();

// rb(Pgd-Xid)
len = (int) (b.size() * rb);

for (j = 0; j < len; j++) {
SO tt = b.get(j);
Vii.add(tt);
}

// save new Vii
listV.set(i, Vii);

// refresh position
// Xid’=Xid+Vid
add(oPopulation[i], Vii);
}


改变 swarm 的数目和迭代次数,得到的路径长度如下:



随着两个参数的无限增长,得到的最佳路径也会越来越短,但同时所耗的内存和时间也会有所增加。

最佳路径大概长这样:



P.S. 在 IntelliJ 里面做界面真的太方便了。

代码已上传到 github,点击传送门
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息