#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<math.h>
#include<time.h>
#include<iostream>
#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<popsize;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<D;j++)
fprintf(p," %e ",pop.P[i].x[j]);
fprintf(p,"\n");
}
fclose(p);
}
void indivial::inition()
{
int i;
for(i=0;i<D;i++)
x[i]=rand_real(0.0,1.0);
}
population::population()
{
int i;
for(i=0;i<popsize;i++)
{
P[i].inition();
}
for(i=0;i<popsize;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<popsize/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<popsize;i++)
{
s=rand_real(0.0,1.0);
if(s<=0.9)
{
for(j=0;j<D;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<D;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<popsize;i++)
{
Q[i].fitness_count();
}
}
void indivial::fitness_count()
{
fintness[0]=x[0];
int i;
double g=1,sum=0;
for(i=1;i<D;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<P_num;i++)
{
R[R_num++]=P[i];
}
for(i=0;i<Q_num;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<len[i];j++)
{
for(k=0;k<F[i][j].is_domied;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<len[i];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<n;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<n;j++)
{
if(m_max<F[i][j].fintness[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<n-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<n;j++)
{
if(m_max<F[i][j].fintness[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<n-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]<f->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]<f->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<f->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<len[i];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<popsize-P_num;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;
}