蚁群算法 c语言,蚁群算法的c语言版本

代码来源于博客http://blog.sina.com.cn/s/blog_6bb1b4b001016pt0.html

添加了部分注释,几乎没有改动(参数和城市格式略做改动),原博主的代码写的很容易理解,也是我找到的最短的代码了,在此感谢。

算法步骤基本与此网页类似介绍:http://www.nocow.cn/index.php/%E8%9A%81%E7%BE%A4%E4%BC%98%E5%8C%96%E7%AE%97%E6%B3%95

如果没有接触过蚁群算法,请先阅读http://download.csdn.net/detail/waytoaccept/9493547   这本书介绍的比较全,连参数都告诉你怎么调了。

代码如下:

//蚁群算法关于简单的TSP问题求解//

#include

#include

#include

#include

#include

#define M 13 //蚂蚁的数量

#define N 52 //城市的数量

#define R 1000 //迭代次数

#define IN 1 //初始化的信息素的量

#define MAX 0x7fffffff //定义最大值

struct coordinate

{

char city[15]; //城市名

int x; //城市相对横坐标

int y; //城市相对纵坐标

}coords[N];

double graph[N][N]; //储存城市之间的距离的邻接矩阵,自己到自己记作MAX

double phe[N][N]; //每条路径上的信息素的量

double add[N][N]; //代表相应路径上的信息素的增量

double yita[N][N]; //启发函数,yita[i][j]=1/graph[i][j]

int vis[M][N]; //标记已经走过的城市

int map[M][N]; //map[K][N]记录第K只蚂蚁走的路线

double solution[M]; //记录某次循环中每只蚂蚁走的路线的距离

int bestway[N]; //记录最近的那条路线

double bestsolution=MAX;

int NcMax; //代表迭代次数,理论上迭代次数越多所求的解更接近最优解,最具有说服力

double alpha,betra,rou,Q;

void Initialize(); //信息初始化

void Inputcoords(FILE *fp); //将文件中的坐标信息读入

void GreateGraph(); //根据坐标信息建图

double Distance(int *p); //计算蚂蚁所走的路线的总长度

void Result(); //将结果保存到out.txt中

void Initialize()//初始化参数和迭代次数

{

alpha=2; betra=4; rou=0.5; Q=50;

NcMax=R;

return ;

}

//从文件读入城市坐标

void Inputcoords(FILE *fp)

