📄 cmga.cpp
字号:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include <time.h>
#include <windows.h>
#include <vector>
#include <algorithm>
#include "matlib.h"
using namespace std;
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
#define shiyingduchushizhi -6.67e66
#define PI 3.14159265358//9793238462643
#define sl 3 //学习域的大小
#define szhongqun 9//学习种群的大小
#define smaxgen 10//学习次数
#define sR 0.2 //学习半径
#define spm 0.05//学习过程中的变异概率
#define PM 0.1
#define PC 0.1
#define wei 30
#define houdaishuliang 9
#define huanshuliang 3
#define lingyu 9
int jieweishu=30;
int jishuqi=0;
int bianyitongji=0;
int jiaochatongji=0;
int yimintongji=0;
int jingzhengtongji=0;
int jingzhengtongji1=0;
int xuexitongji=0;
unsigned int seed=0; //seed 为种子,要设为全局变量
void mysrand(long int i) //初始化种子
{
seed = -i;
}
long a[1];
vector<double> zuo;//定义左边界数值
vector<double> you;//定义右边界数值
//设置全局变量
struct individual
{
double *chrom; //染色体;
double geti[wei];//变量值
double shiyingdu; //目标函数的值;
double fitness; //变换后的适应度值;
};
struct group
{
int geti[lingyu];
double shiyingdu;
};
class gpji
{
public:
double gpp[wei];
};
gpji gp[houdaishuliang];
group lian[huanshuliang];
int MGA[9][4]={{1,1,1,1},{1,2,2,2},{1,3,3,3},{2,1,2,3},{2,2,3,1},{2,3,1,2},{3,1,3,2},{3,2,1,3},{3,3,2,1}};
bool cmpshiyingdujiang1(const individual &p1,const individual &p2)
{
return ((p1.shiyingdu)>(p2.shiyingdu));
}
int cmpgeti(const void *p1,const void *p2)
{
float i=((individual *)p1)->geti[0];//现在是按照"个体值"排序
float j=((individual *)p2)->geti[0];
return i<j ? -1:(i==j ? 0:1);//现在是按升序牌排列,将1和-1互换后就是按降序排列
}
int cmpshiyingdu(const void *p1,const void *p2)
{
float i=((individual *)p1)->shiyingdu;//现在是按照"个体"排序
float j=((individual *)p2)->shiyingdu;
return i<j ? 1:(i==j ? 0:-1);//现在是按jiang序牌排列,将1和-1互换后就是按sheng序排列
}
int cmpshiyingdu1(const void *p1,const void *p2)
{
float i=((group *)p1)->shiyingdu;//现在是按照"个体"排序
float j=((group *)p2)->shiyingdu;
return i<j ? 1:(i==j ? 0:-1);//现在是按jiang序牌排列,将1和-1互换后就是按sheng序排列
}
double ran1(long *idum)
{
int j;
long k;
static long idum2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*idum <= 0)
{
if (-(*idum) < 1) *idum=1;
else *idum = -(*idum);
idum2=(*idum);
for (j=NTAB+7;j>=0;j--)
{
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0];
}
k=(*idum)/IQ1;
*idum=IA1*(*idum-k*IQ1)-k*IR1;
if (*idum < 0) *idum += IM1;
k=idum2/IQ2;
idum2=IA2*(idum2-k*IQ2)-k*IR2;
if (idum2 < 0) idum2 += IM2;
j=iy/NDIV;
iy=iv[j]-idum2;
iv[j] = *idum;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
double gasdev(long *idum)
{
double ran1(long *idum);
static int iset=0;
static double gset;
double fac,rsq,v1,v2;
if (*idum < 0)
iset=0; //初始化
if (iset == 0)
{
do
{
v1=2.0*ran1(idum)-1.0;
v2=2.0*ran1(idum)-1.0;
rsq=v1*v1+v2*v2;
}while (rsq >= 1.0 || rsq == 0.0);
fac=sqrt(-2.0*log(rsq)/rsq);
gset=v1*fac;
iset=1;
return v2*fac;
}
else
{
iset=0;
return gset;
}
}
class GA
{
public:
GA(int mgen=700,vector<double> z=zuo,vector<double> y=you,int zhongqun=24,int weishu=jieweishu)
{
zuobianjie=z;
youbianjie=y;
maxgen=mgen;
zhongqunshu1=zhongqun;
jiedeweishu=weishu;
}
//函数
void initialize()
{
//shengchenggp();
//cout<<"176"<<endl;
//system("pause");
int i,j;
temp_zuobianjie=zuobianjie;
temp_youbianjie=youbianjie;
lzuobianjie=zuobianjie;
lyoubianjie=youbianjie;
gen=0;//起始代
nowpop=new individual[zhongqunshu1];//当代
//cout<<zhongqunshu1<<endl;
//system("pause");
mysrand(time(0));//随机数种子
a[0]=seed;//随机数种子
//对最优个体的初始化
double **chushihua;
chushihua=new (double *[3e3]);
for(i=0;i<3e3;i++)
{
chushihua[i]=new double[jiedeweishu];
}
for(i=0;i<jiedeweishu;i++)
{
zuiyougeti.geti[i]=0;
}
zuiyougeti.fitness=0;
zuiyougeti.shiyingdu=shiyingduchushizhi;
/*for(i=0;i<3e3;i++)
{
for(int j=0;j<jiedeweishu;j++)
{
chushihua[i][j]=(i+1)*gp[0].gpp[j];
if(chushihua[i][j]>1)
{
chushihua[i][j]=chushihua[i][j]-floor(chushihua[i][j]);
}
}
}*/
vector<individual> hundunzhongqun(3e3);
for(i=0;i<3e3;i++)
{
for(j=0;j<jiedeweishu;j++)
{
hundunzhongqun[i].geti[j]=zuobianjie[j]+(youbianjie[j]-(zuobianjie[j]))*ran1(a);//*chushihua[i][j];//yindao;
}
}
for(i=0;i<3e3;i++)
{
mubiaohanshu(hundunzhongqun[i]);
}
sort(hundunzhongqun.begin(),hundunzhongqun.end(),cmpshiyingdujiang1);//根据适应度将初始种群集按降序进行排列
if(hundunzhongqun[0].shiyingdu<hundunzhongqun[1].shiyingdu)
system("pause");
for(i=0;i<zhongqunshu1;i++)//产生初始种群
{
nowpop[i]=hundunzhongqun[i];
}
jingyingbaoliu(); //精英保留的实现
int bianhao;
for(i=0;i<huanshuliang;i++)
{
for(bianhao=i*(lingyu-1),j=0;j<lingyu;j++,bianhao++)
{
if(bianhao!=zhongqunshu1)
{
lian[i].geti[j]=bianhao;
}
else
{
lian[i].geti[j]=0;
}
}
}
for(i = 0; i < 3e3; i++)
{
delete [] chushihua[i];
}
delete [] chushihua;
}
void jingyingbaoliu() //精英保留的实现
{
individual max=nowpop[0];
int maxhao=0;
for(int i=1;i<zhongqunshu1;i++)
{
if(max.shiyingdu<nowpop[i].shiyingdu)
{
max=nowpop[i];
maxhao=i;
}
}
//xuexi(max);
if(max.shiyingdu>zuiyougeti.shiyingdu)
{
zuiyougeti=max;//如果最优个体的shiyingdu比当代最大的shiyingdu小则用当代的代替之
}
else
//nowpop[maxhao]=zuiyougeti;
nowpop[rnd(0,(zhongqunshu1-1))]=zuiyougeti;//否则的话从当代中随机挑选一个用最优个体代替之
}
void lingyujianjingzheng()
{
for(int i=0;i<huanshuliang;i++)
{
//individual max=nowpop[lian[i].geti[0]];
double he=0;
for(int m=0;m<lingyu;m++)
{
he+=nowpop[lian[i].geti[m]].shiyingdu;
}
//for(int m=1;m<lingyu;m++)
//{
// if(max.shiyingdu<nowpop[lian[i].geti[m]].shiyingdu)
// max=nowpop[lian[i].geti[m]];
//}
lian[i].shiyingdu=he/lingyu;//max.shiyingdu;//;
}
qsort(lian,huanshuliang,sizeof(group),cmpshiyingdu1);
}
virtual void mubiaohanshu(individual &bianliang)//计算shiyingdu
{
jishuqi++;
/*double he=0;
for(int i=0;i<jiedeweishu;i++)
{
he+=-bianliang.geti[i]*sin(sqrt(fabs(bianliang.geti[i])));
}
bianliang.shiyingdu=-he;*/
double he=0;
for(int i=0;i<jiedeweishu;i++)
{
he+=pow(bianliang.geti[i],2)-10*cos(2*PI*bianliang.geti[i])+10;
}
bianliang.shiyingdu=-he;
/*double t=0;
for(int i=0;i<jiedeweishu-1;i++)
t+=100*pow(bianliang.geti[i+1]-pow(bianliang.geti[i],2),2)+pow(bianliang.geti[i]-1,2);
bianliang.shiyingdu=-t;*/
}
void generation()
{
int j=0,i=0;
lingyujianjingzheng();
/*for(i=0;i<huanshuliang;i++)
{
for(j=0;j<lingyu;j++)
{
cout<<lian[i].geti[j]<<" ";
}
cout<<endl;
}
system("pause");*/
for(i=0;i<huanshuliang;i++)
{
jingzheng(i);
}
jingyingbaoliu();
//交叉与变异的实现
//交叉
lingyujianjingzheng();
for(i=0;i<huanshuliang;i++)
{
jiaocha(i);
}
//jingyingbaoliu();
//变异的实现
for(j=0;j<zhongqunshu1;j++)
{
bianyi(nowpop[j]);
}
//精英保留的实现
jingyingbaoliu();
//
//for(j=0;j<zhongqunshu1;j++)
//{
//xuexi(nowpop[j]);
//}
xuexi(zuiyougeti);
}
void crossover(individual parent1,individual parent2,individual &child1,individual &child2)//交叉
{
int j=0,i=0,jj,yiminpanduan=0;
if(ran1(a)<PC)//(flipc(parent1.fitness,parent2.fitness))
{
double pan1=0;
do
{
for(i=0;i<jiedeweishu;i++)
{
pan1=pan1+(parent1.geti[i]-parent2.geti[i]);
}
if(pan1==0)
{
yiminpanduan=1;
for(i=0;i<jiedeweishu;i++)
{
parent2.geti[i]=parent2.geti[i]+0.2*(exp(-10*gen/maxgen)+0.2)*gasdev(a);//
if(parent2.geti[i]<zuobianjie[i])
parent2.geti[i]=zuobianjie[i];
if(parent2.geti[i]>youbianjie[i])
parent2.geti[i]=youbianjie[i];
//while(parent2.geti[i]<zuobianjie[i]||parent2.geti[i]>youbianjie[i]);
}
}
}while(pan1==0);
if(yiminpanduan==1)
{
yimintongji++;
mubiaohanshu(parent2);
}
j=0,i=0,jj;
int fenduan[5];
int inte=0;
fenduan[0]=0;
for(i=1;i<4;i++)
{
inte=rnd(inte+1,jiedeweishu-(5-(i+1)));
fenduan[i]=inte;
}
fenduan[i]=jiedeweishu;
/* for(i=0;i<5;i++)
{
cout<<fenduan[i]<<endl;
}
system("pause");*/
individual houdai[houdaishuliang+2];
vector<double> y(jiedeweishu);
vector<double> z(jiedeweishu);
for(i=0;i<jiedeweishu;i++)
{
z[i]= min(parent1.geti[i],parent2.geti[i]);
y[i]= max(parent1.geti[i],parent2.geti[i]);
}
/*for(i=0;i<jiedeweishu;i++)
{
cout<<z[i]<<" ";
}
cout<<endl;
for(i=0;i<jiedeweishu;i++)
{
cout<<y[i]<<" ";
}
cout<<endl;*/
//system("pause");
for(i=0;i<houdaishuliang;i++)
{
for(j=0;j<4;j++)
{
for(jj=fenduan[j];jj<fenduan[j+1];jj++)
{
houdai[i].geti[jj]=z[jj]+(MGA[i][jj]-1)*(y[jj]-z[jj])/(3-1);//
//cout<<z[jj]<<" ";
/*if(houdai[i].geti[j]<zuobianjie[j])
houdai[i].geti[j]=zuobianjie[j];*/
/*if(houdai[i].geti[jj]>y[jj])
houdai[i].geti[jj]=y[jj];*/
}
}
}
//cout<<endl;
//cout<<jj<<endl;
//system("pause");
houdai[i]=parent1;
houdai[i+1]=parent2;
for(i=0;i<houdaishuliang;i++)
{
jiaochatongji++;
mubiaohanshu(houdai[i]);
}
qsort(houdai,(houdaishuliang+2),sizeof(individual),&cmpshiyingdu);
child1=houdai[0];
child2=houdai[1];
//cout<<child1.shiyingdu<<" "<<child2.shiyingdu<<endl;
//system("pause");
}
else
{
/*for(jj=0;jj<jiedeweishu;jj++)
{
child1.geti[jj]=parent1.geti[jj];
child2.geti[jj]=parent2.geti[jj];
}
child1.shiyingdu=parent1.shiyingdu;
child2.shiyingdu=parent2.shiyingdu;*/
child1=parent1;
child2=parent2;
}
}
void bianyi(individual &child)//变异
{
int bianyipanduan=0;
int jj=0;
for(jj=0;jj<jiedeweishu;jj++)
{
if(ran1(a)<0.1)
{
double alpha;
alpha=ran1(a);
if(alpha>=1/jiedeweishu)
{
bianyipanduan=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -