蚁群算法的原理以及实现源代码_第1页
蚁群算法的原理以及实现源代码_第2页
蚁群算法的原理以及实现源代码_第3页
蚁群算法的原理以及实现源代码_第4页
蚁群算法的原理以及实现源代码_第5页
已阅读5页,还剩20页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

蚁群算法ACO(antcolonyoptimization)的原理以及实现源代码ByMinidxer|February1,2008之前说的算法基本上都比较枯燥的(废话,算法都很枯燥……),这次要介绍的蚁群算法(AntColonyAlgorithm)却是一种源于自然现象的算法,也是一种metaheuristic,即与具体问题关系不大的优化算法,也就是它是一种用来在图中寻找优化路径的机率型技术。MarcoDorigo于1992年在他的博士论文中引入,其灵感来源于蚂蚁在寻找食物过程中发现路径的行为。小小的蚂蚁总是能够找到食物,他们具有什么样的智能呢?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就是人工生命、复杂性科学解释的规律!下面就是实现如此复杂性的七条简单规则:1、范围:蚂蚁观察到的范围是一个方格世界,蚂蚁有一个参数为速度半径(一般是3),那么它能观察到的范围就是3*3个方格世界,并且能移动的距离也在这个范围之内。2、环境:蚂蚁所在的环境是一个虚拟的世界,其中有障碍物,有别的蚂蚁,还有信息素,信息素有两种,一种是找到食物的蚂蚁洒下的食物信息素,一种是找到窝的蚂蚁洒下的窝的信息素。每个蚂蚁都仅仅能感知它范围内的环境信息。环境以一定的速率让信息素消失。3、觅食规则:在每只蚂蚁能感知的范围内寻找是否有食物,如果有就直接过去。否则看是否有信息素,并且比较在能感知的范围内哪一点的信息素最多,这样,它就朝信息素多的地方走,并且每只蚂蚁多会以小概率犯错误,从而并不是往信息素最多的点移动。蚂蚁找窝的规则和上面一样,只不过它对窝的信息素做出反应,而对食物信息素没反应。4、移动规则:每只蚂蚁都朝向信息素最多的方向移,并且,当周围没有信息素指引的时候,蚂蚁会按照自己原来运动的方向惯性的运动下去,并且,在运动的方向有一个随机的小的扰动。为了防止蚂蚁原地转圈,它会记住最近刚走过了哪些点,如果发现要走的下一点已经在最近走过了,它就会尽量避开。5、避障规则:如果蚂蚁要移动的方向有障碍物挡住,它会随机的选择另一个方向,并且有信息素指引的话,它会按照觅食的规则行为。7、播撒信息素规则:每只蚂蚁在刚找到食物或者窝的时候撒发的信息素最多,并随着它走远的距离,播撒的信息素越来越少。下面的程序开始运行之后,蚂蚁们开始从窝里出动了,寻找食物;他们会顺着屏幕爬满整个画面,直到找到食物再返回窝。其中,‘F'点表示食物,‘H'表示窝,白色块表示障碍物,‘+'就是蚂蚁了。参数说明:最大信息素:蚂蚁在一开始拥有的信息素总量,越大表示程序在较长一段时间能够存在信息素。信息素消减的速度:随着时间的流逝,已经存在于世界上的信息素会消减,这个数值越大,那么消减的越快。错误概率表示这个蚂蚁不往信息素最大的区域走的概率,越大则表示这个蚂蚁越有创新性。速度半径表示蚂蚁一次能走的最大长度,也表示这个蚂蚁的感知范围。记忆能力表示蚂蚁能记住多少个刚刚走过点的坐标,这个值避免了蚂蚁在本地打转,停滞不前。而这个值越大那么整个系统运行速度就慢,越小则蚂蚁越容易原地转圈。源代码如下(不同编译器可能需做一定修改):/*ant.c*/#defineSPACE0x20#defineESC0x1b#defineANT_CHAR_EMPTY'+'#defineANT_CHAR_FOOD153#defineHOME_CHAR'H'#defineFOOD_CHAR'F'#defineFOOD_CHAR2'f'#defineFOOD_HOME_COLOR12#defineBLOCK_CHAR177#defineMAX_ANT50#defineINI_SPEED3#defineMAXX80#defineMAXY23#defineMAX_FOOD10000#defineTARGET_FOOD200#defineMAX_SMELL5000#defineSMELL_DROP_RATE0.05#defineANT_ERROR_RATE0.02#defineANT_EYESHOT3#defineSMELL_GONE_SPEED50#defineSMELL_GONE_RATE0.05#defineTRACE_REMEMBER50#defineMAX_BLOCK100#defineNULL0#defineUP1#defineDOWN2#defineLEFT3#defineRIGHT4#defineSMELL_TYPE_FOOD0#defineSMELL_TYPE_HOME1#include"stdio.h"#include"conio.h"#include"dos.h"#include"stdlib.h"#include"dos.h"#include"process.h"#include"ctype.h"#include"math.h"voidWorldInitial(void);voidBlockInitial(void);voidCreatBlock(void);voidSaveBlock(void);voidLoadBlock(void);voidHomeFoodInitial(void);voidAntInitial(void);voidWorldChange(void);voidAntMove(void);voidAntOneStep(void);voidDealKey(charkey);voidClearSmellDisp(void);voidDispSmell(inttype);intAntNextDir(intxxx,intyyy,intddir);intGetMaxSmell(inttype,intxxx,intyyy,intddir);intIsTrace(intxxx,intyyy);intMaxLocation(intnum1,intnum2,intnum3);intCanGo(intxxx,intyyy,intddir);intJudgeCanGo(intxxx,intyyy);intTurnLeft(intddir);intTurnRight(intddir);intTurnBack(intddir);intMainTimer(void);charWaitForKey(intsecnum);voidDispPlayTime(void);intTimeUse(void);voidHideCur(void);voidResetCur(void);/* */structHomeStruct{intxxx,yyy;intamount;intTargetFood;}home;structFoodStruct{intxxx,yyy;intamount;}food;structAntStruct{intxxx,yyy;intdir;intspeed;intSpeedTimer;intfood;intSmellAmount[2];inttracex[TRACE_REMEMBER];inttracey[TRACE_REMEMBER];intTracePtr;intIQ;}ant[MAX_ANT];intAntNow;inttimer10ms;structtimestarttime,endtime;intSmell[2][MAXX+1][MAXY+1];intblock[MAXX+1][MAXY+1];intSmellGoneTimer;intSmellDispFlag;intCanFindFood;intHardtoFindPath;/* Main */voidmain(void){charKeyPress;inttu;clrscr();HideCur();WorldInitial();do{timer10ms=MainTimer();if(timer10ms)AntMove();if(timer10ms)WorldChange();tu=TimeUse();if(tu>=60&&!CanFindFood){gotoxy(1,MAXY+1);printf("Cannotfindfood,maybeablockworld.");WaitForKey(10);WorldInitial();}if(tu>=180&&home.amount<100&&!HardtoFindPath){gotoxy(1,MAXY+1);printf("God!itissodifficulttofindapath.");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();}elseif(kbhit()){KeyPress=getch();DealKey(KeyPress);}elseKeyPress=NULL;}while(KeyPress!=ESC);gettime(&endtime);DispPlayTime();WaitForKey(10);clrscr();ResetCur();}/* generalsubprocess */intMainTimer(void)/*output:howmuch10mshavepassfromlasttimecallthisprocess*/{staticintoldhund,oldsec;structtimet;inttimeuse;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;}elsetimeuse=0;return(timeuse);}charWaitForKey(intsecnum)/*funtion:ifhavekeyin,exitimmediately,elsewait'secnum'sencondsthenexitinput:secnum--waitthissenconds,must<3600(1hour)output:keychar,ifnokeyin(exitwhentimeout),returnNULL*/{intsecin,secnow;intminin,minnow;inthourin,hournow;intsecuse;structtimet;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);elsesecuse=secnow-secin;/*countingerrorcheck*/if(secuse<0){gotoxy(1,MAXY+1);printf("Timeconutingerror,anykeytoexit...");getch();exit(3);}}while(secuse<=secnum);return(NULL);}voidDispPlayTime(void){intph,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);",ph,pm,ps);printf("Timeuse:%dhour-%dmin-%dsec}",ph,pm,ps);intTimeUse(void){intph,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)));}voidHideCur(void){unionREGSregs0;regs0.h.ah=1;regs0.h.ch=0x30;regs0.h.cl=0x31;int86(0x10,®s0,®s0);}voidResetCur(void){unionREGSregs0;regs0.h.ah=1;regs0.h.ch=0x06;regs0.h.cl=0x07;int86(0x10,®s0,®s0);}*//* mainANTprograme */voidWorldInitial(void){intk,i,j;randomize();clrscr();HomeFoodInitial();for(AntNow=0;AntNow<MAX_ANT;AntNow++){AntInitial();}/*offorAntNow*/;BlockInitial();for(k=0;k<=1;k++)/*SMELLTYPEFOODandHOME*/for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j]=0;SmellGoneTimer=0;gettime(&starttime);SmellDispFlag=0;CanFindFood=0;HardtoFindPath=0;}voidBlockInitial(void){inti,j;intbn;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)block[i][j]=0;bn=1+MAX_BLOCK/2+random(MAX_BLOCK/2);for(i=0;i<=bn;i++)CreatBlock();}voidCreatBlock(void){intx1,y1,x2,y2;