{

int i;

int number;

if(fp==NULL)

{

printf("Sorry,the file is not exist\n");

exit(1);

}

else

{

for(i=0; i

{

fscanf(fp,"%d,%d,%d,%s",&number,&coords[i].x,&coords[i].y,coords[i].city);

}

}

}

//初始化任意两个城市间的距离

void GreateGraph( )

{

int i,j;

double d;

for(i=0; i

{

graph[i][i]=MAX; //自己到自己标记为无穷大

for(j=i+1; j

{

d=(double)((coords[i].x-coords[j].x)*(coords[i].x-coords[j].x)+(coords[i].y-coords[j].y)*(coords[i].y-coords[j].y));

graph[j][i]=graph[i][j]=sqrt(d);

}

}

graph[N-1][N-1]=MAX;

return ;

}

//计算环路的最小代价

double Distance(int *p)

{

double d=0;

int i;

for(i=0; i

{

d+=graph[*(p+i)][*(p+i+1)];

}

d+=graph[*(p+i)][*(p)];

return d;

}

//输出各个结果

void Result()

{

FILE *fl;

int i;

fl = fopen("out.txt","a"); //将结果保存在out.txt这个文件里面

fprintf(fl,"%s\n","本次算法中的各参数如下:");

fprintf(fl,"alpha=%.3lf, betra=%.3lf, rou=%.3lf, Q=%.3lf\n",alpha,betra,rou,Q);

fprintf(fl,"%s %d\n","本次算法迭代次数为:",NcMax);

fprintf(fl,"%s %.4lf\n","本算法得出的最短路径长度为:",bestsolution);

fprintf(fl,"%s\n","本算法求得的最短路径为:");

for(i=0; i

fprintf(fl,"%s → ",coords[bestway[i]].city);

fprintf(fl,"%s",coords[bestway[0]].city);

fprintf(fl,"\n\n\n");

fclose(fl);

return ;

}

int main()

{

int NC=0;//迭代次数

int i,j,k;

int s;

double drand,pro,psum;

FILE *fp;

Initialize();

fp = fopen("coords.txt","r+");

Inputcoords(fp);

GreateGraph();

fclose(fp);

for(i=0; i

{

for(j=0; j

{

phe[i][j]=IN; //信息素初始化

if(i!=j)

yita[i][j]=100.0/graph[i][j]; //期望值,与距离成反比

}

}

memset(map,-1,sizeof(map)); //把蚂蚁走的路线置空

memset(vis,0,sizeof(vis)); //0表示未访问,1表示已访问

srand(time(NULL));

while(NC++<=NcMax)//迭代次数小于等于最大值

{

for(k=0; k

{

map[k][0]=(k+NC)%N; //给每只蚂蚁分配一个起点,并且保证起点在N个城市里

vis[k][map[k][0]]=1; //将起点标记为已经访问,第k个蚂蚁第1个点标记为访问。每个蚂蚁都有一个map

}

s=1;//当前每个蚂蚁应该走的第几个城市,下标从0开始,0是每个蚂蚁的起点且已经走过

while(s

{

for(k=0; k

{

psum=0;//Pij(概率)的分母部分,按照公式来计算

for(j=0; j

{

if(vis[k][j]==0)

{

psum+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra);

}

}

drand=(double)(rand()%5000);

drand/=5000.0; //生成一个小于1的随机数(轮盘随机)

pro=0;//累计的概率之和,当和大于随机数的时候,代表选中当前城市,很形象的模拟

for(j=0; j

{

if(vis[k][j]==0)

pro+=pow(phe[map[k][s-1]][j],alpha)*pow(yita[map[k][s-1]][j],betra)/psum;

if(pro>drand)

break;

}

vis[k][j]=1; //将走过的城市标记起来(选中j,将j标记)

map[k][s]=j; //记录城市的顺序

}

s++;

}//一次迭代完成

memset(add,0,sizeof(add));

for(k=0; k

{

solution[k]=Distance(map[k]); //蚂蚁k所走的路线的总长度

if(solution[k]

{

bestsolution=solution[k];

for(i=0; i

bestway[i]=map[k][i];//记录当前最好的路径

}

}

for(k=0; k

{

for(j=0; j

{

add[map[k][j]][map[k][j+1]]+=Q/solution[k];

}

add[N-1][0]+=Q/solution[k];//首尾相接

}

for(i=0; i

{

for(j=0; j

{

phe[i][j]=phe[i][j]*rou+add[i][j];//更新信息素

if(phe[i][j]<0.0001) //设立一个下界

phe[i][j]=0.0001;

else if(phe[i][j]>20) //设立一个上界,防止启发因子的作用被淹没

phe[i][j]=20;

}

}

memset(vis,0,sizeof(vis));

memset(map,-1,sizeof(map));

}

Result();

printf("Result is saved in out.txt\n");

return 0;

}

输入文件coords.txt:格式(序号,横坐标,纵坐标,城市代号)

0,1,1,a

1,1,2,b

2,1,3,c

3,1,4,d

4,1,5,e

5,1,6,f

6,1,7,g

7,1,8,h

8,1,9,i

9,1,10,j

10,2,11,k

11,7,11,l

12,12,11,m

13,17,11,n

14,22,11,o

15,27,11,p

16,32,11,q

17,37,11,r

18,42,11,s

19,47,11,t

20,52,11,u

21,57,11,v

22,62,11,w

23,67,11,x

24,72,11,y

25,77,11,z

26,82,11,A

27,87,11,B

28,92,11,C

29,97,11,D

30,101,10,E

31,101,9,F

32,101,8,G

33,101,7,H

34,101,6,I

35,101,5,J

36,101,4,K

37,101,3,L

38,101,2,M

39,100,1,N

40,95,1,O

41,90,1,P

42,85,1,Q

43,80,1,R

44,75,1,S

45,70,1,T

46,65,1,U

47,60,1,V

48,55,1,W

49,50,1,X

50,45,1,Y

51,40,1,Z

输出结果

本次算法中的各参数如下:

alpha=2.000, betra=4.000, rou=0.500, Q=50.000

本次算法迭代次数为: 1000

本算法得出的最短路径长度为: 217.9515

本算法求得的最短路径为:

j → k → l → m → n → o → p → q → r → s → t → u → v → w → x → y → z →

A → B → C → D → E → F → G → H → I → J → K → L → M → N → O → P → Q →

R → S → T → U → V → W → X → Y → Z → a → b → c → d → e → f → g → h → i → j

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值