1. 萤火虫算法
本期给大家介绍一种比较新颖的群体智能搜索算法——萤火虫算法,萤火虫算法(Firefly Algorithm, FA)是一种基于仿生学的群体智能搜索算法,是模拟萤火虫种群之间的发光特性和特殊的信息传递方式而设计出的一种有效的启发式算法。
简单来说,每一只萤火虫作为独立的个体有着两个基本属性,即发光强度和所处位置。萤火虫个体所处的位置越好,发光强度越高。萤火虫个体与个体之间存在相互吸引的作用力,亮度越高的萤火虫个体对其他位置的低亮度个体吸引力越大,从而能吸引范围内的低亮度萤火虫向着高亮度萤火虫移动。
-
TSP问题
了解了萤火虫算法的工作原理,我们简单回顾一下TSP问题,又叫旅行商问题。旅行推销员问题(英语:Travelling salesman problem, TSP)是这样一个问题:给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。它是组合优化中的一个NP难问题,在运筹学中非常重要。 -
算法流程
用萤火虫算法求解TSP问题的基本原理就比较清晰了,我们还是采用TSP常用的序列编码。萤火虫的两个属性,其中位置属性对应序列的编码,萤火虫的亮度则对应该编码解的好坏。萤火虫的亮度越高,代表解的质量越高,亮度越低,代表解的质量越低。而萤火虫个体之间的相对位置则用编码之间的相对距离进行表示。通过不断迭代,亮度低的萤火虫不断向亮度高的萤火虫移动,即效果差的解不断向效果好的解进行移动,而最亮的个体则进行随机移动,从而达到搜索邻域空间内的解的效果,直到找到种群中最好的个体或达到算法终止条件。
萤火虫算法的实现过程和步骤描述如下:
Step1:系统初始化,生成初始种群,设置参数等;
Step2:计算每个初始萤火虫的亮度;
Step3:根据移动公式更新萤火虫的位置;
Step4:最亮的萤火虫随机移动;
Step5:计算位置更新后的每个萤火虫的亮度;
Step6:如果满足终止条件,则结束循环,返回最优个体解,否则转Step3;
4.代码部分
代码采用java编写,实现以每个firefly为类,代码的思路就比较清晰了,此处只给出了核心部分的代码(firefly类)
package algorithm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.math.*;
public class Firefly {
public ArrayList<Integer> path;
public double light;
public int M;
public Firefly()
{
this.path = new ArrayList<Integer>();
this.M = Integer.MAX_VALUE;
}
public void setlight(double l)
{
this.light = l;
}
public double getlight()
{
return this.light;
}
public void addspot(int i)
{
this.path.add(i);
}
public ArrayList<Integer> getpath()
{
return this.path;
}
public void removespot(int i)
{
this.path.remove(i);
}
public void insert(int index, int i)
{
this.path.add(index, i);
}
public void Calculight(Params inst)
{
//计算light;
double l = 0.0;
for(int j = 0; j <this.path.size() - 1; j ++)
{
l += inst.dist[this.path.get(j)][this.path.get(j+1)];
}
this.setlight(1000/ l);
}
public void moveto(Firefly f, Params p) // f is a better one;
{
Random r = new Random();
for(int i = 0; i <this.path.size(); i ++)
{
int flg;
double dis = f.path.get(i) - this.path.get(i);
double aff = p.beta * Math.exp( - p.gama * ( dis * dis));
double the = r.nextDouble();
double nex = this.path.get(i) + aff * dis + p.alph * the;
if(nex > p.spotnum)
{
flg = p.spotnum;
}
else
{
flg = (int)Math.ceil(nex);
}
this.path.set(i, flg);
}
//adjust
ArrayList<Integer> temp= new ArrayList<Integer>();
for(int j = 0; j <this.path.size(); j ++)
{
int aa = Collections.min(this.path);
int bb = this.path.indexOf(aa);
temp.add(bb);
this.path.set(bb, M);
}
for(int j = 0; j < temp.size(); j ++)
{
this.path.set(temp.get(j), j);
}
}
public void randmove(Params p)
{
Random r = new Random();
for(int i = 0; i < this.path.size(); i ++)
{
int flg;
double the = r.nextDouble() * 2 - 1;
double nex = this.path.get(i) + p.alph * the;
if(nex > p.spotnum)
{
flg = p.spotnum;
}
else
{
flg = (int)Math.ceil(nex);
}
this.path.set(i, flg);
}
ArrayList<Integer> temp= new ArrayList<Integer>();
for(int j = 0; j <this.path.size(); j ++)
{
int aa = Collections.min(this.path);
int bb = this.path.indexOf(aa);
temp.add(bb);
this.path.set(bb, M);
}
for(int j = 0; j < temp.size(); j ++)
{
this.path.set(temp.get(j), j);
}
}
完整代码获取:
https://mp.weixin.qq.com/s?__biz=MzUzNDAzMTU0NA==&mid=2247484047&idx=1&sn=c898a5db967a6a4d99e98edb288d4350&chksm=fa9bbf58cdec364e7991c19e55eb856e02c80218816e3891dc922493415e8fbd1f8116405480#rd