⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ant_system_alogrithm.cpp

📁 c写的遗传和蚁群融合用于tsp的代码 很好的写论文的材料
💻 CPP
字号:
// Ant_System_Alogrithm.cpp: implementation of the CAnt_System_Alogrithm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ASA.h"
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#include "Ant_System_Alogrithm.h"
#include "GamblingPad.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAnt_System_Alogrithm::CAnt_System_Alogrithm()
{

}

//功能:初始化环境和蚁群信息
void CAnt_System_Alogrithm::init()
{
   FILE  *fp;
   if((fp=fopen("el51.txt","r"))==NULL)
   {
	::AfxMessageBox("cannot open kroa100 file");
    exit(0);
   }
   int i,j,x,y;
   for(j=0; j<CITY_NUM; j++)
   {
      fscanf(fp,"%d%d%d",&i,&x,&y);
      citypos[i-1].x=x;
      citypos[i-1].y=y;
   }
   fclose(fp);
    
   //初始化城市距离dis_city[i][j],η[i][j],г[i][j]
   for(i=0; i<CITY_NUM-1; i++)
   {
	  dis_city[i][i] = 0;
	  yita[i][i]=1;
	  tao[i][i]=C+0.5;
      for(j=i+1; j<CITY_NUM; j++)
	  { 
	    	dis_city[i][j]  =(int)(  sqrt(    pow(citypos[i].x-citypos[j].x,2 ) 
				                             +pow(citypos[i].y-citypos[j].y, 2)  ) 	+0.5 
								   );
	        dis_city[j][i]  =dis_city[i][j];
			yita[i][j]=yita[j][i]=1.0/dis_city[i][j];
			tao [i][j]=tao [j][i]=C+0.5;
	  }
   }
   
   //初始化每只蚂蚁信息
   ::srand( (unsigned)time( NULL ) );
   for (i=0; i<ANT_NUM; i++)
   {
	   Ant[i].len=0;      //当前累积长度为0
	   Ant[i].tailpos=0;  //路径末尾指示器为0
	   Ant[i].curpos = rand()%CITY_NUM;   //当前位置随机设定
	   //路径信息为空,所有顶点都未访问
	   for (j=0; j<CITY_NUM+1; j++)
	   {
		   Ant[i].path[j]=-1;
		   Ant[i].flag[j]=FALSE;
	   }
	   //将当前位置加入路径信息
	   Ant[i].path[Ant[i].tailpos++]=Ant[i].curpos;
	   Ant[i].flag[Ant[i].curpos]=TRUE;
   }
   	bestresult.len=999999; //初始化最优解长度
}

//功能:执行蚁群算法
void CAnt_System_Alogrithm::run()
{
	int i,k;
	int nc;
	int minlen=10000000;
	int    NOofbestAnt =0;

	//反复执行NCMAX次训练
	for (nc=0; nc<NCMAX+50; nc++)
	{
		//每只蚂蚁都遍历城市一遍
		for (k=0; k<ANT_NUM; k++) 
		{
     		findPath(k);
			if (Ant[k].len<minlen)
			{
				minlen=Ant[k].len;
                NOofbestAnt=k;
			}
		}

		//与最优解比较,更新最优解
		if (Ant[NOofbestAnt].len<bestresult.len) bestresult=Ant[NOofbestAnt];

		//更新信息素
        updateTao();

		//初始化每只蚂蚁的信息,准备下一次循环
		for (k=0; k<ANT_NUM; k++)
		{
	        Ant[k].len=0;               //当前累积长度为0
	        Ant[k].tailpos=0;           //路径末尾指示器为0
		    //Ant[k].curpos = rand()%CITY_NUM;   //当前位置随机设定
			for (i=0; i<CITY_NUM; i++)  //访问标志清空
				Ant[k].flag[i]=FALSE;
			
			//将当前位置加入路径信息
			Ant[k].path[Ant[k].tailpos++]=Ant[k].curpos;
	        Ant[k].flag[Ant[k].curpos]=TRUE;
		}

	}//end of for (nc=0; nc<NCMAX; nc++)
}


void CAnt_System_Alogrithm::updateTao()
{
	int i,j,k;
	double temp;
	double tempdeltatao[ANT_NUM][CITY_NUM][CITY_NUM];
	double deltatao[CITY_NUM][CITY_NUM];
	//初始化tempdeltatao[k][i][j]
	for (k=0; k<ANT_NUM; k++)
		for (i=0; i<CITY_NUM; i++)
			for (j=0; j<CITY_NUM; j++)
				tempdeltatao[k][i][j]=0;

	//初始化deltatao[i][j]
	for (i=0; i<CITY_NUM; i++)
		for (j=0; j<CITY_NUM; j++)
			deltatao[i][j]=0;

	//计算tempdeltatao[k][i][j]
	for (k=0; k<ANT_NUM; k++)
	{
		for (int cnt=0; cnt<Ant[k].tailpos; cnt++)
		{
			temp=tempdeltatao[k][ Ant[k].path[cnt] ][ Ant[k].path[cnt+1] ]=Q/Ant[k].len;
		    tempdeltatao[k][ Ant[k].path[cnt+1] ][ Ant[k].path[cnt] ]=temp;
		}		
	}

	//计算delta г[i][j]
	for (i=0; i<CITY_NUM; i++)
		for (j=0; j<CITY_NUM; j++)
			for (k=0; k<ANT_NUM; k++)
				deltatao[i][j]+=tempdeltatao[k][i][j];

	//更新г[i][j]
	for (i=0; i<CITY_NUM; i++)
		for (j=0; j<CITY_NUM; j++)
			tao[i][j]=ROU*tao[i][j]+(1-ROU)*deltatao[i][j];
}

