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

📄 iga.cpp

📁 一个函数寻优的免疫遗传算法
💻 CPP
字号:
// IGA.cpp: implementation of the CIGA class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ImmueGA.h"
#include "IGA.h"
#include "math.h"

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

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

CIGA::CIGA()
{	srand((unsigned)time(NULL)); //产生种子
	for(int i=0;i<SUM;i++)
		for(int j=0;j<VAR;j++)
			AntiBase[i].AntiGene[j]= AverageRandom(TL,TH);	 //在[a,b]之间
}

CIGA::~CIGA()
{
}

double CIGA::DoIGA(CAntiCell *ac)
{	double oldfit=0;
	srand((unsigned)time(NULL)); //产生种子
	for(int i=0;i<LOOPNUM;i++)
	{	ResortAntiBase();
		if(i==0)	InitMemory();	//i>0后才更新记忆库
		if(i>0)	//第1次不用添加
		{	AddMemory();
			GenerateNew();
			AddNew();
		}
		if(i>0)		UpdateMemory();
		CalAntiC();
/*		if(fabs(oldfit-GetMemoryFit())<delt)//亲和度趋于稳定时结束
		{	ResortMB();
			*ac=MB[0];
			return (10/ac->Fitness-LB);
		}
		oldfit=GetMemoryFit();
*/		Updatesp();	//抗体激励和抑制
		Genetic();	//进行遗传操作
	}
	ResortMB();	//选择记忆库中的最优抗体
	*ac=MB[0];
	return (10/ac->Fitness-LB);//
}

/*待函数是y=min fun(x0,x1,x2,x3)=
(0.7*x0*(2*x1-1)*x3+1.2*x2)/(1+x0*x0+x1*x1)+sin(0.5*x0*x1)
亲和度*/
void CIGA::fun(CAntiCell *ac)//保守的下界估计
{	ac->Fitness=10/(LB+(0.7*ac->AntiGene[0]*(2*ac->AntiGene[1]-1)*ac->AntiGene[3]+
				 1.2*ac->AntiGene[2])/(1+ac->AntiGene[0]*ac->AntiGene[0]+
				 ac->AntiGene[1]*ac->AntiGene[1])
				 +sin(0.5*ac->AntiGene[0]*ac->AntiGene[1]));
}

void CIGA::GenerateNew()//
{	srand((unsigned)time(NULL)); //产生种子
	for(int i=0;i<NEWSUM;i++)
		for(int j=0;j<VAR;j++)
			NB[i].AntiGene[j]= AverageRandom(TL,TH);	 //在[a,b]之间
}

double CIGA::AverageRandom(double min, double max)
{	int minInteger = (int)(min*10000);
	int maxInteger = (int)(max*10000);
	int randInteger = rand()*rand();
	int diffInteger = maxInteger - minInteger;
	int resultInteger = randInteger % diffInteger + minInteger;
	return resultInteger/10000.0;
}
void CIGA::AddMemory()//添加到总细胞
{	int i,j,k;
	ResortAntiBase();
	for(i=0;i<MSUM;i++)//MB[i]
		for(j=0;j<2*MSUM;j++)//AntiBase[j]
		{	if(fabs(MB[i].Fitness-AntiBase[j].Fitness)<0.1*delt)
				break;
			if(MB[i].Fitness>AntiBase[j].Fitness)	//MB[i]加入到总免疫细胞库
			{	for(k=SUM-1;k>j;k--)				//右移
					AntiBase[k]=AntiBase[k-1];
				AntiBase[j]=MB[i];
				break;
			}
		}
}

void CIGA::AddNew()	//添加到总细胞末尾
{	ResortAntiBase();
	for(int i=0;i<NEWSUM;i++)	
		AntiBase[SUM-NEWSUM+i]=NB[i];
}
void CIGA::ResortAntiBase()
{	int i,j;
	CAntiCell tmp;
	for(i=0;i<SUM;i++)
		fun(AntiBase+i);
	for(i=0;i<SUM;i++)
		for(j=i;j<SUM;j++)//按亲和度从大到小排序
			if(AntiBase[i].Fitness<AntiBase[j].Fitness)//swap
			{	tmp=AntiBase[i];
				AntiBase[i]=AntiBase[j];
				AntiBase[j]=tmp;
			}
}

void CIGA::ResortMB()
{	int i,j;
	CAntiCell tmp;
	for(i=0;i<MSUM;i++)
		fun(MB+i);
	for(i=0;i<MSUM;i++)
		for(j=i;j<MSUM;j++)
			if(MB[i].Fitness<MB[j].Fitness)
			{	tmp=MB[i];
				MB[i]=MB[j];
				MB[j]=tmp;
			}
}

void CIGA::UpdateMemory()//更新记忆库
{	int i,j,k;
	ResortAntiBase();
	ResortMB();
	for(i=0;i<MSUM;i++)//AntiBase[i]
		for(j=0;j<MSUM;j++)//MB[j]
		{	if(fabs(AntiBase[i].Fitness-MB[j].Fitness)<0.1*delt)
				break;
			if(AntiBase[i].Fitness>MB[j].Fitness)//AntiBase[i]加入记忆库
			{	for(k=MSUM-1;k>j;k--)//右移
					MB[k]=MB[k-1];
				MB[j]=AntiBase[i];
				break;
			}
		}
}

