📄 ann+ga.cpp
字号:
return 1;
}//子程序Delta_O_H()结束
/////////////////////////////////////////////////////
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
Delta_H_I(int n )
{
// if(n<=1)
// {
for (int j=0;j<HN;j++){
for (int i=0;i<IN;i++)
{
// if(flag==1)
// Ww[j][i]+=b*e_err_total[j]*P[i];//b*e_err[j]*P[i];//隐层至输入层的权值调整
// else
Ww[j][i]+=b*e_err[j]*P[i];
}
// if(flag==1)
// YU_H[j]+=b*e_err_total[j];//b*e_err[j];
// else
YU_H[j]+=b*e_err[j];
}
// }
/* else
{
for (int j=0;j<HN;j++){
for (int i=0;i<IN;i++)
{
// if(flag==1)
// Ww[j][i]+=b*e_err_total[j]*P[i]+alpha*(Ww[j][i]-Old_WV[(n-1)].old_W[j][i]);//b*e_err[j]*P[i];//隐层至输入层的权值调整
// else
Ww[j][i]+=b*e_err[j]*P[i]+alpha*(Ww[j][i]-Old_WV[(n-1)].old_W[j][i]);
}
// if(flag==1)
// YU_H[j]+=b*e_err_total[j]+alpha*(YU_H[j]-Old_WV[(n-1)].old_YU_HN[j]);//b*e_err[j];
// else
YU_H[j]+=b*e_err[j]+alpha*(YU_H[j]-Old_WV[(n-1)].old_YU_HN[j]);
}
}*/
return 1;
}//子程序Delta_H_I()结束
/////////////////////////////////
//N个样本的全局误差计算子程序////
/////////////////////////////////
double Err_Sum()
{
double total_err=0.0;
for (int m=0;m<N;m++) {
total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差
}
return total_err;
}//子程序Err_sum()结束
//评估函数:使用到用户定义的衰减模型,每次如果被改变则要重新编译
//返回值是误差的平方和,显然返回值越大则表示评价的结果越差
int study;
double error;
double evaluate(double *prms) //参数为个体基因中的参数串charm[]
{
int i,ii,j,jj,k,kk,q,qq;
double old_sum_err=0.0,sum_err=0.0;
int study;//训练次数
a = 0.6;
b = 0.6;
alpha=0.9;
study=0; //学习次数
GetTrainingData();
q=0;
// cout<<"evalute"<<endl;
for(i=0;i<HN;i++)
{
for(j=0;j<IN;j++)
{
Ww[i][j]=prms[q++];
// cout<<Ww[i][j]<<" ";
}
// cout<<endl;
}
for(ii=0;ii<ON;ii++)
{
for(jj=0;jj<HN;jj++)
{
Vv[ii][jj]=prms[q++];
// cout<<Vv[ii][jj]<<" ";
}
// cout<<endl;
}
for(k=0;k<HN;k++)
{
YU_H[k]=prms[q++];
// cout<<YU_H[k]<<" ";
}
// cout<<endl;
for(kk=0;kk<ON;kk++)
{
YU_O[kk]=prms[q++];
// cout<<YU_O[kk]<<" ";
}
// cout<<endl;
do
{
++study;
old_sum_err=sum_err;
for(int iii=0;iii<ON;iii++)
d_err_total[iii]=0.0;
for(int jjj=0;jjj<HN;jjj++)
e_err_total[jjj]=0.0;
saveWV(study,prms);
flag=0;
for (int m=0;m<N;m++)
{
input_P(m); //输入第m个学习样本 (2)
input_T(m);//输入第m个样本的教师信号 (3)
H_I_O(); //第m个学习样本隐层各单元输入、输出值 (4)
O_I_O(); //第m个学习样本输出层各单元输入、输出值 (5)
Err_O_H(m); //第m个学习样本输出层至隐层一般化误差 (6)
Err_H_I(); //第m个学习样本隐层至输入层一般化误差 (7)
Delta_O_H(study); //第m个学习样本输出层至隐层权阈值调整、修改 (8)
Delta_H_I(study); //第m个学习样本隐层至输入层权阈值调整、修改 (9)
for(int qq=0;qq<ON;qq++)
out[m][qq]=O[qq];
} //全部样本训练完毕
flag=1;
//Delta_O_H(study);
//Delta_H_I(study);
sum_err=Err_Sum(); //全部样本全局误差计算 (10)
error=sum_err;
qq=0;
for(i=0;i<HN;i++)
for(j=0;j<IN;j++)
prms[qq++]=Ww[i][j];
for(ii=0;ii<ON;ii++)
for(jj=0;jj<HN;jj++)
prms[qq++]=Vv[ii][jj];
for(k=0;k<HN;k++)
prms[qq++]=YU_H[k];
for(kk=0;kk<ON;kk++)
prms[qq++]=YU_O[kk];
//saveWV(study,prms);
}while(study<5);
// cout<<"evaluate_end"<<endl;
//for( int ep=0;ep<NVARS;ep++)
//{
// cout<<prms[ep]<<" ";
// if((ep+1)%3==0)cout<<endl;
//}
//cout<<endl;
return (sum_err);
}
void savequan()
{
ofstream outQuanFile( "品种钢权值.txt", ios::out );
ofstream outYuFile( "品种钢阈值.txt", ios::out );
ofstream outshuchuFile( "kkk输出.txt", ios::out );
outQuanFile<<"A\n";
for(int i=0;i<HN;i++)
{
for(int j=0;j<IN;j++)
{
outQuanFile<<Old_WV[study-1].old_W[i][j]<<" ";
}
outQuanFile<<"\n";
}
outQuanFile<<"B\n";
for(int ii=0;ii<ON;ii++)
{
for(int jj=0;jj<HN;jj++)
{
outQuanFile<<Old_WV[study-1].old_V[ii][jj]<<" ";
}
outQuanFile<<"\n";
}
outYuFile<<"输出层的阈值为:\n";
for(int k=0;k<ON;k++)
{
outYuFile<<Old_WV[study-1].old_YU_ON[k]<<" "; //输出层阈值写入文本
}
outYuFile<<"\n隐层的阈值为:\n";
for(int kk=0;kk<HN;kk++)
{
outYuFile<<Old_WV[study-1].old_YU_HN[kk]<<" "; //隐层阈值写入文本
}
for(int m=0;m<N;m++)
{
for(int iii=0;iii<IN;iii++)
outshuchuFile<<Study_Data[m].input[iii]*lengthin+minin<<" \t";
for(int jjj=0;jjj<ON;jjj++)
outshuchuFile<<Study_Data[m].teach[jjj]*lengthout+minout<<" \t";
for(int qqq=0;qqq<ON;qqq++)
outshuchuFile<<" *** "<<out[m][qqq]*lengthout+minout<<" \t";
outshuchuFile<<"\n";
}
outshuchuFile.close();
outQuanFile.close();
outYuFile.close();
}
//用于确定在种群中的个体选择位置和规格化适应度的函数
//初始化种群的函数,用随机生成的数初始化参数a,b,c;
//用评估函数的返回值作为个体的适应度,同时规格化适应度确定个体的选择位置
//选择函数:采用赌盘选择方法
int select(individual *pop)
{
double rand1;
double partsum=0.0;
int i=0;
double sum=0.0;
// rand1=rdft()*POPSIZE*(POPSIZE+1);
for(i=0;i<POPSIZE;i++)
sum+=pop[i].r;
rand1=rdft()*sum;
for(i=int(POPSIZE*rdft());(rand1>=partsum);)
{
if(i>=POPSIZE) i=int(POPSIZE*rdft());
partsum+=pop[i].r;
i++;
}
// partsum+=pop[i].fitness;//部分和是基因适应度的和
return (i-1);
}
//突变:
double mutate(int i)
{
return -1+rdft()*(1-(-1));//产生参数上下限内的随机数
}
//交叉和突变函数:数学交叉
void xover(double *parent1,double *parent2,double *child1,double *child2)
//参数为个体基因中的参数串charm[]
{
// double alpha;
// double bt;
int i;
int k,kk;
k=rnd(0,NVARS-1);
do
{
kk=rnd(0,NVARS-1);
}while(k==kk);
if(k>kk)
{
int t=k;
k=kk;
kk=t;
}
for(i=0;i<k;i++)
{
child1[i]=parent2[i];
child2[i]=parent1[i];
}
for(i=k;i<kk;i++)
{
child1[i]=parent1[i];
child2[i]=parent2[i];
}
for(i=kk;i<NVARS;i++)
{
child1[i]=parent2[i];
child2[i]=parent1[i];
}
for(i=0;i<NVARS;i++)
{
// alpha=rdft();
// child1[i]=alpha*parent1[i]+(1-alpha)*parent2[i];
// child2[i]=alpha*parent2[i]+(1-alpha)*parent1[i];
/* if(change>10&&uu==0)
{
vv++;
uu++;
}
else
if(change==0)uu=0;
if(change>5&&change%3!=0)
{
child1[i]=parent1[i]+(((b[i]-a[i])/5)/(change%((vv+1)*5)+1))*(rdft()-rdft());
child2[i]=parent2[i]+(((b[i]-a[i])/5)/(change%((vv+1)*5)+1))*(rdft()-rdft());
}
else*/
{
if(rdft()<pmt1)
child1[i]=mutate(i);
if(rdft()<pmt2)
child2[i]=mutate(i);
}
}
}
//重组函数:通过选择、交叉和变异由老的一代产生新的一代
void recombine(void)
{
int i=0,k=0,ii,ll;
int j=0;
int mate1,mate2;
double length[2*POPSIZE];
individual temp[POPSIZE];
individual allpop[2*POPSIZE];
int max,min;
double temp1[NVARS];
double temp2[2*POPSIZE];
int location_all[2*POPSIZE];
int best=0;
double fitsum=0.0,fit1max,fitmin,fitave;
double fit=0.0;
int g=0;
double fitmax;
maxlsquare=oldpop[0].lsquare;
minlsquare=oldpop[0].lsquare;
pc1=0.9,pc2=0.6,pm1=0.1,pm2=0.001;
for(ii=0;ii<POPSIZE;ii++)
{
if(maxlsquare<oldpop[ii].lsquare) maxlsquare=oldpop[ii].lsquare;
if(minlsquare>oldpop[ii].lsquare) minlsquare=oldpop[ii].lsquare;
fitsum=fitsum+oldpop[ii].lsquare;
}
fit1max=maxlsquare;
fitmin=minlsquare;
fitave=fitsum/POPSIZE;
pmt1=pmt2=0.05+change*0.005;
if(pmt1>0.1)pmt1=pmt2=0.1;
i=0;
while(i<POPSIZE){
//从老一代中选择两个双亲
mate1=select(oldpop);
do
{
mate2=select(oldpop);
}while(mate1==mate2);
fitmax=(oldpop[mate1].lsquare<oldpop[mate2].lsquare)?
oldpop[mate1].lsquare:oldpop[mate2].lsquare;
pc=(pc1-pc2)*(1-exp(-fabs(fitmax-fitave)/(fit1max-fitave)))+pc2;
//对选择的个体进行交叉和突变操作
if(rdft()<pc)
{
xover(oldpop[mate1].chrom,oldpop[mate2].chrom,temp[i].chrom,temp[i+1].chrom); //newpop[i].chrom,newpop[i+1].chrom);
temp[i].lsquare=evaluate(temp[i].chrom);//fx;
temp[i+1].lsquare=evaluate(temp[i+1].chrom);//fx;
}
else
{
temp[i]=oldpop[mate1];//newpop[i]=oldpop[mate1];
temp[i+1]=oldpop[mate2];//newpop[i+1]=oldpop[mate2];
}
i+=2;
}
for(ll=0;ll<POPSIZE;ll++)
{
allpop[ll]=oldpop[ll];
allpop[ll+POPSIZE]=temp[ll];
}
for(ll=0;ll<2*POPSIZE;ll++)
{
location_all[ll]=ll;
temp2[ll]=allpop[ll].lsquare;
}
quick_sort_all(temp2,0,2*POPSIZE-1,location_all);
best=location_all[0];
for(i=0;i<POPSIZE/2;i++)
// for(i=0;i<int(2*POPSIZE/5.0+0.5);i++)
{
newpop[i]=allpop[location_all[i]];
}
for(i=0;i<2*POPSIZE;i++)
length[i]=0.0;
for(i=0;i<2*POPSIZE;i++)
{
for(j=0;j<2*POPSIZE;j++)
{
length[i]+=fabs(allpop[i].lsquare-allpop[j].lsquare);
}
}
for(i=0;i<2*POPSIZE;i++)
location_all[i]=i;
quick_sort_length(length,0,2*POPSIZE-1,location_all);
for(i=0;i<POPSIZE/2;i++)
// for(i=0;i<int(3*POPSIZE/5.0+0.5);i++)
{
newpop[i+POPSIZE/2]=allpop[location_all[i]];
// newpop[i+int(2*POPSIZE/5.0+0.5)]=allpop[location_all[i]];
}
maxlsquare=-1.0e10;
minlsquare=1.0e10;
for(i=0;i<POPSIZE;i++)
{
if(maxlsquare<newpop[i].lsquare) {maxlsquare=newpop[i].lsquare;max=i;}
if(minlsquare>newpop[i].lsquare) {minlsquare=newpop[i].lsquare;min=i;}
}
if(change>10&&u==0)
{
v++;
u++;
}
else
if(change==0)u=0;
for(i=0;i<NVARS;i++)
{
temp1[i]=newpop[min].chrom[i]+(((1-(-1))/5)/(change%((v+1)*5)+1))*(rdft()-rdft());
}
for(i=0;i<NVARS;i++)
{
newpop[max].chrom[i]=temp1[i];
}
newpop[max].lsquare=evaluate(newpop[max].chrom);
normalfitness(newpop);
//在新的种群中随机选择一个个体,若它比原种群中最好的个体好,则替代它,否则不做改变
i=rnd(0,POPSIZE-1);
// printf("\ni=%d\n",i);
//printf( "\niiiiiiiiiii=%d\n",i);
// printf("\noldpop[POPSIZE].lsquare=%lf\n",oldpop[POPSIZE].lsquare);
if(newpop[i].lsquare>oldpop[POPSIZE].lsquare)
newpop[i]=oldpop[POPSIZE];
// printf("\n######################################################################\n");
normalfitness(newpop); //确定个体在种群中的选择位置和规格化适应度
//printf("\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
//如果新的种群中的最好的个体比过去的种群中的最好的个体好,
//就从新的种群中拷贝这个最好的否则用过去的种群中的最好的个体替代当前的最好个体
//注意:这个最好的个体不包括直接进化产生的
if(newpop[location[POPSIZE-1]].lsquare<oldpop[POPSIZE].lsquare)
{
newpop[POPSIZE]=newpop[location[POPSIZE-1]];
change=0;
}
else
{
newpop[POPSIZE]=oldpop[POPSIZE];
change++;
}
}
void report(int gen) //结果报告
{
// int i;
printf("\rG=%3d U=%2d ",gen,change);
// printf("max=%lf min=%lf pc=%lf pmt1=%lf pmt2=%lf ",maxlsquare,minlsquare,pc,pmt1,pmt2);
//for(i=0;i<NVARS;i++)
// printf("par%d=%lf ",i,newpop[POPSIZE].chrom[i]);
printf("err=%.10lf\n",newpop[POPSIZE].lsquare);
//printf("\n************************************************************************\n");
}
//主函数:
void main(void)
{
int i;
initialize(); //初始化种群
for(gen=1;gen<=1000;gen++)
// do
{
recombine(); //基因重组
report(gen); //结果输出
for(i=0;i<=POPSIZE;i++)
oldpop[i]=newpop[i];
}//while(error>0.0001);
savequan(); //权值和阈值保存
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -