`
twtmnm1314
  • 浏览: 66596 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

蚁群算法ACO(ant colony optimization)的原理以及实现源代码

阅读更多
小小的蚂蚁总是能够找到食物,他们具有什么样的智能呢?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。 为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就是人工生命、复杂性科学解释的规律! 下面就是实现如此复杂性的七条简单规则: 1、范围: 蚂蚁观察到的范围是一个方格世界,蚂蚁有一个参数为速度半径(一般是3),那么它能观察到的范围就是3*3个方格世界,并且能移动的距离也在这个范围之内。 2、环境: 蚂蚁所在的环境是一个虚拟的世界,其中有障碍物,有别的蚂蚁,还有信息素,信息素有两种,一种是找到食物的蚂蚁洒下的食物信息素,一种是找到窝的蚂蚁洒下的窝的信息素。每个蚂蚁都仅仅能感知它范围内的环境信息。环境以一定的速率让信息素消失。 3、觅食规则: 在每只蚂蚁能感知的范围内寻找是否有食物,如果有就直接过去。否则看是否有信息素,并且比较在能感知的范围内哪一点的信息素最多,这样,它就朝信息素多的地方走,并且每只蚂蚁多会以小概率犯错误,从而并不是往信息素最多的点移动。蚂蚁找窝的规则和上面一样,只不过它对窝的信息素做出反应,而对食物信息素没反应。 4、移动规则: 每只蚂蚁都朝向信息素最多的方向移,并且,当周围没有信息素指引的时候,蚂蚁会按照自己原来运动的方向惯性的运动下去,并且,在运动的方向有一个随机的小的扰动。为了防止蚂蚁原地转圈,它会记住最近刚走过了哪些点,如果发现要走的下一点已经在最近走过了,它就会尽量避开。 5、避障规则: 如果蚂蚁要移动的方向有障碍物挡住,它会随机的选择另一个方向,并且有信息素指引的话,它会按照觅食的规则行为。 7、播撒信息素规则: 每只蚂蚁在刚找到食物或者窝的时候撒发的信息素最多,并随着它走远的距离,播撒的信息素越来越少。 下面的程序开始运行之后,蚂蚁们开始从窝里出动了,寻找食物;他们会顺着屏幕爬满整个画面,直到找到食物再返回窝。 其中,‘F’点表示食物,‘H’表示窝,白色块表示障碍物,‘+’就是蚂蚁了。 参数说明: 最大信息素:蚂蚁在一开始拥有的信息素总量,越大表示程序在较长一段时间能够存在信息素。信息素消减的速度:随着时间的流逝,已经存在于世界上的信息素会消减,这个数值越大,那么消减的越快。 错误概率表示这个蚂蚁不往信息素最大的区域走的概率,越大则表示这个蚂蚁越有创新性。 速度半径表示蚂蚁一次能走的最大长度,也表示这个蚂蚁的感知范围。 记忆能力表示蚂蚁能记住多少个刚刚走过点的坐标,这个值避免了蚂蚁在本地打转,停滞不前。而这个值越大那么整个系统运行速度就慢,越小则蚂蚁越容易原地转圈。 源代码如下: /*ant.c*/ #define SPACE 0x20 #define ESC 0x1b #define ANT_CHAR_EMPTY '+' #define ANT_CHAR_FOOD 153 #define HOME_CHAR 'H' #define FOOD_CHAR 'F' #define FOOD_CHAR2 'f' #define FOOD_HOME_COLOR 12 #define BLOCK_CHAR 177 #define MAX_ANT 50 #define INI_SPEED 3 #define MAXX 80 #define MAXY 23 #define MAX_FOOD 10000 #define TARGET_FOOD 200 #define MAX_SMELL 5000 #define SMELL_DROP_RATE 0.05 #define ANT_ERROR_RATE 0.02 #define ANT_EYESHOT 3 #define SMELL_GONE_SPEED 50 #define SMELL_GONE_RATE 0.05 #define TRACE_REMEMBER 50 #define MAX_BLOCK 100 #define NULL 0 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define SMELL_TYPE_FOOD 0 #define SMELL_TYPE_HOME 1 #include "stdio.h" #include "conio.h" #include "dos.h" #include "stdlib.h" #include "dos.h" #include "process.h" #include "ctype.h" #include "math.h" void WorldInitial(void); void BlockInitial(void); void CreatBlock(void); void SaveBlock(void); void LoadBlock(void); void HomeFoodInitial(void); void AntInitial(void); void WorldChange(void); void AntMove(void); void AntOneStep(void); void DealKey(char key); void ClearSmellDisp(void); void DispSmell(int type); int AntNextDir(int xxx,int yyy,int ddir); int GetMaxSmell(int type,int xxx,int yyy,int ddir); int IsTrace(int xxx,int yyy); int MaxLocation(int num1,int num2,int num3); int CanGo(int xxx,int yyy,int ddir); int JudgeCanGo(int xxx,int yyy); int TurnLeft(int ddir); int TurnRight(int ddir); int TurnBack(int ddir); int MainTimer(void); char WaitForKey(int secnum); void DispPlayTime(void); int TimeUse(void); void HideCur(void); void ResetCur(void); /* --------------- */ struct HomeStruct { int xxx,yyy; int amount; int TargetFood; }home; struct FoodStruct { int xxx,yyy; int amount; }food; struct AntStruct { int xxx,yyy; int dir; int speed; int SpeedTimer; int food; int SmellAmount[2]; int tracex[TRACE_REMEMBER]; int tracey[TRACE_REMEMBER]; int TracePtr; int IQ; }ant[MAX_ANT]; int AntNow; int timer10ms; struct time starttime,endtime; int Smell[2][MAXX+1][MAXY+1]; int block[MAXX+1][MAXY+1]; int SmellGoneTimer; int SmellDispFlag; int CanFindFood; int HardtoFindPath; /* ----- Main -------- */ void main(void) { char KeyPress; int tu; clrscr(); HideCur(); WorldInitial(); do { timer10ms = MainTimer(); if(timer10ms) AntMove(); if(timer10ms) WorldChange(); tu = TimeUse(); if(tu>=60&&!CanFindFood) { gotoxy(1,MAXY+1); printf("Can not find food, maybe a block world."); WaitForKey(10); WorldInitial(); } if(tu>=180&&home.amount<100&&!HardtoFindPath) { gotoxy(1,MAXY+1); printf("God! it is so difficult to find a path."); if(WaitForKey(10)==0x0d) WorldInitial(); else { HardtoFindPath = 1; gotoxy(1,MAXY+1); printf(" "); } } if(home.amount>=home.TargetFood) { gettime(&endtime); KeyPress = WaitForKey(60); DispPlayTime(); WaitForKey(10); WorldInitial(); } else if(kbhit()) { KeyPress = getch(); DealKey(KeyPress); } else KeyPress = NULL; } while(KeyPress!=ESC); gettime(&endtime); DispPlayTime(); WaitForKey(10); clrscr(); ResetCur(); } /* ------ general sub process ----------- */ int MainTimer(void) /* output: how much 10ms have pass from last time call this process */ { static int oldhund,oldsec; struct time t; int timeuse; gettime(&t); timeuse = 0; if(t.ti_hund!=oldhund) { if(t.ti_sec!=oldsec) { timeuse+=100; oldsec = t.ti_sec; } timeuse+=t.ti_hund-oldhund; oldhund = t.ti_hund; } else timeuse = 0; return (timeuse); } char WaitForKey(int secnum) /* funtion: if have key in, exit immediately, else wait 'secnum' senconds then exit input: secnum -- wait this senconds, must < 3600 (1 hour) output: key char, if no key in(exit when timeout), return NULL */ { int secin,secnow; int minin,minnow; int hourin,hournow; int secuse; struct time t; gettime(&t); secin = t.ti_sec; minin = t.ti_min; hourin = t.ti_hour; do { if(kbhit()) return(getch()); gettime(&t); secnow = t.ti_sec; minnow = t.ti_min; hournow = t.ti_hour; if(hournow!=hourin) minnow+=60; if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin); else secuse = secnow - secin; /* counting error check */ if(secuse<0) { gotoxy(1,MAXY+1); printf("Time conuting error, any keyto exit..."); getch(); exit(3); } } while(secuse<=secnum); return (NULL); } void DispPlayTime(void) { int ph,pm,ps; ph = endtime.ti_hour - starttime.ti_hour; pm = endtime.ti_min - starttime.ti_min; ps = endtime.ti_sec - starttime.ti_sec; if(ph<0) ph+=24; if(pm<0) { ph--; pm+=60; } if(ps<0) { pm--; ps+=60; } gotoxy(1,MAXY+1); printf("Time use: %d hour- %d min- %d sec ",ph,pm,ps); } int TimeUse(void) { int ph,pm,ps; gettime(&endtime); ph = endtime.ti_hour - starttime.ti_hour; pm = endtime.ti_min - starttime.ti_min; ps = endtime.ti_sec - starttime.ti_sec; if(ph<0) ph+=24; if(pm<0) { ph--; pm+=60; } if(ps<0) { pm--; ps+=60; } return(ps+(60*(pm+60*ph))); } void HideCur(void) { union REGS regs0; regs0.h.ah=1; regs0.h.ch=0x30; regs0.h.cl=0x31; int86(0x10,®s0,®s0); } void ResetCur(void) { union REGS regs0; regs0.h.ah=1; regs0.h.ch=0x06; regs0.h.cl=0x07; int86(0x10,®s0,®s0); } /* ------------ main ANT programe ------------- */ void WorldInitial(void) { int k,i,j; randomize(); clrscr(); HomeFoodInitial(); for(AntNow=0;AntNow<max_ant;antnow++) {="" antinitial();="" }="" *="" of="" for="" antnow="" *="" ;="" blockinitial();="" for(k="0;k&lt;=1;k++)" *="" smell="" type="" food="" and="" home="" *="" for(i="0;i&lt;=MAXX;i++)" for(j="0;j&lt;=MAXY;j++)" smell[k][i][j]="0;" smellgonetimer="0;" gettime(&starttime);="" smelldispflag="0;" canfindfood="0;" hardtofindpath="0;" }="" void="" blockinitial(void)="" {="" int="" i,j;="" int="" bn;="" for(i="0;i&lt;=MAXX;i++)" for(j="0;j&lt;=MAXY;j++)" block[i][j]="0;" bn="1+" max_block="" 2="" +="" random(max_block="" 2);="" for(i="0;i&lt;=bn;i++)" creatblock();="" }="" void="" creatblock(void)="" {="" int="" x1,y1,x2,y2;="" int="" dx,dy;="" int="" i,j;="" x1="random(MAXX)+1;" y1="random(MAXY)+1;" dx="random(MAXX/10)+1;" dy="random(MAXY/10)+1;" x2="x1+dx;" y2="y1+dy;" if(x2="">MAXX) x2 = MAXX; if(y2>MAXY) y2 = MAXY; if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2) return; if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2) return; for(i=x1;i<=x2;i++) for(j=y1;j<=y2;j++) { block[i][j] = 1; gotoxy(i,j); putch(BLOCK_CHAR); } } void SaveBlock(void) { FILE *fp_block; char FileNameBlock[20]; int i,j; gotoxy(1,MAXY+1); printf(" "); gotoxy(1,MAXY+1); printf("Save to file...",FileNameBlock); gets(FileNameBlock); if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant"); else strcat(FileNameBlock,".ant"); if ((fp_block = fopen(FileNameBlock, "wb")) == NULL) { gotoxy(1,MAXY+1); printf("Creat file %s fail...",FileNameBlock); getch(); exit(2); } gotoxy(1,MAXY+1); printf(" "); fputc(home.xxx,fp_block); fputc(home.yyy,fp_block); fputc(food.xxx,fp_block); fputc(food.yyy,fp_block); for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) fputc(block[i][j],fp_block); fclose(fp_block); } void LoadBlock(void) { FILE *fp_block; char FileNameBlock[20]; int i,j,k; gotoxy(1,MAXY+1); printf(" "); gotoxy(1,MAXY+1); printf("Load file...",FileNameBlock); gets(FileNameBlock); if(FileNameBlock[0]==0) strcpy(FileNameBlock,"Ant.ant"); else strcat(FileNameBlock,".ant"); if ((fp_block = fopen(FileNameBlock, "rb")) == NULL) { gotoxy(1,MAXY+1); printf("Open file %s fail...",FileNameBlock); getch(); exit(2); } clrscr(); home.xxx = fgetc(fp_block); home.yyy = fgetc(fp_block); food.xxx = fgetc(fp_block); food.yyy = fgetc(fp_block); gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR); food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1; /* food.amount = MAX_FOOD; */ home.amount = 0; home.TargetFood = (food.amount<target_food)?food.amount:target_food; for(antnow="0;AntNow&lt;MAX_ANT;AntNow++)" {="" antinitial();="" }="" *="" of="" for="" antnow="" *="" ;="" for(i="0;i&lt;=MAXX;i++)" for(j="0;j&lt;=MAXY;j++)" {="" block[i][j]="fgetc(fp_block);" if(block[i][j])="" {="" gotoxy(i,j);="" putch(block_char);="" }="" }="" for(k="0;k&lt;=1;k++)" *="" smell="" type="" food="" and="" home="" *="" for(i="0;i&lt;=MAXX;i++)" for(j="0;j&lt;=MAXY;j++)" smell[k][i][j]="0;" smellgonetimer="0;" gettime(&starttime);="" smelldispflag="0;" canfindfood="0;" hardtofindpath="0;" fclose(fp_block);="" }="" void="" homefoodinitial(void)="" {="" int="" randnum;="" int="" homeplace;="" *="" 1="" --="" home="" at="" left-up,="" food="" at="" right-down="" 2="" --="" home="" at="" left-down,="" food="" at="" right-up="" 3="" --="" home="" at="" right-up,="" food="" at="" left-down="" 4="" --="" home="" at="" right-down,="" food="" at="" left-up="" *="" randnum="random(100);" if(randnum<25)="" homeplace="1;" else="" if="" (randnum="">=25&&randnum<50) homeplace = 2; else if (randnum>=50&&randnum<75) homeplace = 3; else homeplace = 4; switch(homeplace) { case 1: home.xxx = random(MAXX/3)+1; home.yyy = random(MAXY/3)+1; food.xxx = random(MAXX/3)+2*MAXX/3+1; food.yyy = random(MAXY/3)+2*MAXY/3+1; break; case 2: home.xxx = random(MAXX/3)+1; home.yyy = random(MAXY/3)+2*MAXY/3+1; food.xxx = random(MAXX/3)+2*MAXX/3+1; food.yyy = random(MAXY/3)+1; break; case 3: home.xxx = random(MAXX/3)+2*MAXX/3+1; home.yyy = random(MAXY/3)+1; food.xxx = random(MAXX/3)+1; food.yyy = random(MAXY/3)+2*MAXY/3+1; break; case 4: home.xxx = random(MAXX/3)+2*MAXX/3+1; home.yyy = random(MAXY/3)+2*MAXY/3+1; food.xxx = random(MAXX/3)+1; food.yyy = random(MAXY/3)+1; break; } food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1; /* food.amount = MAX_FOOD; */ home.amount = 0; home.TargetFood = (food.amount<target_food)?food.amount:target_food; *="" data="" correctness="" check="" *="" if(home.xxx<="0||home.xxx">MAXX||home.yyy<=0||home.yyy>MAXY|| food.xxx<=0||food.xxx>MAXX||food.yyy<=0||food.yyy>MAXY|| food.amount<=0) { gotoxy(1,MAXY+1); printf("World initial fail, any key to exit..."); getch(); exit(2); } gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR); } void AntInitial(void) /* initial ant[AntNow] */ { int randnum; int i; ant[AntNow].xxx = home.xxx; ant[AntNow].yyy = home.yyy; randnum = random(100); if(randnum<25) ant[AntNow].dir = UP; else if (randnum>=25&&randnum<50) ant[AntNow].dir = DOWN; else if (randnum>=50&&randnum<75) ant[AntNow].dir = LEFT; else ant[AntNow].dir = RIGHT; ant[AntNow].speed = 2*(random(INI_SPEED/2)+1); ant[AntNow].SpeedTimer = 0; ant[AntNow].food = 0; ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL; ant[AntNow].IQ = 1; for(i=0;i<trace_remember;i++) {="" ant[antnow].tracex[i]="0;" ant[antnow].tracey[i]="0;" }="" ant[antnow].traceptr="0;" *="" a="" sepecail="" ant="" *="" if(antnow="=0)" ant[antnow].speed="INI_SPEED;" }="" void="" worldchange(void)="" {="" int="" k,i,j;="" int="" smelldisp;="" smellgonetimer+="timer10ms;" if(smellgonetimer="">=SMELL_GONE_SPEED) { SmellGoneTimer = 0; for(k=0;k<=1;k++) /* SMELL TYPE FOOD and HOME */ for(i=1;i<=MAXX;i++) for(j=1;j<=MAXY;j++) { if(Smell[k][i][j]) { smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000; if(SmellDispFlag) { gotoxy(i,j); if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy)) /* don't over write Food and Home */; else { if(smelldisp>9) putch('#'); else putch(smelldisp+'0'); } } Smell[k][i][j]-= 1+(Smell[k][i][j]*SMELL_GONE_RATE); if(Smell[k][i][j]<0) Smell[k][i][j] = 0; if(SmellDispFlag) { if(Smell[k][i][j]<=2) { gotoxy(i,j); putch(SPACE); } } } } /* of one location */ } /* of time to change the world */ } /* of world change */ void AntMove(void) { int antx,anty; int smelltodrop,smellnow; for(AntNow=0;AntNow<max_ant;antnow++) {="" ant[antnow].speedtimer+="timer10ms;" if(ant[antnow].speedtimer="">=ant[AntNow].speed) { ant[AntNow].SpeedTimer = 0; gotoxy(ant[AntNow].xxx,ant[AntNow].yyy); putch(SPACE); AntOneStep(); gotoxy(ant[AntNow].xxx,ant[AntNow].yyy); /* ant0 is a sepecail ant, use different color */ if(AntNow==0) textcolor(0xd); if(ant[AntNow].food) putch(ANT_CHAR_FOOD); else putch(ANT_CHAR_EMPTY); if(AntNow==0) textcolor(0x7); /* remember trace */ ant[AntNow].tracex[ant[AntNow].TracePtr] = ant[AntNow].xxx; ant[AntNow].tracey[ant[AntNow].TracePtr] = ant[AntNow].yyy; if(++(ant[AntNow].TracePtr)>=TRACE_REMEMBER) ant[AntNow].TracePtr = 0; /* drop smell */ antx = ant[AntNow].xxx; anty = ant[AntNow].yyy; if(ant[AntNow].food) /* have food, looking for home */ { if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]) { smellnow = Smell[SMELL_TYPE_FOOD][antx][anty]; smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]*SMELL_DROP_RATE; if(smelltodrop>smellnow) Smell[SMELL_TYPE_FOOD][antx][anty] = smelltodrop; /* else Smell[...] = smellnow */ ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]-= smelltodrop; if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]<0) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; } /* of have smell to drop */ } /* of have food */ else /* no food, looking for food */ { if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]) { smellnow = Smell[SMELL_TYPE_HOME][antx][anty]; smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_HOME]*SMELL_DROP_RATE; if(smelltodrop>smellnow) Smell[SMELL_TYPE_HOME][antx][anty] = smelltodrop; /* else Smell[...] = smellnow */ ant[AntNow].SmellAmount[SMELL_TYPE_HOME]-= smelltodrop; if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]<0) ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; } /* of have smell to drop */ } } /* of time to go */ /* else not go */ } /* of for AntNow */ textcolor(FOOD_HOME_COLOR); gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); if(food.amount>0) putch(FOOD_CHAR); else putch(FOOD_CHAR2); textcolor(7); gotoxy(1,MAXY+1); printf("Food %d, Home %d ",food.amount,home.amount); } void AntOneStep(void) { int ddir,tttx,ttty; int i; ddir = ant[AntNow].dir; tttx = ant[AntNow].xxx; ttty = ant[AntNow].yyy; ddir = AntNextDir(tttx,ttty,ddir); switch(ddir) { case UP: ttty--; break; case DOWN: ttty++; break; case LEFT: tttx--; break; case RIGHT: tttx++; break; default: break; } /* of switch dir */ ant[AntNow].dir = ddir; ant[AntNow].xxx = tttx; ant[AntNow].yyy = ttty; if(ant[AntNow].food) /* this ant carry with food, search for home */ { if(tttx==home.xxx&&ttty==home.yyy) { home.amount++; AntInitial(); } if(tttx==food.xxx&&ttty==food.yyy) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; } /* of search for home */ else /* this ant is empty, search for food */ { if(tttx==food.xxx&&ttty==food.yyy) { if(food.amount>0) { ant[AntNow].food = 1; food.amount--; ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; ant[AntNow].dir = TurnBack(ant[AntNow].dir); for(i=0;i<trace_remember;i++) {="" ant[antnow].tracex[i]="0;" ant[antnow].tracey[i]="0;" }="" ant[antnow].traceptr="0;" canfindfood="1;" }="" *="" of="" still="" have="" food="" *="" }="" if(tttx="=home.xxx&amp;&amp;ttty==home.yyy)" ant[antnow].smellamount[smell_type_home]="MAX_SMELL;" }="" *="" of="" search="" for="" food="" *="" }="" void="" dealkey(char="" key)="" {="" int="" i;="" switch(key)="" {="" case="" 'p':="" gettime(&endtime);="" dispplaytime();="" getch();="" gotoxy(1,maxy+1);="" for(i="1;i&lt;=MAXX-1;i++)" putch(space);="" break;="" case="" 't':="" if(smelldispflag)="" {="" smelldispflag="0;" clearsmelldisp();="" }="" else="" smelldispflag="1;" break;="" case="" '1':="" dispsmell(smell_type_food);="" getch();="" clearsmelldisp();="" break;="" case="" '2':="" dispsmell(smell_type_home);="" getch();="" clearsmelldisp();="" break;="" case="" '3':="" dispsmell(2);="" getch();="" clearsmelldisp();="" break;="" case="" 's':="" saveblock();="" break;="" case="" 'l':="" loadblock();="" break;="" default:="" gotoxy(1,maxy+1);="" for(i="1;i&lt;=MAXX-1;i++)" putch(space);="" }="" *="" of="" switch="" *="" }="" void="" clearsmelldisp(void)="" {="" int="" k,i,j;="" for(k="0;k&lt;=1;k++)" *="" smell="" type="" food="" and="" home="" *="" for(i="1;i&lt;=MAXX;i++)" for(j="1;j&lt;=MAXY;j++)" {="" if(smell[k][i][j])="" {="" gotoxy(i,j);="" putch(space);="" }="" }="" *="" of="" one="" location="" *="" }="" void="" dispsmell(int="" type)="" *="" input:="" 0="" --="" only="" display="" food="" smell="" 1="" --="" only="" display="" home="" smell="" 2="" --="" display="" both="" food="" and="" home="" smell="" *="" {="" int="" k,i,j;="" int="" fromk,tok;="" int="" smelldisp;="" switch(type)="" {="" case="" 0:="" fromk="0;" tok="0;" break;="" case="" 1:="" fromk="1;" tok="1;" break;="" case="" 2:="" fromk="0;" tok="1;" break;="" default:fromk="0;" tok="1;" break;="" }="" smellgonetimer="0;" for(k="fromk;k&lt;=tok;k++)" *="" smell="" type="" food="" and="" home="" *="" for(i="1;i&lt;=MAXX;i++)" for(j="1;j&lt;=MAXY;j++)" {="" if(smell[k][i][j])="" {="" smelldisp="1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE));" if(smelldisp="">=30000||smelldisp<0) smelldisp = 30000; gotoxy(i,j); if(i!=food.xxx||j!=food.yyy) { if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy)) /* don't over write Food and Home */; else { if(smelldisp>9) putch('#'); else putch(smelldisp+'0'); } } } } /* of one location */ } int AntNextDir(int xxx,int yyy,int ddir) { int randnum; int testdir; int CanGoState; int cangof,cangol,cangor; int msf,msl,msr,maxms; int type; CanGoState = CanGo(xxx,yyy,ddir); if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6) cangof = 1; else cangof = 0; if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5) cangol = 1; else cangol = 0; if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4) cangor = 1; else cangor = 0; if(ant[AntNow].food) type = SMELL_TYPE_HOME; else type = SMELL_TYPE_FOOD; msf = GetMaxSmell(type,xxx,yyy,ddir); msl = GetMaxSmell(type,xxx,yyy,TurnLeft(ddir)); msr= GetMaxSmell(type,xxx,yyy,TurnRight(ddir)); maxms = MaxLocation(msf,msl,msr); /* maxms - 1 - msf is MAX 2 - msl is MAX 3 - msr is MAX 0 - all 3 number is 0 */ testdir = NULL; switch(maxms) { case 0: /* all is 0, keep testdir = NULL, random select dir */ break; case 1: if(cangof) testdir = ddir; else if(msl>msr) if(cangol) testdir = TurnLeft(ddir); else if(cangor) testdir = TurnRight(ddir); break; case 2: if(cangol) testdir = TurnLeft(ddir); else if(msf>msr) if(cangof) testdir = ddir; else if(cangor) testdir = TurnRight(ddir); break; case 3: if(cangor) testdir = TurnRight(ddir); else if(msf>msl) if(cangof) testdir =ddir; else if(cangol) testdir = TurnLeft(ddir); break; default:break; } /* of maxms */ randnum = random(1000); if(randnum<smell_drop_rate*1000||testdir==null) *="" 1.="" if="" testdir="NULL," means="" can="" not="" find="" the="" max="" smell="" or="" the="" dir="" to="" max="" smell="" can="" not="" go="" then="" random="" select="" dir="" 2.="" if="" ant="" error,="" don't="" follow="" the="" smell,="" random="" select="" dir="" *="" {="" randnum="random(100);" switch(cangostate)="" {="" case="" 0:="" if(randnum<90)="" testdir="ddir;" else="" if="" (randnum="">=90&&randnum<95) testdir = TurnLeft(ddir); else testdir = TurnRight(ddir); break; case 1: if(randnum<50) testdir = TurnLeft(ddir); else testdir = TurnRight(ddir); break; case 2: if(randnum<90) testdir = ddir; else testdir = TurnRight(ddir); break; case 3: if(randnum<90) testdir = ddir; else testdir = TurnLeft(ddir); break; case 4: testdir = TurnRight(ddir); break; case 5: testdir = TurnLeft(ddir); break; case 6: testdir = ddir; break; case 7: testdir = TurnBack(ddir); break; default:testdir = TurnBack(ddir); } /* of can go state */ } return(testdir); } int GetMaxSmell(int type,int xxx,int yyy,int ddir) { int i,j; int ms; /* MAX smell */ ms = 0; switch(ddir) { case UP: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++) for(j=yyy-ANT_EYESHOT;j<yyy;j++) {="" if(!judgecango(i,j))="" continue;="" if((i="=food.xxx&amp;&amp;j==food.yyy&amp;&amp;type==SMELL_TYPE_FOOD)||" (i="=home.xxx&amp;&amp;j==home.yyy&amp;&amp;type==SMELL_TYPE_HOME))" {="" ms="MAX_SMELL;" break;="" }="" if(istrace(i,j))="" continue;="" if(smell[type][i][j]="">ms) ms = Smell[type][i][j]; } break; case DOWN: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++) for(j=yyy+1;j<=yyy+ANT_EYESHOT;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; case LEFT: for(i=xxx-ANT_EYESHOT;i<xxx;i++) for(j="yyy-ANT_EYESHOT;j&lt;=yyy+ANT_EYESHOT;j++)" {="" if(!judgecango(i,j))="" continue;="" if((i="=food.xxx&amp;&amp;j==food.yyy&amp;&amp;type==SMELL_TYPE_FOOD)||" (i="=home.xxx&amp;&amp;j==home.yyy&amp;&amp;type==SMELL_TYPE_HOME))" {="" ms="MAX_SMELL;" break;="" }="" if(istrace(i,j))="" continue;="" if(smell[type][i][j]="">ms) ms = Smell[type][i][j]; } break; case RIGHT: for(i=xxx+1;i<=xxx+ANT_EYESHOT;i++) for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; default: break; } return(ms); } int IsTrace(int xxx,int yyy) { int i; for(i=0;i<trace_remember;i++) if(ant[antnow].tracex[i]="=xxx&amp;&amp;ant[AntNow].tracey[i]==yyy)" return(1);="" return(0);="" }="" int="" maxlocation(int="" num1,int="" num2,int="" num3)="" {="" int="" maxnum;="" if(num1="=0&amp;&amp;num2==0&amp;&amp;num3==0)" return(0);="" maxnum="num1;" if(num2="">maxnum) maxnum = num2; if(num3>maxnum) maxnum = num3; if(maxnum==num1) return(1); if(maxnum==num2) return(2); if(maxnum==num3) return(3); } int CanGo(int xxx,int yyy,int ddir) /* input: xxx,yyy - location of ant ddir - now dir output: 0 - forward and left and right can go 1 - forward can not go 2 - left can not go 3 - right can not go 4 - forward and left can not go 5 - forward and right can not go 6 - left and right can not go 7 - forward and left and right all can not go */ { int tx,ty,tdir; int okf,okl,okr; /* forward can go ? */ tdir = ddir; tx = xxx; ty = yyy; switch(tdir) { case UP: ty--; break; case DOWN: ty++; break; case LEFT: tx--; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okf = 1; else okf = 0; /* turn left can go ? */ tdir = TurnLeft(ddir); tx = xxx; ty = yyy; switch(tdir) { case UP: ty--; break; case DOWN: ty++; break; case LEFT: tx--; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okl = 1; else okl = 0; /* turn right can go ? */ tdir = TurnRight(ddir); tx = xxx; ty = yyy; switch(tdir) { case UP: ty--; break; case DOWN: ty++; break; case LEFT: tx--; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okr = 1; else okr = 0; if(okf&&okl&&okr) return(0); if(!okf&&okl&&okr) return(1); if(okf&&!okl&&okr) return(2); if(okf&&okl&&!okr) return(3); if(!okf&&!okl&&okr) return(4); if(!okf&&okl&&!okr) return(5); if(okf&&!okl&&!okr) return(6); if(!okf&&!okl&&!okr) return(7); return(7); } int JudgeCanGo(int xxx,int yyy) /* input: location to judeg output: 0 -- can not go 1 -- can go */ { int i,j; if(xxx<=0||xxx>MAXX) return(0); if(yyy<=0||yyy>MAXY) return(0); if(block[xxx][yyy]) return(0); return(1); } int TurnLeft(int ddir) { switch(ddir) { case UP: return(LEFT); case DOWN: return(RIGHT); case LEFT: return(DOWN); case RIGHT: return(UP); default: break; } /* of switch dir */ } int TurnRight(int ddir) { switch(ddir) { case UP: return(RIGHT); case DOWN: return(LEFT); case LEFT: return(UP); case RIGHT: return(DOWN); default: break; } /* of switch dir */ } int TurnBack(int ddir) { switch(ddir) { case UP: return(DOWN); case DOWN: return(UP); case LEFT: return(RIGHT); case RIGHT: return(LEFT); default: break; } /* of switch dir */ }
分享到:
评论

相关推荐

    蚁群算法(ant colony optimization, ACO)c++编程

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型技术。它由Marco Dorigo于1992年在他的博士论文中引入,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。  蚁群...

    蚁群算法的演示程序(ant colony optimization, ACO)

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,一种用来在图中寻找优化路径的机率型技术。

    蚁群算法 C语言程序(已运行)

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法 蚁群算法是一种模拟进化算法,初步的研究表明该算法具有许多优良的性质.针对PID控制器参数优化设计问题,将蚁群...

    aco:蚁群算法(ant colony optimization, ACO)

    aco蚁群算法(ant colony optimization, ACO)

    蚁群算法matlab代码

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。蚁群算法是...

    c#蚁群算法

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。蚁群算法是...

    蚁群算法(ant colony optimization, ACO)

    蚁群算法是一种模拟进化算法,初步的研究表明该算法具有许多优良的性质。

    蚁群算法相关学术论文

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。  蚁群...

    Ant Colony Optimization英文原版

    Ant Colony Optimization英文原版,强烈建议深入学习!

    “蚁群算法”学习包(1) 包括论文原理等

    蚁群系统本来是生物学家为更好揭示昆虫的交互作用而提出的一种昆虫自组织模式。尽管建立这种模式的初衷是为了帮助人们去理解这类昆虫的复杂行为,蚂蚁...ACS)蚁群优化(Ant Colony Optimization,ACO)是该系统的核心内容

    蚁群算法的基本原理

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。蚁群算法是...

    ACO蚁群算法

    ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法ACO蚁群算法

    用于旅行路线规划的 遗传算法(GA) 和蚁群优化 (ACO )_Java

    蚁群算法—Ant Colony Optimization 遗传算法-Genetic Algorithm java包目录结构 src |—— aco.tour.AS 未优化的蚁群算法 |—— aco.tour.MMAS 最大最小蚁群算法 |—— ga.tour.optimized 优化后的遗传算法,结合...

    标准的蚁群算法ACO

    标准的蚁群算法ACO,下载后可以直接编译并运行

    蚁群算法的Matlab程序

    蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文中提出,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。蚁群算法是...

    ACO_TSP蚁群-计算智能-matlab代码

    蚁群算法(Ant Colony Optimization, ACO),又称蚂蚁算法,是一种用来在图中寻找优化路径的机率型算法。它由Marco Dorigo于1992年在他的博士论文“Ant system: optimization by a colony of cooperating agents”中...

    基于Python实现的蚁群算法.zip

    蚁群算法(Ant Colony Optimization, ACO),是一种用来在图中寻找优化路径的机率型算法,对蚂蚁行为进行模仿抽象。在求解旅行推销员问题时,蚂蚁随机从某一城市出发,根据城市间距离与残留信息素浓度按概率选择下一...

    ACO.rar_Colony Optimization_aco-svm_蚁群算法 matlab_铓佺兢 matlab_铓佺兢绠楁

    蚁群算法的通用程序,ant colony optimization.

    基于 Python 实现的蚁群算法【100011503】

    蚁群算法(Ant Colony Optimization, ACO),是一种用来在图中寻找优化路径的机率型算法,对蚂蚁行为进行模仿抽象。在求解旅行推销员问题时,蚂蚁随机从某一城市出发,根据城市间距离与残留信息素浓度按概率选择下一...

    Ant Colony Optimization (ACO)

    Ant Colony Optimization

Global site tag (gtag.js) - Google Analytics