📄 bsga.cpp
字号:
/*******************************************
* 毕设遗传算法程序 *
* programmed by 朱健华 *
*******************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
/*******************************************
* the defination of constant *
*******************************************/
#define POPSIZE 200//种群数量
#define pi 3.14
/*******************************************
* 用户数据定义 *
*******************************************/
#define CHROMLENGTH 120
int PopSize =200;//种群规模
int MaxGeneration =50000;//终止进化代数
double Pc =0.60;//交叉概率
double Pm =0.03;//变异概率
/*******************************************
* 数据类型定义 *
*******************************************/
struct individual //个体数据定义
{
char chrom[CHROMLENGTH+1];//个体字符串编码
double f1,f2,a1,a2,k1,k2;
double value;//个体表现型值
double fitness;//个体适应度值
};
/*******************************************
* 定义全局变量 *
*******************************************/
int generation;//进化代数
int best_index;//最佳个体索引
int worst_index;//最差个体索引
struct individual bestindividual;//当前代最佳个体
struct individual worstindividual;//当前代最差个体
struct individual currentbest;//迄今为止的最好个体
struct individual population[POPSIZE];//种群
FILE *galog;
/*******************************************
* 函数原型声明 *
*******************************************/
void GenerateInitialPopulation(void);//产生初始种群
void initreport(void);
void GenerateNextPopulation(void);//产生下一代群体
void EvaluatePopulation(void);//评价函数
double DecodeChromosome1(char *,int,int);//电阻值对应染色体解码
double DecodeChromosome2(char *,int,int);//电容值对应染色体解码
void CaculateObjectValue(void);//计算个体表现型值
void CaculateFitnessValue(void);//计算适应度
void FindBestAndWorstIndividual(void);//寻找最佳和最差个体
void PerformEvolution(void);//进行评价操作
void SelectionOperator(void);//选择操作
void CrossoverOperator(void);//交叉操作
void MutationOperator(void);//变异操作
void OutputTextReport(void);
void CaculateDeviceValue(char *);
void finalreport(void);
/********************************************
* 主程序 *
********************************************/
void main(void)
{
srand( (unsigned)time( NULL ) );
if ((galog = fopen("galog.txt","w"))==NULL){exit(1);}
generation=0;
GenerateInitialPopulation();
EvaluatePopulation();
while(generation<MaxGeneration)
{
generation++;
GenerateNextPopulation();
EvaluatePopulation();
PerformEvolution();
OutputTextReport();
}
finalreport();
}
/********************************************
* 产生初始群体 *
********************************************/
void GenerateInitialPopulation(void)
{
int i,j;
initreport();
for(i=0;i<PopSize;i++)
{
for(j=0;j<CHROMLENGTH;j++)
{population[i].chrom[j]=(rand()%10<5)?'0':'1';}
population[i].chrom[CHROMLENGTH]='\0';
}
}
/********************************************
* 初始参数输出 *
********************************************/
void initreport()
{
fprintf(galog," 基本遗传算法参数\n");
fprintf(galog," -------------------------------------------------\n");
fprintf(galog," 种群大小(PopSize) = %d\n",PopSize);
fprintf(galog," 染色体长度(CHROMLENGTH) = %d\n",CHROMLENGTH);
fprintf(galog," 最大进化代数(MaxGeneration) = %d\n",MaxGeneration);
fprintf(galog," 交叉概率(pcross) = %f\n",Pc);
fprintf(galog," 变异概率(pmutation) = %f\n",Pm);
fprintf(galog," -------------------------------------------------\n");
}
/*********************************************
* 产生下一代 *
*********************************************/
void GenerateNextPopulation(void)
{
SelectionOperator();//选择操作
CrossoverOperator();//交叉操作
MutationOperator();//变异操作
}
/*********************************************
* 依据一定的规则评价种群 *
*********************************************/
void EvaluatePopulation(void)
{
CaculateObjectValue();//计算个体函数值
CaculateFitnessValue();//计算适应度
FindBestAndWorstIndividual();
}
/*********************************************
*将二进制染色体码解码成十进制数 电阻值解码 *
*********************************************/
double DecodeChromosome1(char *string,int point,int length)
{
int i;
double r=0.0;
char *pointer;
for(i=0,pointer=string+point;i<length;i++,pointer++)
{
if(i<7)
{r+=(*pointer-'0')<<(length-1-i);}
else if(i>=7)
{r+=((*pointer-'0')<<(length-1-i))/8.0;}
}
return(r);
}
/*********************************************
*将二进制染色体码解码成十进制数 电容值解码 *
*********************************************/
double DecodeChromosome2(char *string,int point,int length)
{
int i;
double c=0.0;
char *pointer;
for(i=0,pointer=string+point;i<length;i++,pointer++)
{c+=(*pointer-'0')<<(length-1-i);}
c=c/(1024.0*40.0);
return(c);
}
/****************************************
* 计算最终滤波器的各元件参数值 *
****************************************/
void CaculateDeviceValue(char *sstring)
{
int j=1;
double y[12];
for(j=1;j<=12;j++)
{
if(j<8)
{
y[j-1]=DecodeChromosome1(sstring,10*j,10);
fprintf(galog,"R[%d]:%f\n",j,y[j-1]);
}
else if(j>=8)
{
y[j-1]=DecodeChromosome2(sstring,10*j,10);
fprintf(galog,"C[%d]:%f\n",j-7,y[j-1]);
}
}
}
/*********************************************
* 计算个体函数值 *
*********************************************/
void CaculateObjectValue(void)
{
int i,j;
double x[12];
for(i=0;i<PopSize;i++)
{
for(j=0;j<12;j++)
{
if(j<8)
{
x[j]=DecodeChromosome1(population[i].chrom,10*j,10);
}
else if(j>=8)
{
x[j]=DecodeChromosome2(population[i].chrom,10*j,10);
}
}
population[i].f1=1000/(2*pi*sqrt(x[0]*x[1]*x[8]*x[9]));
population[i].f2=1000/(2*pi*sqrt(x[4]*x[5]*x[10]*x[11]));
population[i].k1=1+x[3]/x[2];
population[i].k2=1+x[7]/x[6];
population[i].a1=(sqrt(x[1]*x[9]/(x[0]*x[8]))+sqrt(x[0]*x[9]/(x[1]*x[8]))-(population[i].k1-1)*sqrt(x[0]*x[8]/(x[1]*x[9])))/2;
population[i].a2=(sqrt(x[5]*x[11]/(x[4]*x[10]))+sqrt(x[4]*x[11]/(x[5]*x[10]))-(population[i].k2-1)*sqrt(x[4]*x[10]/(x[5]*x[11])))/2;
population[i].value=0.05*fabs(population[i].f1-11940.04)+0.05*fabs(population[i].f2-20625.4)+fabs(population[i].k1*population[i].k2-6)+10*fabs(population[i].a1-0.709)+10*fabs(population[i].a2-0.17)+1;
}
}
/***********************************************
* 计算适应度值 *
***********************************************/
void CaculateFitnessValue(void)
{
int i;
for(i=0;i<PopSize;i++)
{
if(population[i].value==0.00)
population[i].fitness=population[i].value;
else
population[i].fitness=1/population[i].value;
}
}
/***********************************************
* 寻找当前代最佳个体 *
***********************************************/
void FindBestAndWorstIndividual(void)
{
int i;
double sum=0.0;
//寻找当前代最佳和最差个体
bestindividual=population[0];
worstindividual=population[0];
for(i=1;i<PopSize;i++)
{
if(population[i].fitness>bestindividual.fitness)
{
bestindividual=population[i];
best_index=i;
}
else if(population[i].fitness<worstindividual.fitness)
{
worstindividual=population[i];
worst_index=i;
}
sum+=population[i].fitness;
//寻找迄今为止最佳个体
if(generation==0)
{currentbest=bestindividual;}
else
{if(bestindividual.fitness>currentbest.fitness)
{currentbest=bestindividual;}
}
}
}
/***********************************************
* 用最优保存策略进行评价操作 *
***********************************************/
void PerformEvolution(void)
{
if(bestindividual.fitness>currentbest.fitness)
{currentbest=population[best_index];}
else
{population[worst_index]=currentbest;}
}
/***********************************************
* 用比例选择的方法复制染色体 *
***********************************************/
void SelectionOperator(void)
{
int i,index;
double p,sum=0.0;
double cfitness[POPSIZE];
struct individual newpopulation[POPSIZE];
//计算相对适应度
for(i=0;i<PopSize;i++)
{sum+=population[i].fitness;}
for(i=0;i<PopSize;i++)
{cfitness[i]=population[i].fitness/sum;}
//计算
for(i=1;i<PopSize;i++)
{cfitness[i]=cfitness[i-1]+cfitness[i];}
//选择操作
for(i=0;i<PopSize;i++)
{
p=rand()%1000/1000.0;
index=0;
while(p>cfitness[index])
{index++;}
newpopulation[i]=population[index];
}
for(i=0;i<PopSize;i++)
{population[i]=newpopulation[i];}
}
/***********************************************
* 用单点交叉方法进行交叉操作 *
***********************************************/
void CrossoverOperator(void)
{
int i,j;
int index[POPSIZE];
int point,temp;
double p;
char ch;
//随机配对两个个体
for(i=0;i<PopSize;i++)
{index[i]=i;}
for(i=0;i<PopSize;i++)
{
point=rand()%(PopSize-i);
temp=index[i];
index[i]=index[point+i];
index[point+i]=temp;
}
//单点交叉操作
for(i=0;i<PopSize-1;i+=2)
{
p=rand()%1000/1000.0;
if(p<Pc)
{
point=rand()%(CHROMLENGTH-1)+1;
for(j=point;j<CHROMLENGTH;j++)
{
ch=population[index[i]].chrom[j];
population[index[i]].chrom[j]=population[index[i+1]].chrom[j];
population[index[i+1]].chrom[j]=ch;
}
}
}
}
/***********************************************
* 变异操作 *
***********************************************/
void MutationOperator(void)
{
int i,j;
double p;
//位变异
for(i=0;i<PopSize;i++)
{
for(j=0;j<CHROMLENGTH;j++)
{
p=rand()%1000/1000.0;
if(p<Pm)
{population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}
}
}
}
/***********************************************
* 输出结果 *
***********************************************/
void OutputTextReport(void)
{
/*int i;
fprintf(galog,"--------------------------------算法统计报告------------------------------\n");
fprintf(galog,"第%d代",generation);
fprintf(galog,"\n");
fprintf(galog,"当前代最佳染色体编码\n");
for(i=0;i<CHROMLENGTH;i++)
{
fprintf(galog,"%c",currentbest.chrom[i]);
}
fprintf(galog,"\n");*/
}
void finalreport(void)
{
int i;
fprintf(galog,"最佳染色体编码\n");
for(i=0;i<CHROMLENGTH;i++)
{
fprintf(galog,"%c",currentbest.chrom[i]);
}
fprintf(galog,"\n");
fprintf(galog,"个体最大适应度值:%f\n",currentbest.fitness);
fprintf(galog,"第一节滤波器的频率:%f\n",currentbest.f1);
fprintf(galog,"第二节滤波器的频率:%f\n",currentbest.f2);
fprintf(galog,"第一节滤波器的增益:%f\n",currentbest.k1);
fprintf(galog,"第二节滤波器的增益:%f\n",currentbest.k2);
fprintf(galog,"第一节滤波器的阻尼系数:%f\n",currentbest.a1);
fprintf(galog,"第二节滤波器的阻尼系数:%f\n",currentbest.a2);
CaculateDeviceValue(currentbest.chrom);
fprintf(galog,"\n\nSimulation Completed\n");
fprintf(galog,"success!\n");
printf("success!\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -