?? 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 + -