|
- #include<iostream>
- #include<stdio.h>
- #include<string>
- #include<string.h>
- #include<cmath>
- #include<ctime>
- #include<stdlib.h>
- using namespace std;
- int seed=(int)time(0);//产生随机种子
- int CityPos[30][2]= {{87,7},{91,38},{83,46},{71,44},{64,60},{68,58},{83,69},{87,76},{74,78},{71,71},{58,69},{54,62},{51,67},{37,84},{41,94},{2,99},{7,64},{22,60},{25,62},{18,54},{4,50},{13,40},{18,40},{24,42},{25,38},{41,26},{45,21},{44,35},{58,35},{62,32}};
- #define CITY_NUM 30//城市数量
- #define ANT_NUM 30//蚁群数量
- #define TMAC 10000//迭代最大次数
- #define ROU 0.5//误差大小
- #define ALPHA 1//信息素重要程度的参数
- #define BETA 4//启发式因子重要程度的参数
- #define Q 100//信息素残留参数
- #define maxn 100
- #define inf 0x3f3f3f3f
- double dis[maxn][maxn];//距离矩阵
- double info[maxn][maxn];//信息素矩阵
- bool vis[CITY_NUM][CITY_NUM];//标记矩阵
-
- //返回指定范围内的随机整数
- int rnd(int low,int upper)
- {
- return low+(upper-low)*rand()/(RAND_MAX+1);
- }
-
- //返回指定范围内的随机浮点数
- double rnd(double low,double upper)
- {
- double temp=rand()/((double)RAND_MAX+1.0);
- return low+temp*(upper-low);
- }
-
- struct Ant
- {
- int path[CITY_NUM];//保存蚂蚁走的路径
- double length;//路径总长度
- bool vis[CITY_NUM];//标记走过的城市
- int cur_cityno;//当前城市
- int moved_cnt;//已走城市数量
-
- //初始化
- void Init()
- {
- memset(vis,false,sizeof(vis));
- length=0;
- cur_cityno=rnd(0,CITY_NUM);
- path[0]=cur_cityno;
- vis[cur_cityno]=true;
- moved_cnt=1;
- }
-
- //选择下一个城市
- int Choose()
- {
- int select_city=-1;//所选城市编号
- double sum=0;
- double prob[CITY_NUM];//保存每个城市被选中的概率
- for(int i=0; i<CITY_NUM; i++)
- {
- if(!vis[i])
- {
- prob[i]=pow(info[cur_cityno][i],ALPHA)*pow(1.0/dis[cur_cityno][i], BETA);
- sum=sum+prob[i];
- }
- else
- {
- prob[i]=0;
- }
- }
- //进行轮盘选择
- double temp=0;
- if(sum>0)//总的信息素大于0
- {
- temp=rnd(0.0,sum);
- for(int i=0; i<CITY_NUM; i++)
- {
- if(!vis[i])
- {
- temp=temp-prob[i];
- if(temp<0.0)
- {
- select_city=i;
- break;
- }
- }
- }
- }
- else //信息素太少就随便找个没走过的城市
- {
- for(int i=0; i<CITY_NUM; i++)
- {
- if(!vis[i])
- {
- select_city=i;
- break;
- }
- }
- }
- return select_city;
- }
-
- //蚂蚁的移动
- void Move()
- {
- int nex_cityno=Choose();
- path[moved_cnt]=nex_cityno;
- vis[nex_cityno]=true;
- length=length+dis[cur_cityno][nex_cityno];
- cur_cityno=nex_cityno;
- moved_cnt++;
- }
-
- //蚂蚁进行一次迭代
- void Search()
- {
- Init();
- while(moved_cnt<CITY_NUM)
- {
- Move();
- }
- //回到原来的城市
- length=length+dis[path[CITY_NUM-1]][path[0]];
- }
- };
-
- struct TSP
- {
- Ant ants[ANT_NUM];//定义蚁群
- Ant ant_best;//最优路径蚂蚁
-
- void Init()
- {
- //初始化为最大值
- ant_best.length = inf;
- //计算两两城市间距离
- for (int i = 0; i < CITY_NUM; i++)
- {
- for (int j = 0; j < CITY_NUM; j++)
- {
- info[i][j]=1.0;
- double temp1=CityPos[j][0]-CityPos[i][0];
- double temp2=CityPos[j][1]-CityPos[i][1];
- dis[i][j] = sqrt(temp1*temp1+temp2*temp2);
- }
- }
- }
-
- //更新信息素
- void UpdateInfo()
- {
- double temp_info[CITY_NUM][CITY_NUM];
- memset(temp_info,0,sizeof(temp_info));
- int u,v;
- for(int i=0; i<ANT_NUM; i++) //遍历每一只蚂蚁
- {
- for(int j=1; j<CITY_NUM; j++)
- {
- u=ants[i].path[j-1];
- v=ants[i].path[j];
- temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
- temp_info[v][u]=temp_info[u][v];
- }
- //最后城市和开始城市之间的信息素
- u=ants[i].path[0];
- temp_info[u][v]=temp_info[u][v]+Q/ants[i].length;
- temp_info[v][u]=temp_info[u][v];
- }
- for(int i=0; i<CITY_NUM; i++)
- {
- for(int j=0; j<CITY_NUM; j++)
- {
- info[i][j]=info[i][j]*ROU+temp_info[i][j];
- }
- }
- }
- void Search()
- {
- //迭代TMAC次
- for(int i=0; i<TMAC; i++)
- {
- //所有蚂蚁都进行一次遍历
- for(int j=0; j<ANT_NUM; j++)
- {
- ants[j].Search();
- }
- //保存所有蚂蚁遍历的最佳结果
- for(int j=0; j<ANT_NUM; j++)
- {
- if(ant_best.length>ants[j].length)
- {
- ant_best=ants[j];
- }
- }
- UpdateInfo();
- printf("第%d次迭代最优路径长度是%lf\n", i,ant_best.length);
- printf("\n");
- }
- }
- };
- int main()
- {
- srand(seed);
- TSP tsp;
- tsp.Init();
- tsp.Search();
- printf("最短路径如下\n");
- for(int i=0;i<CITY_NUM;i++)
- {
- printf("%d",tsp.ant_best.path[i]);
- if(i<CITY_NUM-1)
- printf("->");
- else
- printf("\n");
- }
- return 0;
- }
复制代码 |
|