# 遗传算法

#include<bits/stdc++.h>
using namespace std;
typedef struct Chrom{
short bit[6];
int fit;
double rfit,cfit; //分别是百分比和积累;
bool operator<(const Chrom o)const{
return fit > o.fit;
}
}chrom;

void init(chrom *popcur);
int getFit(int x);
int getDec(chrom x);
void select(chrom *popnext);
void pickChroms(chrom *popnext);
void crossover (chrom *popnext);
void mutation (chrom *popnext);
chrom cur[4];
chrom next[4];
int main()
{
int t;
srand((unsigned)time(NULL));
printf("请输入最大迭代次数: ");
scanf("%d",&t);
init(cur);
int max_fit = cur[0].fit;
while(t--){
for(int i = 0; i < 4; ++i){
next[i] = cur[i];
}
printf("\nafter select :\n\n");
pickChroms(next);
printf("after crossover :\n\n");
crossover(next);
printf("\nafter mutation :\n\n");
mutation(next);
for(int i = 0; i < 4; ++i){
cur[i] = next[i];
}
//getchar();
}
int x = 0;
for(int i = 1; i < 4; ++i){
if(cur[i].fit > max_fit){
max_fit = cur[i].fit;
x = getDec(cur[i]);
}
}
printf("\n当x 等于 %d 时， 函数取得最大值为 : %d",x,max_fit);
return 0;

}
void init(chrom *popcur)
{
int value;
double sum = 0;
int i,j;
for(i = 0; i < 4; ++i){
for(j = 0; j < 6; ++j){
popcur[i].bit[j] = rand()%2;
}
value = getDec(popcur[i]);
popcur[i].fit = getFit(value);
sum += popcur[i].fit;
printf("\n popcurrent[%d]=%d%d%d%d%d%d , value = %d, fitness = %d",
i, popcur[i].bit[0], popcur[i].bit[1], popcur[i].bit[2], popcur[i].bit[3], popcur[i].bit[4], popcur[i].bit[5]
,value,popcur[i].fit);
}
for(i = 0; i < 4; ++i){
popcur[i].rfit = popcur[i].fit/sum;
popcur[i].cfit = 0;
}

}

int getFit(int x)
{
return -(x*x) + 5;
}
int getDec(chrom x)
{
int dec= x.bit[5]+x.bit[4]*2 + x.bit[3]*4 + x.bit[2]*8 + x.bit[1]*16;
if(x.bit[0] == 1){
return dec*(-1);
}
return dec;
}
//void select(chrom *popnext)
//	{
//		double sumFit = 0;
//		for(int i = 0; i < 4; ++i){
//			sumFit += popnext[i].fit;
//		}
//		//calculate the relative fitness of each member
//		for(int i = 0; i < 4; ++i){
//			popnext[i].rfit = popnext[i].fit/sumFit;
//		}
//		//calculate the cumulative fitness,即计算积累概率
//		popnext[0].cfit = popnext[0].rfit;
//		for(int i = 1; i < 4; ++i){
//			popnext[i].cfit = popnext[i].rfit+popnext[i-1].cfit;
//			printf("cfit = %.2f ",popnext[i].cfit);
//		}
//		double p = 0;
//		for(int i = 0; i < 4; ++i){
//			p = rand()%10/10;
//			if(p < popnext[0].cfit){
//				popcur[i] = popnext[0];
//			}
//			else{
//				for(int j = 0; j < 4; ++j){
//					if(p >= popnext[j].cfit && p < popnext[j+1].cfit){
//						popcur[i] = popnext[j+1];
//					}
//				}
//			}
//		}
//		for(int i = 0; i < 4; ++i){
//			popnext[i] = popcur[i];
//					printf("\n popcurrent[%d]=%d%d%d%d%d%d fitness = %d cfit = %.2lf",
//			i, popcur[i].bit[0], popcur[i].bit[1], popcur[i].bit[2], popcur[i].bit[3], popcur[i].bit[4], popcur[i].bit[5]
//			,popnext[i].fit,popnext[i].cfit);
//		}
//
//		return ;
//	}
void pickChroms(chrom *popnext)
{
chrom tmp;
int i,j;
sort(popnext,popnext+4);
//		for(int i = 0; i < 4; ++i){
//			printf("%d ",popnext[i].fit);
//		}
for(i = 0;i < 4; i++) {
printf("Select popnext[%d]=%d%d%d%d%d%d    value=%d    fitness = %d",i, popnext[i].bit[0], popnext[i].bit[1], popnext[i].bit[2], popnext[i].bit[3], popnext[i].bit[4], popnext[i].bit[5], getDec(popnext[i]), popnext[i].fit);
printf("\n" );
}

return ;
}
void crossover (chrom *popnext)              // 函数：交叉操作；
{

int random ;
int i ;
random=rand ();                             // 随机产生交叉点；
random=((random %5)+1);                     // 交叉点控制在1到5之间；
for(i = 0;i < random; i++)
{
popnext[2].bit[i] = popnext[0].bit[i];   // child 1 cross over
popnext[3].bit[i] = popnext[1].bit[i];   // child 2 cross over
}

for(i = random; i < 6;i++)                      // crossing the bits beyond the cross point index
{
popnext[2].bit[i]= popnext[1].bit[i];    // child 1 cross over
popnext[3].bit[i]= popnext[0].bit[i];    // chlid 2 cross over
}

for(i = 0;i < 4; i++){
popnext[i].fit= getFit(getDec(popnext[i]));        // 为新个体计算适应度值；
}

for(i =0;i < 4; i++) {
printf("\nCrossOver popnext[%d]=%d%d%d%d%d%d    value=%d    fitness = %d",i, popnext[i].bit[0], popnext[i].bit[1], popnext[i].bit[2], popnext[i].bit[3], popnext[i].bit[4], popnext[i].bit[5], getDec(popnext[i]), popnext[i].fit);
}
return ;
}

void mutation(chrom *popnext)
{
int random,row,col,value;
random = rand()%50;
if(random == 25){
row = rand()%4;
col = rand()%6;
if(popnext[row].bit[col] == 1)
popnext[row].bit[col] = 0;
else if(popnext[row].bit[col] == 0){
popnext[row].bit[col] = 1;
}
popnext[row].fit = getFit(getDec(popnext[row]));
value = getDec(popnext[row]);
}
for(int i = 0; i < 4; ++i){
printf("Mutarion popnext[%d]=%d%d%d%d%d%d    value=%d    fitness = %d",i, popnext[i].bit[0], popnext[i].bit[1], popnext[i].bit[2], popnext[i].bit[3], popnext[i].bit[4], popnext[i].bit[5], getDec(popnext[i]), popnext[i].fit);
printf("\n");
}
}