遗传算法的VC++实现.docx
《遗传算法的VC++实现.docx》由会员分享,可在线阅读,更多相关《遗传算法的VC++实现.docx(15页珍藏版)》请在冰豆网上搜索。
遗传算法的VC++实现
遗传算法的VC++实现
遗传算法是一种借鉴生物界自然选择和自然遗传机制的高度并行、随机、自适应搜索算法,其隐含的对全局信息的有效利用能力使遗传算法具有稳健性,能够很好地处理传统优化方法解决不了的复杂和非线性问题。
遗传算法的执行过程可以简单描述为随机地在参变量空间中进行搜索,由串组成的群体在遗传算子的作用下,同时对空间中不同的区域进行采样计算,从而构成一个不断迭代进化的群体序列。
遗传算法的突出表现能力是能够把注意力集中到搜索空间中期望值最高的部分,这是遗传算法中杂交算子作用的直接结果。
杂交过程就是模拟生物界中的有性繁殖,它是遗传算法中最重要的部分,是遗传算法区别于其它优化算法的根本所在。
遗传算法以迭代群体中的所有个体为操作对象,从本质上讲属于一种群体操作算法,其基本流程如图1所示。
一个标准的遗传算法程序包含4个基本组成部分:
(1)参数编码;
(2)初始群体生成;(3)适应值检测;(4)遗传操作。
其中遗传操作是遗传算法的核心,它由3个基本操作算子组成,即选择算子、交叉算子和变异算子,不同的遗传算子对算法的运行性能有着各不相同的影响。
文章主要从遗传算法在求解连续最优化问题中的设计与实现环节上对遗传算法进行研究。
根据所求解问题的性质,设计合理的遗传算法程序,使之满足求解问题的要求。
一些术语
一、染色体(Chronmosome)
染色体又可以叫做基因型个体(individuals),一定数量的个体组成了群体(population),群体中个体的数量叫做群体大小。
二、基因(Gene)
基因是串中的元素,基因用于表示个体的特征。
例如有一个串S=1011,则其中的1,0,1,1这4个元素分别称为基因。
它们的值称为等位基因(Alletes)。
三、基因地点(Locus)
基因地点在算法中表示一个基因在串中的位置称为基因位置(GenePosition),有时也简称基因位。
基因位置由串的左向右计算,例如在串S=1101中,0的基因位置是3。
四、基因特征值(GeneFeature)
在用串表示整数时,基因的特征值与二进制数的权一致;例如在串S=1011中,基因位置3中的1,它的基因特征值为2;基因位置1中的1,它的基因特征值为8。
五、适应度(Fitness)
各个个体对环境的适应程度叫做适应度(fitness)。
为了体现染色体的适应能力,引入了对问题中的每一个染色体都能进行度量的函数,叫适应度函数.这个函数是计算个体在群体中被使用的概率。
vc程序设计(遗传算法)
/**************************************************************/
/*基于基本遗传算法的函数最优化*/
/*同济大学计算机系王小平2000年5月*/
/**************************************************************/
#include
#include
#include
#include
#include
#include
#include"graph.c"
#include"operator.c"
#definePOP_SIZE25/*种群大小*/
#defineG_LENGTH8/*染色体长度*/
#defineC_RATE0.2/*交叉概率*/
#defineM_RATE0.01/*变异概率*/
#defineXMAX255/*函数变量最大值*/
#defineX1350/*函数图形区窗口左上点X坐标*/
#defineY140/*函数图形区窗口左上点Y坐标*/
#defineXR1255/*函数图形区窗口长度*/
#defineYR1200/*函数图形区窗口高度*/
#defineX2360/*适应度图形区窗口左上点X坐标*/
#defineY2280/*适应度图形区窗口左上点Y坐标*/
#defineXR2250/*适应度图形区窗口长度*/
#defineYR2100/*适应度图形区窗口宽度*/
#defineSTEP2/*适应度图形区X方向步长*/
voidinitialize_gene(gene,pop_size,g_length)
/*种群中个体遗传基因型的初始化*/
unsignedchar*gene;/*遗传基因*/
intpop_size;/*种群大小*/
intg_length;/*个体染色体长度*/
{
inti,j;
randomize();
for(i=0;ifor(j=0;j*(gene+i*g_length+j)=random
(2);
}
intgene_to_pheno(gene,g_length)
/*基因型到表现型的变换--解码*/
unsignedchar*gene;/*基因型*/
intg_length;/*染色体长度*/
{
inti,pheno;
pheno=0;
for(i=0;ipheno=pheno*2+*(gene+i);
return(pheno);
}
voidcalc_fitness(gene,fitness,pop_size,g_length,func,max_fit,avg_fit)
/*计算种群中个体的适应度*/
unsignedchar*gene;/*个体的遗传基因*/
double*fitness;/*个体的适应度*/
double*func;/*评价函数*/
double*max_fit,*avg_fit;/*最大适应度与平均适应度*/
intpop_size;/*种群大小*/
intg_length;/*个体染色体长度*/
{
unsignedchar*g;/*个体的遗传基因指针变量*/
intpheno;/*个体的表现型*/
inti,j;
doublef;
*max_fit=0.0;
*avg_fit=0.0;
f=(double)pop_size;
for(i=0;i{
g=gene+i*g_length;
pheno=gene_to_pheno(g,g_length);
*(fitness+i)=*(func+pheno);
if(*(fitness+i)>*max_fit)
*max_fit=*(fitness+i);
*avg_fit=*avg_fit+*(fitness+i)/f;
}
}
voidsga_reproduction(gene,fitness,new_gene,new_fitness,pop_size,g_length)
/*基于个体的适应度评价进行新一代个体的选择(轮盘赌方法),选择后分别将新的基因型和适应度代入到新个体中*/
unsignedchar*gene;/*当前代的个体遗传基因型*/
unsignedchar*new_gene;/*新一代的个体遗传基因型*/
double*fitness;/*当前代的个体适应度*/
double*new_fitness;/*新一代的个体适应度*/
intpop_size;/*种群大小*/
intg_length;/*染色体长度*/
{
doublesum_of_fitness;
doubleborder;
doubler;/*轮盘上的选择位置变量*/
inti,j;
intnum;
sum_of_fitness=0.0;
for(i=0;isum_of_fitness=sum_of_fitness+*(fitness+i);
for(i=0;i{
r=sum_of_fitness*(random(10001)/10000.0);
num=0;
border=*fitness;
while(border{
num++;
border=border+*(fitness+num);
}
for(j=0;j*(new_gene+i*g_length+j)=*(gene+num*g_length+j);
*(new_fitness+i)=*(fitness+num);
}
}
voidsga_crossover(gene,pop_size,g_length,c_rate)
/*基本遗传算法的交叉操作--单点交叉*/
unsignedchar*gene;/*遗传基因*/
intpop_size;/*种群大小*/
intg_length;/*个体染色体长度*/
doublec_rate;/*交叉概率*/
{
unsignedchar*gene1;/*父个体1的遗传基因指针变量*/
unsignedchar*gene2;/*父个体1的遗传基因指针变量*/
unsignedcharwork;/*中间变量*/
inti,j;
intc_pos;/*交叉位置变量*/
doubler;/*随机数变量*/
for(i=0;i{
r=random(10001)/10000.0;
if(r<=c_rate)
{
gene1=gene+g_length*i;
gene2=gene1+g_length;
c_pos=random(g_length-2)+1;
for(j=c_pos;j{work=*(gene1+j);
*(gene1+j)=*(gene2+j);
*(gene2+j)=work;
}
}
}
}
voidsga_mutation(gene,pop_size,g_length,m_rate)
/*基本遗传算法的变异操作--个体遗传基因按小概率翻转*/
unsignedchar*gene;/*遗传基因*/
intpop_size;/*种群大小*/
intg_length;/*染色体长度*/
doublem_rate;/*变异概率*/
{
inti,j;
doubler;
for(i=0;i{
for(j=0;jr=random(10001)/10000.0;
if(r<=m_rate)/*变异发生判断*/
{
if(*(gene+g_length*i+j)==0)
*(gene+g_length*i+j)=1;
else
*(gene+g_length*i+j)=0;
}
}
}
voidmake_function(func,xmax)
/*生成一个函数,用于最优化计算的目标函数(最大化)*/
/*f=∑ai*sin(x*bi+ci)其中ai∈[0,0.35]的均匀随机数
bi∈[2*pi,5*2*pi]/xmax的均匀随机数
ci∈[0,2*pi]的均匀随机数
x∈[0,xmax]为优化变量
i=1,2,3*/
double*func;/*函数值*/
intxmax;/*变量最大值{
intx,i;
doublea[3],b[3],c[3];
doublepi=3.141592;
doublefxmax,fx,f_value;
doublef_min,f_max,f_mid,f_range;
doubledbl;
randomize();
fxmax=(double)xmax;
for(i=0;i<3;i++)/*优化函数为三个三角函数之和*/
{
a[i]=0.35*(random(10001)/10000.0);
b[i]=(4*(random(10001)/10000.0)+1)*2.0*pi/fxmax;
c[i]=2.0*pi*(random(10001)/10000.0);
}
f_min=1.0;
f_max=0.0;
for(x=0;x<=xmax;x++)/*将优化函数正规化为[0,1]区间数*/
{
fx=(double)x;
f_value=0.0;
for(i=0;i<3;i++)
{
dbl=b[i]*fx+c[i];
f_value=f_value+a[i]*sin(dbl);
}
f_value=f_value+0.5;
if(f_value>f_max)f_max=f_value;
if(f_value*(func+x)=(double)f_value;
}
f_range=f_max-f_min;
f_mid=(f_max+f_min)/2.0;
for(x=0;x<=xmax;x++)
{
f_value=(*(func+x)-f_mid)/f_range+0.5;
if(f_value>1.0)f_value=1.0;
elseif(f_value<0.0)f_value=0.0;
*(func+x)=f_value;
}
}
voidg_draw_func(func,xmax)
/*绘制优化函数的图形*/
double*func;/*函数值*/
intxmax;/*变量最大值*/
{
intx,y,x_old,y_old,i;
doublef;
g_rectangle(X1+1,Y1+1,X1+XR1-1,Y1+YR1-1,0,1);
g_rectangle(X1+1,Y1-12,X1+XR1,Y1-1,8,1);
g_rectangle(X1,Y1,X1+XR1,Y1+YR1,6,0);
x_old=X1;
y_old=Y1+YR1-(int)(*func*YR1);
f=XR1/(double)xmax;
for(i=1;i<=xmax;i++)
{
x=X1+(int)(i*f);
y=Y1+YR1-(int)(*(func+i)*YR1);
g_line(x_old,y_old,x,y,12);
x_old=x;
y_old=y;
}
}
voidg_init_grph(func,xmax)
/*初始化画面的图形*/
double*func;/*函数值*/
intxmax;/*变量最大值*/
{
intx,y,x_old,y_old,i;
charc[5];
/*初始化函数图形区*/
g_rectangle(320,0,639,399,8,1);
g_rectangle(321,1,638,16,8,1);
disp_hz16("基于基本遗传算法的函数最优化",370,1,15);
disp_hz16("g(x)",X1-30,Y1-18,15);
disp_hz16("1.0",X1-30,Y1,15);
disp_hz16("0",X1-10,Y1+YR1,15);
disp_hz16("x",X1+XR1+10,Y1+YR1-20,15);
disp_hz16("XMAX",X1+XR1-10,Y1+YR1,15);
g_draw_func(func,xmax);
/*初始化适应度图形区*/
g_rectangle(X2,Y2,X2+XR2,Y2+YR2,0,1);
g_rectangle(X2,Y2,X2+XR2,Y2+YR2,6,0);
setcolor(15);
disp_hz16("最大适应度",X2+5,Y2-18,15);
g_line(X2+90,Y2-10,X2+110,Y2-10,11);
setcolor(15);
disp_hz16("平均适应度",X2+120,Y2-18,15);
g_line(X2+205,Y2-10,X2+225,Y2-10,9);
setcolor(15);
disp_hz16("世代数",X2+168,Y2+YR2+10,15);
g_text(X2-30,Y2,15,"1.0");
/*g_text(X2-30,Y2+YR2,15,"0.0");*/
}
voidg_plot_grph(num,gene,fitness,pop_size,g_length,func,xmax,max_fit,m_f_old,avg_fit,a_f_old,gen_num)
/*随世代进化更新图形*/
unsignedchar*gene;/*遗传基因*/
double*fitness;/*适应度*/
double*func;/*函数值*/
doublemax_fit,m_f_old;/*当前代最大适应度,上一代最大适应度*/
doubleavg_fit,a_f_old;/*当前代平均适应度,上一代平均适应度*/
intnum;/*当前世代数*/
intpop_size;/*种群大小*/
intg_length;/*染色体长度*/
intxmax;/*变量最大值*/
intgen_num;/*最大世代数*/
{
inti,j,x,y,x_old,y_old;
doublef;
unsignedchar*g;
charc[10];
/*显示当前世代种群中个体的遗传基因*/
if(num==gen_num-1)
{
for(i=0;i{
printf("Indv.%2d:
",i+1);
for(j=0;jprintf("%d",*(gene+i*g_length+j));
printf("==>Fitness%.4f\n",*(fitness+i));
}
printf("Max_fit=%f\n",max_fit);
printf("Avg_fit=%f\n",avg_fit);
}
/*显示个体在函数图形区中的位置*/
g_draw_func(func,xmax);
f=XR1/(double)xmax;
for(i=0;i{
g=gene+i*g_length;
j=gene_to_pheno(g,g_length);
x=X1+(int)(j*f);
y=Y1+YR1-*(func+j)*YR1;
g_line(x,y-10,x,y,15);
}
/*适应度曲线的更新*/
if(num!
=1&&num<=XR2/STEP)
{
if(num%10==0)/*每隔10代更新一次*/
{
x=X2+(num-1)*STEP;
g_line(x,Y2+1,x,Y2+YR2-1,1);
sprintf(c,"%d",num);
if(num<100||num%20==0)
g_text(x-8,Y2+YR2,15,c);
}
x_old=X2+(num-1)*STEP;
x=x_old+STEP;
y_old=Y2+YR2-(int)(m_f_old*YR2);
y=Y2+YR2-(int)(max_fit*YR2);
g_line(x_old,y_old,x,y,11);
y_old=Y2+YR2-(int)(a_f_old*YR2);
y=Y2+YR2-(int)(avg_fit*YR2);
g_line(x_old,y_old,x,y,9);
}
}
voidgeneration(gene,fitness,pop_size,g_length,c_rate,m_rate,new_gene,new_fitness,func,xmax)
/*世代进化的模拟*/
unsignedchar*gene;/*当前世代的个体遗传基因型*/
unsignedchar*new_gene;/*新一代的个体遗传基因型*/
double*fitness;/*当前世代的个体适应度*/
double*new_fitness;/*新一代的个体适应度*/
double*func;/*优化函数*/
doublec_rate,m_rate;/*交叉概率和变异概率*/
intpop_size,g_length;/*种群大小与染色体长度*/
{intgen_max;/*最大模拟世代数*/
inti,j,k;
doublemax_fit,avg_fit;/*当前代最大适应度和平均适应度*/
doublem_f_old,a_f_old;/*新一代最大适应度和平均适应度*/
charchoice[3];
setcolor(15);
disp_hz16("输入最大模拟世代数:
",10,1,20);
gscanf(170,1,4,0,3,"%s",choice);
gen_max=atoi(choice);
m_f_old=0.0;
a_f_old=0.0;
for(i=0;i{
if(i==gen_max-1)
{
printf("\n");
printf("************Gen.%d*************\n",i+1);
}
calc_fitness(gene,fitness,pop_size,g_length,func,
&max_fit,&avg_fit);
sga_reproduction(gene,fitness,new_gene,new_fitness,
pop_size,g_length);
for(j=0;j{
*(fitness+j)=*(new_fitness+j);
for(k=0;k