//功能:对第k只蚂蚁所得路径进行二次交叉
void CAnt_System_Alogrithm::intercross(int k)
{
	int i=1;
	int j=1;
	int temp;
	//随机生成位置i,j
	while(TRUE)
	{
		i=rand()%(CITY_NUM-2)+1;
	    j=rand()%(CITY_NUM-2)+1;
		if (i>j)
		{
			temp=i;i=j;j=temp;
		}
		if (i+2<=j) break;
	}

    int formerlen,latterlen;
	formerlen = dis_city[Ant[k].path[i-1]][Ant[k].path[i]]+dis_city[Ant[k].path[i]][Ant[k].path[i+1]]
		       +dis_city[Ant[k].path[j-1]][Ant[k].path[j]]+dis_city[Ant[k].path[j]][Ant[k].path[j+1]];

	latterlen = dis_city[Ant[k].path[i-1]][Ant[k].path[j]]+dis_city[Ant[k].path[j]][Ant[k].path[i+1]]
		       +dis_city[Ant[k].path[j-1]][Ant[k].path[i]]+dis_city[Ant[k].path[i]][Ant[k].path[j+1]];
	if (latterlen<formerlen)
	{
		Ant[k].len=Ant[k].len-formerlen+latterlen;
		temp=Ant[k].path[i];
		Ant[k].path[i]=Ant[k].path[j];
		Ant[k].path[j]=temp;
	}
}

//功能:第i只蚂蚁遍历CITY_NUM个城市得到一条路径
void CAnt_System_Alogrithm::findPath(int i)
{
	GamblingPad gmbpad;//将转移概率放入赌盘
	int j;   //记录下一个城市的序号
	for (int cnt=0; cnt<CITY_NUM-1; cnt++)//循环CITY_NUM-1次
	{
        getTransferProbability(i,gmbpad);	
		j = gmbpad.getCity();   //用赌盘法计算下一个城市
		//更新蚂蚁路径信息
	    Ant[i].flag[j]  =TRUE;                          //标记为已访问过的城市
		Ant[i].len     += dis_city[Ant[i].curpos][j];   //累积走过的路径长度
		Ant[i].curpos   =j;                             //当前位置移到j城市
		Ant[i].path[Ant[i].tailpos++]=j;                //将城市序号j纳入蚂蚁路径
		gmbpad.citycnt=0;
		gmbpad.type=gmbpad.YUANSHIPRO;
	}

	//蚂蚁的最后一步是回到原点
	Ant[i].path[Ant[i].tailpos] = Ant[i].path[0];
	Ant[i].len                 += dis_city[Ant[i].curpos][Ant[i].path[0]];
	Ant[i].curpos                  =Ant[i].path[0];

	//对所得路径进行二次交叉
    intercross(i);
     
}

//功能:计算第i只蚂蚁从当前位置到其余未访问节点的转移概率,结果放入赌盘
void CAnt_System_Alogrithm::getTransferProbability(int i,GamblingPad& gmbpad)
{
	int j;
	double total_tao_yita=0;
	double tao_yita[CITY_NUM]; 
	for (j=0; j<CITY_NUM; j++)
	{
		if (Ant[i].flag[j]==FALSE/*表示未访问过*/)
		{
			tao_yita[gmbpad.citycnt] = tao[Ant[i].curpos][j]
				                       *pow(yita[Ant[i].curpos][j],BETA);
		    total_tao_yita += tao_yita[gmbpad.citycnt];
			gmbpad.city[gmbpad.citycnt]=j;  //记录城市序号
			gmbpad.citycnt++;               //城市数加一
		}
	}

	for (j=0; j<gmbpad.citycnt; j++)
		gmbpad.pr[j]=tao_yita[j]/total_tao_yita;//得到去每个未访问城市的转移概率
}

//功能:显示结果
void CAnt_System_Alogrithm::displayResult(CDC* pDC)
{
	CString str;
	CPoint  point(100,60);
	str.Format("最优长度=%d",bestresult.len);
	pDC->TextOut(0,0,str);
	pDC->TextOut(0,30,"路径序列:");

	pDC->MoveTo(citypos[bestresult.path[0]].x*5,citypos[bestresult.path[0]].y*5);
	for (int i=0; i<=bestresult.tailpos; i++)
	{
		pDC->LineTo(citypos[bestresult.path[i]].x*5,citypos[bestresult.path[i]].y*5);
		point.x =100 + (i%10)*50; point.y = 60 + (i/10)*30;
		str.Format("%d",bestresult.path[i]);
		pDC->TextOut(point.x,point.y,str);
	}
}

CAnt_System_Alogrithm::~CAnt_System_Alogrithm()
{

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -