蚁群算法
的第一个算法就是蚂蚁系统,而蚂蚁系统有三种基本模型分别是
有7个城市(城市编号0到6,每两个城市之间的距离设置为两编号之和)的测试结果图:
蚁周模型、蚁密模型、蚁量模型。三种模型的实现大致相同,主要区别是在信息素
的更新方式上。在用蚂蚁系统解决T SP问题时,蚁量模型和蚁密模型是蚂蚁在构建
一条合法路径的过程中进行信息素的更新的,当蚂蚁走过一条边之后,就对该边进
行信息素的更新,即为局部更新方式。而蚁周模型是在所有蚂蚁都构建了一条合
法路径之后才对各边进行信息素更新的,也即全局更新方式。
并且这三种模型中蚂蚁在自己所走过的路线上释放的信息素的量也是有所
不同的,在蚁密模型蚂蚁在自己所走过的路上释放的信息素是一个常量Q,而在蚁
量模型中蚂蚁在走过某条边上释放的信息素量等于Q/(该条边的长度);在蚁周
模型中蚂蚁是在完整的走过一条路线后再跟新的信息素,所以其蚂蚁在走过的每
条边上释放的信息素是相等的,都等于Q/(该条完整路线的总长度);
其中蚁周模型的性能是做好的,所以用其来解决TSP问题也很方便,在
用蚁周模型解决问题时该注意的绩点核心就是:
一、为每条路设置信息素的初始量。
二、合理的设置好蚁群算法中的各种影响参数(这个直接影响最后效果)。
三、利用轮盘选赌法为每只蚂蚁选择不重复的下一天边。
四、在一轮结束后计算每天边上的信息素增量。
五、更新全局的信息素
最后附上用蚁周模型解决TSP问题的简单实现版本代码及结果。
#include<iostream>
using namespace std;
int main()
{
const int N = 10;//城市的个数
const int M = 10;//每一轮中蚂蚁的个数
const int RcMax = 2000;//迭代次数
const int IN = 1;//信息素的初始量
double graph[N][N];//城市图
double add[N][N];//每一段的信息素增量数组
int map[M][N];//每一只蚂蚁的所走的路线记录
int vis[M][N];//记录每一只访问过的城市,0表示未访问,1表示以访问
double expectVa[N][N];//每一段路径的期望值 = 1.0/距离
double phe[N][N];//每一段路径上的信息素
double MAX = 0x7fffffff;
double alphe,betra,rout,Q;//alphe信息素的影响因子,betra路线距离的影响因子,rout信息素的保持度,Q用于计算每只蚂蚁在其路迹留下的信息素增量
double bestSolution = MAX;//最短距离
int bestWay[N];//最优路线
//初始化变量参数和信息数组
alphe = betra = 2;
rout = 0.7;
Q = 10;
//初始化城市图 TODO
for(int i = 0;i<N;i++ )
{
graph[i][i] = MAX;
}
for(int i = 0;i<N-1;i++ )
{
for(int j = i+1;j<N;j++ )
{
graph[i][j] = i+j;
graph[j][i] = i+j;
}
}
//初始化路线记录数组
for(int i = 0;i<M;i++ )
{
for(int j = 0;j<N;j++)
{
map[i][j] = -1;
vis[i][j] = 0;
}
}
//初始化期望值数组
for(int i = 0;i<N;i++ )
{
for(int j = 0;j<N;j++)
{
expectVa[i][j] = 1.0/graph[i][j];
}
}
//初始化信息素数组
for(int i = 0;i<N;i++ )
{
for(int j = 0;j<N;j++)
{
phe[i][j] = IN;
}
}
//迭代
for(int y = 0; y<RcMax;y++)
{
for(int i = 0;i<M;i++)//为每只蚂蚁分配起点
{
map[i][0] = (y+i)%N;
vis[i][ map[i][0]] = 1;
}
//完成该轮中每一只蚂蚁的路线选择
int s = 1;
while(s<N)
{
for(int i = 0;i<M;i++)
{
double psum = 0;
for(int j = 0;j<N;j++)
{
if(vis[i][j]==0)
{
psum += pow(phe[map[i][s-1]][j],alphe) * pow(expectVa[map[i][s-1]][j],betra);
}
}
double drand = (double)(rand())/(RAND_MAX+1);
double pro = 0;
int j;
for(j = 0;j<N;j++)
{
if(vis[i][j]==0)
{
pro += (pow(phe[map[i][s-1]][j],alphe) * pow(expectVa[map[i][s-1]][j],betra))/psum;
if(pro>=drand)
{
break;
}
}
}
vis[i][j] = 1;
map[i][s] = j;
}
s++;
}
//保存最优路线
double solution = 0;
for(int i = 0;i<M;i++)
{
solution = 0;
for(int a =0;a<N-1;a++)
{
solution+= graph[map[i][a]][map[i][a+1]];
}
if(solution<bestSolution)
{
for(int j = 0;j<N;j++)
{
bestWay[j] = map[i][j];
}
bestSolution = solution;
}
}
//计算每一只蚂蚁在其每一段路径上留下的信息素增量
//初始化信息素增量数组
for(int i = 0;i<N;i++)
{
for(int j = 0;j<N;j++)
{
add[i][j] = 0;
}
}
for(int i = 0;i<M;i++)
{
//先算出每只蚂蚁的路线的总距离solu
double solu = 0;
for(int a =0;a<N-1;a++)
{
solu += graph[map[i][a]][map[i][a+1]];
}
int j;
double d = Q/solu;
for( j = 0 ;j<N-1;j++)
{
add[map[i][j]][map[i][j+1]] += d;
}
//注意由于每一只蚂蚁的起始点是随机设置的,所以从终点到起点也要有增加信息素
add[map[i][N-1]][map[i][0]] += d;
}
//更新信息素
for(int i=0;i<N;i++)
{
for(int j = 0;j<N;j++)
{
phe[i][j] = phe[i][j]*rout + add[i][j];
//为信息素设置一个下限值和上限值
if(phe[i][j]<0.0001)
{
phe[i][j] = 0.0001;
}
if(phe[i][j]>20)
{
phe[i][j] = 20;
}
}
}
//恢复路线记录数组
for(int i = 0;i<M;i++ )
{
for(int j = 0;j<N;j++)
{
map[i][j] = -1;
vis[i][j] = 0;
}
}
}
//输出最优路线结果
for(int i = 0;i<N;i++ )
{
cout<<bestWay[i]<<endl;
}
cout<<"最优路线的总长度是:"<<bestSolution<<endl;
}
有7个城市(城市编号0到6,每两个城市之间的距离设置为两编号之和)的测试结果图:
有10个城市(城市编号0到6,每两个城市之间的距离设置为两编号之和)的测试结果图: