📄 iga.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 + -