nsga2
NSGA2学习
步骤:
(1):随机初使化P0,并对P0进行非支配排序,初使化每个个体的RANK值,并对其进行PO值进行非支配排序。
(2):通过二进制锦标赛法从PT中选择个体,并进行交叉和变异操作
(3):通过合并PT和QT产生组合种群
(4):对TR精心非支配排序,并通过排挤和精英保留策略选择N个个体,组成新一代种群。
(5):循环步骤2直到N代。
主要函数伪代码:
(1):初始化种群,并且在此基础上采用二元竞标赛选择,交叉变异操作产生一个新的群体Q,P0和Q0的群体规模均为N
(2):二元竞标选择,对于0-1之间产生的一个随机数,如果其小于0.9则执行杂交炒作,如果大于0.9则执行变异操作,操作如下:
其中C1,C2是产生的两个个体,U是产生的一个随机数,如果U<0.5则带入第一个BU,否则带入第二个。
(2):非支配排序:
1:支配关系:
即对于所有的字目标,P不必Q差,即F1(P)<=F2(Q),F2(P)<=F2(Q),...........并且至少存在一个子目标,使的P比Q好,即F对于1,2,3,4。。。个目标中至少有一个P的值小于Q,则成为P支配Q。
2:非支配的算法描述:
该算法需要保存两个量:
(1).支配个数np。其为在解空间中陪其他个体支配的个数
(2).被支配个体集合SP。其为支配其他个体的集合。
其伪代码:
密度估算:
根据目标函数对所有的个体进行升序排列,从小到大,第一个和最后一个的拥挤距离设为无穷大,第I个个体的拥挤距离为第I个个体的拥挤距离与I+1个和第I-1个个体的的目标函数的差之和与(FM(MAX)与FM(MIN)之差。
其伪代码:
算法主体:
(1):第一步将P和Q并入到R中
(2):产生所有的边界结
(3):R:赋为空集
(4):选择个体到P(T+1)中,直到填满
(5):计算第I层边界集中个体的集聚距离
(6):将第I层边界集选择个体并入到新群体PT
(7):在P(T+1)上执行选择交叉变异操作。
我的代码:
#include#include #include #include #include #include #define D 10//基因维数 #define popsize 100//种群大小 #define genetic 2000 //繁衍代数 #define URAND (rand()/(RAND_MAX+1.0)) #define epx 3.1415926 #define U_S 20 int rand_int(int low,int hight); double rand_real(double low,double high); int cmp1(const void *a,const void *b); int cmp2(const void *a,const void *b); int cmp3(const void *a,const void *b); int temp1[popsize]; int mark[popsize]; using namespace std; class indivial { public: double x[D]; int domi[2*popsize],np,is_domied;//支配集合 void inition(); int rank; double crowding; double fintness[2]; void fitness_count(); }; indivial F[2*popsize][2*popsize]; class population { public: population(); indivial P[popsize];//当代 indivial Q[popsize];//产生的子代 indivial R[2*popsize]; int R_num; void set_p_q(); int P_num; int Q_num; void nodominata_sort();//非支配排序 int len[2*popsize]; int len_f; void crowding_distance(int i); void sorts(int i); void make_new_pop(); void fast_sort_nondominate(); void cal(); void m_printf(); int m_choice(int a,int b); }; bool is_dominated(const indivial &a,const indivial &b); int main() { FILE *p; p=fopen("d:\\1.txt","w+"); srand((unsigned int)(time(0))); population pop; pop.cal(); int i; int j; for(i=0;i ) { fprintf(p,"第%d个个体\n",i); fprintf(p,"%f %f\n",pop.P[i].fintness[0],pop.P[i].fintness[1]); for(j=0;j ) fprintf(p," %e ",pop.P[i].x[j]); fprintf(p,"\n"); } fclose(p); } void indivial::inition() { int i; for(i=0;i ) x[i]=rand_real(0.0,1.0); } population::population() { int i; for(i=0;i ) { P[i].inition(); } for(i=0;i ) { P[i].fitness_count(); } P_num=popsize; Q_num=0; R_num=0; } void population::make_new_pop() { int i,j,x,y,t1,t2,t3; double s,u,b; memset(mark,0,sizeof(mark)); t3=0; while(t3 2) { while(t1=t2=rand_int(0,popsize-1),mark[t1]); while(t1==t2||mark[t2]) {t2=rand_int(0,popsize-1); } t1=m_choice(t1,t2); temp1[t3++]=t1; mark[t1]=1; // printf("__%d___",t1); } //printf("_______________%d__",t3); for(i=0;i ) { s=rand_real(0.0,1.0); if(s<=0.9) { for(j=0;j ) { u=rand_real((0.0+1e-6),(1.0-1e-6)); if(u<=0.5) { b=pow(2*u,1.0/21); } else { b=1.0/pow(2*(1-u),1.0/21); } x=y=rand_int(0,popsize/2-1); while(x==y) y=rand_int(0,popsize/2-1); Q[i].x[j]=1.0/2*((1-b)*P[temp1[x]].x[j]+(1+b)*P[temp1[y]].x[j]); if(Q[i].x[j]<0) Q[i].x[j]=1e-6; else if(Q[i].x[j]>1) Q[i].x[j]=1.0-(1e-6); if(i+1<popsize) { Q[i+1].x[j]=1.0/2*((1+b)*P[temp1[x]].x[j]+(1-b)*P[temp1[y]].x[j]); if(Q[i+1].x[j]<=0) Q[i+1].x[j]=1e-6; else if(Q[i+1].x[j]>1) Q[i+1].x[j]=(1-1e-6); } } i++; } else { for(j=0;j ) { x=rand_int(0,popsize/2-1); u=rand_real(0.0+(1e-6),1.0-(1e-6)); if(u<0.5) { u=pow(2*u,1.0/21)-1; } else { u=1-pow(2*(1-u),1.0/21); } Q[i].x[j]=P[temp1[x]].x[j]+(1.0-0.0)*u; if(Q[i].x[j]<0) Q[i].x[j]=1e-6; else if(Q[i].x[j]>1) Q[i].x[j]=1-(1e-6); } } } Q_num=popsize; for(i=0;i ) { Q[i].fitness_count(); } } void indivial::fitness_count() { fintness[0]=x[0]; int i; double g=1,sum=0; for(i=1;i ) { sum+=x[i]; } sum=9*(sum/(D-1)); g+=sum; fintness[1]=g*(1-sqrt(x[0]/g)); } double rand_real(double low,double high) { double h; h=(high-low)*URAND+low+0.001; if(h>=high) h=high-0.001; return h; } void population::set_p_q() { R_num=0; Q_num=popsize; int i; for(i=0;i ) { R[R_num++]=P[i]; } for(i=0;i ) { R[R_num++]=Q[i]; } for(i=0;i<2*popsize;i++) { R[i].fitness_count(); } } void population::nodominata_sort() { int i,j,k; indivial H[2*popsize]; int h_len=0; for(i=0;i<2*popsize;i++) { R[i].np=0; R[i].is_domied=0; len[i]=0; } for(i=0;i<2*popsize;i++) { for(j=0;j<2*popsize;j++) { if(i!=j) { if(is_dominated(R[i],R[j])) { R[i].domi[R[i].is_domied++]=j; } else if(is_dominated(R[j],R[i])) R[i].np+=1; } } if(R[i].np==0) { len_f=1; F[0][len[0]++]=R[i]; } } i=0; while(len[i]!=0) { h_len=0; for(j=0;j ) { for(k=0;k ) { R[F[i][j].domi[k]].np--; if( R[F[i][j].domi[k]].np==0) {H[h_len++]=R[F[i][j].domi[k]]; R[F[i][j].domi[k]].rank=i+1; } } } i++; len[i]=h_len; if(h_len!=0) { len_f++; for(j=0;j ) { F[i][j]=H[j]; } } } } bool is_dominated(const indivial &a,const indivial &b) { if((a.fintness[0]<=b.fintness[0])&&(a.fintness[1]<=b.fintness[1])) { if((a.fintness[0]==b.fintness[0])&&(a.fintness[1]==b.fintness[1])) return false; return true; } else return false; } void population::crowding_distance(int i) { int n=len[i]; double m_max,m_min; int j; for(j=0;j ) { F[i][j].crowding=0; } F[i][0].crowding=F[i][n-1].crowding=0xffffff; qsort(F[i],n,sizeof(indivial),cmp1); m_max=-0xfffff; m_min=0xfffff; for(j=0;j ) { if(m_max 0]) m_max=F[i][j].fintness[0]; if(m_min>F[i][j].fintness[0]) m_min=F[i][j].fintness[0]; } for(j=1;j 1;j++) { F[i][j].crowding=F[i][j].crowding+(F[i+1][j].fintness[0]-F[i][j-1].fintness[0])/(m_max-m_min); } F[i][0].crowding=F[i][n-1].crowding=0xffffff; qsort(F[i],n,sizeof(indivial),cmp2); m_max=-0xfffff; m_min=0xfffff; for(j=0;j ) { if(m_max 1]) m_max=F[i][j].fintness[1]; if(m_min>F[i][j].fintness[1]) m_min=F[i][j].fintness[1]; } for(j=2;j 1;j++) { F[i][j].crowding=F[i][j].crowding+(F[i+1][j].fintness[1]-F[i][j-1].fintness[1])/(m_max-m_min); } } int cmp1(const void *a,const void *b) { const indivial *e=(const indivial *)a; const indivial *f=(const indivial *)b; if(e->fintness[0]==f->fintness[0]) return 0; else if(e->fintness[0] fintness[0]) return -1; else return 1; } int cmp2(const void *a,const void *b) { const indivial *e=(const indivial *)a; const indivial *f=(const indivial *)b; if(e->fintness[1]==f->fintness[1]) return 0; else if(e->fintness[1] fintness[1]) return -1; else return 1; } void population::sorts(int i) { int n,j; n=len[i]; qsort(F[i],n,sizeof(indivial),cmp3); } int cmp3(const void *a,const void *b) { const indivial *e=(const indivial *)a; const indivial *f=(const indivial *)b; if(e->crowding==f->crowding) return 0; else if(e->crowding crowding) return 1; else return -1; } int rand_int(int low,int hight) { return int((hight-low+1)*URAND)+low; } void population::cal() { int s; int i,j; s=genetic; make_new_pop(); while(s--) { printf("第%d\n",s); set_p_q(); nodominata_sort(); P_num=0; i=0; while(P_num+len[i]<=popsize) { crowding_distance(i); for(j=0;j ) { P[P_num++]=F[i][j]; } i++; if(i>=len_f)break; } if(i<len_f) {crowding_distance(i); sorts(i); } for(j=0;j ) { P[P_num++]=F[i][j]; } make_new_pop(); } printf("S"); } void population::m_printf() { } int population::m_choice(int a,int b) { if(P[a].rank<P[b].rank) return a; else if(P[a].rank==P[b].rank) { if(P[a].crowding>P[b].crowding) return a; else return b; } return b; }