void CIGA::CalAntiC()//计算浓度
{	int i,j,k;
	int genenum,num;
	for(i=0;i<SUM;i++)	//计算总免疫细胞库的细胞浓度
	{	num=0;
		for(j=0;j<SUM;j++)
		{	genenum=0;
			for(k=0;k<VAR;k++)
				if(fabs(AntiBase[i].AntiGene[k]-AntiBase[j].AntiGene[k])<10*delt)
					genenum++;
			if(genenum>=VAR-1)	num++;//相似
		}
		AntiBase[i].Concentration=num*10.0/SUM;
	}
}

void CIGA::CalMemoryC()
{	int i,j,k;
	int genenum,num;
	for(i=0;i<MSUM;i++)	//计算记忆免疫细胞库的细胞浓度
	{	num=0;
		for(j=0;j<MSUM;j++)
		{	genenum=0;
			for(k=0;k<VAR;k++)
				if(fabs(MB[i].AntiGene[k]-MB[j].AntiGene[k])<5*delt)
					genenum++;
			if(genenum>=VAR-1)	num++;//相似
		}
		MB[i].Concentration=num*1.0/SUM;
	}
}

double CIGA::GetMemoryFit()
{	double sumfit=0;
	for(int j=0;j<MSUM;j++)
		sumfit+=MB[j].Fitness;
	return sumfit;
}

void CIGA::Updatesp()//抗体的激励和抑制
{	int i,j;
	double fave,cfave,sumc=0,sumfit=0;
	CalAntiC();
	ResortAntiBase();
	for(j=0;j<SUM;j++)
	{	sumfit+=AntiBase[j].Fitness;
		sumc+=AntiBase[j].Concentration;
	}
	fave=sumfit/SUM;	//计算总免疫细胞库的平均亲和度
	cfave=sumc/SUM;		//计算总免疫细胞库的平均细胞浓度
	for(i=0;i<SUM;i++)	//用浓度调整选择概率
		if(AntiBase[i].Fitness>fave)
			AntiBase[i].sp=(1+beita*(cfave-AntiBase[i].Concentration)
			/(cfave+AntiBase[i].Concentration))*AntiBase[i].Fitness;
		else 
			AntiBase[i].sp=AntiBase[i].Fitness;
}

void CIGA::Genetic()//交叉和变异
{	int i,j;
	int i1,i2;
	CAntiCell tmpAnti[SUM];
	double psum=0;
	for(j=0;j<SUM;j++)	psum+=AntiBase[j].sp;
	for(i=0;i<SUM;i++,i++)
	{	SelectAnti(psum,i1,i2);
		CrossOver(i1,i2,tmpAnti+i,tmpAnti+i+1);
		Mutation(tmpAnti+i,tmpAnti+i+1);
	}
	for(i=0;i<SUM;i++,i++)
		AntiBase[i]=tmpAnti[i];
	ResortAntiBase();//just for dubug
}

void CIGA::SelectAnti(double psum,int&i1,int&i2)
{	double r1,r2,tmpsum=0;
	r1=AverageRandom(0,1);
	r2=AverageRandom(0,1);
	for(i1=0;i1<SUM && tmpsum<r1;i1++)//轮赌法
		tmpsum+=AntiBase[i1].sp/psum;
	tmpsum=0;
	for(i2=0;i2<SUM && tmpsum<r2;i2++)//轮赌法
		tmpsum+=AntiBase[i2].sp/psum;
}

void CIGA::CrossOver(int i1, int i2, CAntiCell *c1, CAntiCell *c2)
{	int i,k;
	double r,tmpsum=0;
//	srand((unsigned)time(NULL)); //产生种子
	r=AverageRandom(0,1);
	if(r<1-PC)	//直接克隆
	{	*c1=AntiBase[i1];
		*c2=AntiBase[i2];
	}
	else
	{	k=rand()%4;	//产生交叉位置
		for(i=0;i<k;i++)//
		{	c1->AntiGene[i]=AntiBase[i1].AntiGene[i];
			c2->AntiGene[i]=AntiBase[i2].AntiGene[i];
		}
		for(i=k;i<VAR;i++)//
		{	c1->AntiGene[i]=AntiBase[i2].AntiGene[i];
			c2->AntiGene[i]=AntiBase[i1].AntiGene[i];
		}
	}
}

void CIGA::Mutation(CAntiCell *ac1,CAntiCell *ac2)
{	int k;
	double r1,r2,anti;
//	srand((unsigned)time(NULL)); //产生种子
	r1=AverageRandom(0,1);
	r2=AverageRandom(0,1);
	if(r1>1-PM)	//判断是否产生变异
	{	anti=AverageRandom(TL,TH);
		k=rand()%VAR;	//产生交叉位置
		ac1->AntiGene[k]=anti;
	}
	if(r2>1-PM)	//判断是否产生变异
	{	anti=AverageRandom(TL,TH);
		k=rand()%VAR;	//产生交叉位置
		ac2->AntiGene[k]=anti;
	}
}

void CIGA::InitMemory()
{	for(int i=0;i<MSUM;i++)
		MB[i]=AntiBase[i];
}

⌨️ 快捷键说明

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