intdx,dy;inti,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;return;return;if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2)if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2)return;return;for(i=x1;i<=x2;i++)for(j=y1;j<=y2;j++){block[i][j]=1;gotoxy(i,j);putch(BLOCK_CHAR);}}voidSaveBlock(void){FILE*fp_block;charFileNameBlock[20];inti,j;gotoxy(1,MAXY+1);printf("");gotoxy(1,MAXY+1);printf("Savetofile...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0)strcpy(FileNameBlock,"Ant.ant");elsestrcat(FileNameBlock,".ant");if((fp_block=fopen(FileNameBlock,"wb"))==NULL){gotoxy(1,MAXY+1);printf("Creatfile%sfail...",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);}voidLoadBlock(void){FILE*fp_block;charFileNameBlock[20];inti,j,k;gotoxy(1,MAXY+1);printf("");gotoxy(1,MAXY+1);printf("Loadfile...",FileNameBlock);gets(FileNameBlock);if(FileNameBlock[0]==0)strcpy(FileNameBlock,"Ant.ant");elsestrcat(FileNameBlock,".ant");if((fp_block=fopen(FileNameBlock,"rb"))==NULL){gotoxy(1,MAXY+1);printf("Openfile%sfail...",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<MAX_ANT;AntNow++){AntInitial();}/*offorAntNow*/;for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++){block[i][j]=fgetc(fp_block);if(block[i][j]){gotoxy(i,j);putch(BLOCK_CHAR);}}for(k=0;k<=1;k++)/*SMELLTYPEFOODandHOME*/for(i=0;i<=MAXX;i++)for(j=0;j<=MAXY;j++)Smell[k][i][j]=0;SmellGoneTimer=0;gettime(&starttime);SmellDispFlag=0;CanFindFood=0;HardtoFindPath=0;fclose(fp_block);}voidHomeFoodInitial(void){intrandnum;inthomeplace;/*1--homeatleft-up,foodatright-down--homeatleft-down,foodatright-up--homeatright-up,foodatleft-down--homeatright-down,foodatleft-up*/randnum=random(100);if(randnum<25)homeplace=1;elseif(randnum>=25&&randnum<50)homeplace=2;elseif(randnum>=50&&randnum<75)homeplace=3;elsehomeplace=4;switch(homeplace){case1: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;case2: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;case3: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;case4: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;/*datacorrectnesscheck*/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("Worldinitialfail,anykeytoexit...");getch();exit(2);}gotoxy(home.xxx,home.yyy);putch(HOME_CHAR);gotoxy(food.xxx,food.yyy);putch(FOOD_CHAR);}voidAntInitial(void)/*initialant[AntNow]*/{intrandnum;inti;ant[AntNow].xxx=home.xxx;ant[AntNow].yyy=home.yyy;randnum=random(100);if(randnum<25)ant[AntNow].dir=UP;elseif(randnum>=25&&randnum<50)ant[AntNow].dir=DOWN;elseif(randnum>=50&&randnum<75)ant[AntNow].dir=LEFT;elseant[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;/*asepecailant*/if(AntNow==0)ant[AntNow].speed=INI_SPEED;}voidWorldChange(void){intk,i,j;intsmelldisp;SmellGoneTimer+=timer10ms;if(SmellGoneTimer>=SMELL_GONE_SPEED){SmellGoneTimer=0;for(k=0;k<=1;k++)/*SMELLTYPEFOODandHOME*/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'toverwriteFoodandHome*/;else{if(smelldisp>9)putch('#');elseputch(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);}}}}/*ofonelocation*/}/*oftimetochangetheworld*/}/*ofworldchange*/voidAntMove(void)intantx,anty;intsmelltodrop,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);/*ant0isasepecailant,usedifferentcolor*/if(AntNow==0)textcolor(0xd);if(ant[AntNow].food)putch(ANT_CHAR_FOOD);elseputch(ANT_CHAR_EMPTY);if(AntNow==0)textcolor(0x7);/*remembertrace*/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;/*dropsmell*/antx=ant[AntNow].xxx;anty=ant[AntNow].yyy;if(ant[AntNow].food)/*havefood,lookingforhome*/{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;/*elseSmell[...]=smellnow*/ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]-=smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]<0)ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]=0;}/*ofhavesmelltodrop*/}/*ofhavefood*/else/*nofood,lookingforfood*/{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;/*elseSmell[...]=smellnow*/ant[AntNow].SmellAmount[SMELL_TYPE_HOME]-=smelltodrop;if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]<0)ant[AntNow].SmellAmount[SMELL_TYPE_HOME]=0;}/*ofhavesmelltodrop*/}}/*oftimetogo*//*elsenotgo*/}/*offorAntNow*/textcolor(FOOD_HOME_COLOR);gotoxy(home.xxx,home.yyy);putch(HOME_CHAR);gotoxy(food.xxx,food.yyy);if(food.amount>0)putch(FOOD_CHAR);elseputch(FOOD_CHAR2);textcolor(7);gotoxy(1,MAXY+1);printf("Food%d,Home%d",food.amount,home.amount);}voidAntOneStep(void){intddir,tttx,ttty;inti;ddir=ant[AntNow].dir;tttx=ant[AntNow].xxx;ttty=ant[AntNow].yyy;ddir=AntNextDir(tttx,ttty,ddir);switch(ddir){caseUP:ttty--;break;caseDOWN:ttty++;break;caseLEFT:tttx--;break;caseRIGHT:tttx++;break;default:break;}/*ofswitchdir*/ant[AntNow].dir=ddir;ant[AntNow].xxx=tttx;ant[AntNow].yyy=ttty;if(ant[AntNow].food)/*thisantcarrywithfood,searchforhome*/{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;}/*ofsearchforhome*/else/*thisantisempty,searchforfood*/{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;}/*ofstillhavefood*/}if(tttx==home.xxx&&ttty==home.yyy)ant[AntNow].SmellAmount[SMELL_TYPE_HOME]=MAX_SMELL;}/*ofsearchforfood*/}voidDealKey(charkey){inti;switch(key){case'p':gettime(&endtime);DispPlayTime();getch();gotoxy(1,MAXY+1);for(i=1;i<=MAXX-1;i++)putch(SPACE);break;case't':if(SmellDispFlag){SmellDispFlag=0;ClearSmellDisp();}elseSmellDispFlag=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<=MAXX-1;i++)putch(SPACE);}/*ofswitch*/}voidClearSmellDisp(void){intk,i,j;for(k=0;k<=1;k++)/*SMELLTYPEFOODandHOME*/for(i=1;i<=MAXX;i++)for(j=1;j<=MAXY;j++){if(Smell[k][i][j]){gotoxy(i,j);putch(SPACE);}}/*ofonelocation*/}voidDispSmell(inttype)/*input:0--Onlydisplayfoodsmell--Onlydisplayhomesmell--Displaybothfoodandhomesmell*/{intk,i,j;intfromk,tok;intsmelldisp;switch(type){case0:fromk=0;tok=0;break;case1:fromk=1;tok=1;break;case2:fromk=0;tok=1;break;default:fromk=0;tok=1;break;}SmellGoneTimer=0;for(k=fromk;k<=tok;k++)/*SMELLTYPEFOODandHOME*/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;gotoxy(i,j);if(i!=food.xxx||j!=food.yyy){if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy))/*don'toverwriteFoodandHome*/;else{if(smelldisp>9)putch('#');elseputch(smelldisp+'0');}}}}/*ofonelocation*/}intAntNextDir(intxxx,intyyy,intddir){intrandnum;inttestdir;intCanGoState;intcangof,cangol,cangor;intmsf,msl,msr,maxms;inttype;CanGoState=CanGo(xxx,yyy,ddir);if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6)cangof=1;elsecangof=0;if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5)cangol=1;elsecangol=0;if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4)cangor=1;elsecangor=0;if(ant[AntNow].food)type=SMELL_TYPE_HOME;elsetype=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-msfisMAX2-mslisMAX-msrisMAX0-all3numberis0*/testdir=NULL;switch(maxms){case0:/*allis0,keeptestdir=NULL,randomselectdir*/break;case1:if(cangof)testdir=ddir;elseif(msl>msr)if(cangol)testdir=TurnLeft(ddir);elseif(cangor)testdir=TurnRight(ddir);break;case2:if(cangol)testdir=TurnLeft(ddir);elseif(msf>msr)if(cangof)testdir=ddir;elseif(cangor)testdir=TurnRight(ddir);break;case3:if(cangor)testdir=TurnRight(ddir);elseif(msf>msl)if(cangof)testdir=ddir;elseif(cangol)testdir=TurnLeft(ddir);break;default:break;}/*ofmaxms*/randnum=random(1000);if(randnum<SMELL_DROP_RATE*1000||testdir==NULL)/*1.iftestdir=NULL,meanscannotfindthemaxsmellorthedirtomaxsmellcannotgothenrandomselectdir2.ifanterror,don'tfollowthesmell,randomselectdir*/{randnum=random(100);switch(CanGoState){case0:if(randnum<90)testdir=ddir;elseif(randnum>=90&&randnum<95)testdir=TurnLeft(ddir);elsetestdir=TurnRight(ddir);break;case1:if(randnum<50)testdir=TurnLeft(ddir);elsetestdir=TurnRight(ddir);break;case2:if(randnum<90)testdir=ddir;elsetestdir=TurnRight(ddir);break;case3:if(randnum<90)testdir=ddir;elsetestdir=TurnLeft(ddir);break;case4:testdir=TurnRight(ddir);break;case5:testdir=TurnLeft(ddir);break;case6:testdir=ddir;break;case7:testdir=TurnBack(ddir);break;default:testdir=TurnBack(ddir);}/*ofcangostate*/}return(testdir);}intGetMaxSmell(inttype,intxxx,intyyy,intddir){inti,j;intms;/*MAXsmell*/ms=0;switch(ddir){caseUP: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&&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;caseDOWN:for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++)for(j=yyy+l;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;caseLEFT:for(i=xxx-ANT_EYESHOT;i<xxx;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;caseRIGHT:for(i=xxx+1;i<=xxx+ANT_EYESH0T;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);}intIsTrace(intxxx,intyyy){inti;for(i=0;i<TRACE_REMEMBER;i++)if(ant[AntNow].tracex[i]==xxx&&ant[AntNow].tracey[i]==yyy)return(1);return(0

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论