當前位置:編程學習大全網 - 編程語言 - 求助:人工智能“遺傳算法求解f(x)=xcosx+2的最大值”

求助:人工智能“遺傳算法求解f(x)=xcosx+2的最大值”

為了方便我只求了-3.14到3.14之間的最大值,妳可以自己改壹下,不過範圍大了之後,種群也因該擴大,我的種群只有66個

結果:極值點(-3.141593,5.141593)

我又算了壹下-100到100之間的極大值

結果:極值點(-97.399473,99.394504)

-1000到1000之間的極大值

結果:(999,1001)

-2000到2000之間的極大值

結果:(1998.053550,2000.053163)

以上結果我用matlab畫圖驗證了,沒問題。

希望再給加點分,呵呵

//中國電子科技集團公司

//第壹研究室

//呼文韜

//hu_hu605@163.com

//隨機初始種群

//編碼方式為格雷碼

//選擇方法為隨機遍歷

//采用了精英保存策略

//采用了自適應的交叉率和變異率

//采用了與模擬退火算法相結合的尺度變換

//采用了均勻交叉法

#include <stdlib.h>

#include <stdio.h>

#include <math.h>

#include <iostream.h>

#include <iomanip.h>

#include <time.h>

#include <windows.h>

#define IM1 2147483563

#define IM2 2147483399

#define AM (1.0/IM1)

#define IMM1 (IM1-1)

#define IA1 40014

#define IA2 40692

#define IQ1 53668

#define IQ2 52774

#define IR1 12211

#define IR2 3791

#define NTAB 32

#define NDIV (1+IMM1/NTAB)

#define EPS 1.2e-7

#define RNMX (1.0-EPS)

#define zhizhenjuli 0.005

#define PI 3.14159265358

#define T0 100000//溫度要取得很高才行。

#define zhongqunshu1 200

#define zuobianjie -2000

#define youbianjie 2000

unsigned int seed=0; //seed 為種子,要設為全局變量

void mysrand(long int i) //初始化種子

{

seed = -i;

}

long a[1];

//double hundun;

//double c=4;

//設置全局變量

struct individual

{

unsigned *chrom; //染色體;

double geti;//變量值

double shiyingdu; //目標函數的值;

double fitness; //變換後的適應度值;

};

individual *zuiyougeti;//精英保存策略

int zhongqunshu; //種群大小

individual *nowpop;//當前代

individual *newpop;//新壹代

double sumfitness;//當代的總適應度fitness

double sumshiyingdu;//當代的總適應度shiyingdu

double maxfitness;//最大適應度

double avefitness;//平均適應度

double maxshiyingdu;//最大適應度

double avgshiyingdu;//平均適應度

float pc;//交叉概率

float pm;//變異概率

int lchrom;//染色體長度

int maxgen;//最大遺傳代數

int gen;//遺傳代數

//函數

int flipc(double ,double );//判斷是否交叉

int flipm(double );//判斷是否變異

int rnd(int low,int high);//產生low與high之間的任意數

void initialize();//遺傳算法初始化

void preselectfitness(); //計算sumfiness,avefitness,maxfitness

void generation();

double suijibianli();//產生隨機遍歷指針

int fuzhi(float );//選擇要復制的個體

void crossover(individual ,individual ,individual &,individual &);//交叉

void bianyi(individual &);//變異

void mubiaohanshu(individual &);//計算適應度

void chidubianhuan(individual &);//對shiyingdu進行尺度變換賦給fitness

double ran1(long *);//隨機數初始

void bianma(double bianliang,unsigned *p);//編碼

double yima(unsigned *p);

void guanjiancanshujisuan();//計算shiyingdu,根據shiyingdu計算sumshiyingdu,對shiyingdu進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness

void jingyingbaoliu();

void glp(int n,int s,int *,int (*)[1],float (*)[1]);//glp生成函數

BOOL Exist(int Val, int Num, int *Array);//判斷壹個數在前面是否出現過

int cmpfitness(const void *p1,const void *p2)

{

float i=((individual *)p1)->shiyingdu;//現在是按照"適應度"排序,改成"個體"的話就是按照"個體"排序

float j=((individual *)p2)->shiyingdu;

return i<j ? -1:(i==j ? 0:1);//現在是按升序牌排列,將1和-1互換後就是按降序排列

}

void main()

{

initialize();

cout<<zuiyougeti->geti<<" "<<zuiyougeti->shiyingdu<<endl;/////////////

for(gen=1;gen<maxgen;gen++)

{ generation();

}

jingyingbaoliu();

cout<<setiosflags(ios::fixed)<<setprecision(6)<<zuiyougeti->geti<<" "<<setiosflags(ios::fixed)<<setprecision(6)<<(zuiyougeti->shiyingdu)<<endl;////////////////

delete [] newpop;

delete [] nowpop;

delete [] zuiyougeti;

system("pause");

}

void initialize()

{

int q[zhongqunshu1][1],s=1;

float xx[zhongqunshu1][1];//生成的glp用x儲存

int h[1]={1};//生成向量

zuiyougeti=new individual;//最優個體的生成

zhongqunshu=200;//種群數量

nowpop=new individual[zhongqunshu1];//當代

newpop=new individual[zhongqunshu1];//新壹代

maxgen=150;//最大代數

gen=0;//起始代

lchrom=22;//基因數量的初始化

mysrand(time(0));//隨機數種子

a[0]=seed;//隨機數種子

//對最優個體的初始化

zuiyougeti->geti=0;

zuiyougeti->fitness=0;

zuiyougeti->shiyingdu=0;

//

glp(zhongqunshu,s,h,q,xx);

//for(int i=0;i<zhongqunshu1;i++)//產生初始種群

//{

// for(int j=0;j<s;j++)

// {

// nowpop[i].geti=zuobianjie+(youbianjie-zuobianjie)*xx[i][j];

// }

//}

for(int i=0;i<zhongqunshu1;i++)//產生初始種群

{

nowpop[i].geti=zuobianjie+(youbianjie-(zuobianjie))*ran1(a);

}

//nowpop[0].geti=999;//////////////////////////

guanjiancanshujisuan();

jingyingbaoliu(); //精英保留的實現

guanjiancanshujisuan();//計算shiyingdu,根據shiyingdu計算sumshiyingdu,對shiyingdu進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness

}

void jingyingbaoliu() //精英保留的實現

{

individual *zuiyougetiguodu;

zuiyougetiguodu=new individual[zhongqunshu1];//建立壹個過渡數組

for(int i=0;i<zhongqunshu;i++)//將當代個體復制到過渡數組中

zuiyougetiguodu[i]=nowpop[i];

qsort(zuiyougetiguodu,zhongqunshu1,sizeof(individual),&cmpfitness);//按fitness升序排序

// cout<<"zuiyougetiguodu適應度:"<<zuiyougetiguodu[zhongqunshu1-1].shiyingdu<<endl;///////////

// cout<<"zuiyougeti適應度:"<<zuiyougeti->shiyingdu<<endl;///////////////////

//system("pause");

if(zuiyougetiguodu[zhongqunshu-1].shiyingdu>zuiyougeti->shiyingdu)

{

*zuiyougeti=zuiyougetiguodu[zhongqunshu1-1];//如果最優個體的fitness比當代最大的fitness小則用當代的代替之

//cout<<"zuiyougetiguodu個體:"<<zuiyougetiguodu[zhongqunshu1-1].geti<<endl;/////////////

//cout<<"zuiyougeti個體:"<<zuiyougeti->geti<<endl;/////////////

}

else

nowpop[rnd(0,(zhongqunshu1-1))]=*zuiyougeti;//否則的話從當代中隨機挑選壹個用最優個體代替之

delete [] zuiyougetiguodu;//釋放過渡數組

}

void guanjiancanshujisuan()//計算shiyingdu,根據shiyingdu計算sumshiyingdu,對shiyingdu進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness

{

for(int i=0;i<zhongqunshu;i++)//計算shiyingdu

mubiaohanshu(nowpop[i]);

for(i=0;i<zhongqunshu;i++)//對shiyingdu進行尺度變換變成fitness

chidubianhuan(nowpop[i]);

preselectfitness();//根據fitness計算sumfitness,avefitness,maxfitness

}

void mubiaohanshu(individual &bianliang)//計算shiyingdu

{

bianliang.shiyingdu=(bianliang.geti*cos(bianliang.geti)+2.0);//目標函數

}

void chidubianhuan(individual &bianliang)//對shiyingdu進行尺度變換變成fitness

{

double T;//退火溫度

T=T0*(pow(0.99,(gen+1-1)));

double sum=0;

for(int j=0;j<zhongqunshu;j++)

sum+=exp(nowpop[j].shiyingdu/T);

bianliang.fitness=exp(bianliang.shiyingdu/T)/sum;//算出fitness

}

void preselectfitness()//根據fitness計算sumfitness,avefitness,maxfitness

{

int j;

sumfitness=0;

for(j=0;j<zhongqunshu;j++)

sumfitness+=nowpop[j].fitness;

individual *guodu;

guodu=new individual[zhongqunshu1];

for(j=0;j<zhongqunshu;j++)

guodu[j]=nowpop[j];

qsort(guodu,zhongqunshu1,sizeof(individual),&cmpfitness);

maxfitness=guodu[zhongqunshu1-1].fitness;

avefitness=sumfitness/zhongqunshu1;

delete [] guodu;

}

void generation()

{

individual fuqin1,fuqin2,*pipeiguodu,*pipeichi;

int *peiduishuzu;//用來存放產生的隨機配對

pipeiguodu=new individual[zhongqunshu1];

pipeichi=new individual[zhongqunshu1];

peiduishuzu=new int[zhongqunshu1];

int member1,member2,j=0,fuzhijishu=0,i=0,temp=0,tt=0;

float zhizhen;

//隨機遍歷的實現

for(zhizhen=suijibianli();zhizhen<1;(zhizhen=zhizhen+zhizhenjuli))//設定指針1/66

{

pipeichi[fuzhijishu]=nowpop[fuzhi(zhizhen)];

fuzhijishu++;

}

//交叉與變異的實現

//交叉

for(i=0;i<zhongqunshu1;i++)

{

peiduishuzu[i]=-1;

}

for (i=0; i<zhongqunshu1; i++)

{

temp =rnd(0,zhongqunshu1-1); //產生值在0-zhongqunshu1-1的隨機數

while(Exist(temp, i, peiduishuzu))//判斷產生的隨機數是否已經產生過,如果是,則再產生壹個隨機數

{

temp =rnd(0,zhongqunshu1-1);

}

//如果沒有的話,則把產生的隨機數放在peiduishuzu中

*(peiduishuzu+i) = temp;

}

for(i=0;i<zhongqunshu1-1;i=i+2)

{

fuqin1=pipeichi[peiduishuzu[i]];

fuqin2=pipeichi[peiduishuzu[i+1]];

crossover(fuqin1,fuqin2,newpop[i],newpop[i+1]);

}

for(j=0;j<zhongqunshu1;j++)

{

//if(newpop[j].geti<-1000)

//cout<<"個體數值小於下界了";

nowpop[j].geti=newpop[j].geti;

}

//

guanjiancanshujisuan();

//變異的實現

for(j=0;j<zhongqunshu;j++)

{

bianyi(nowpop[j]);

}

//

guanjiancanshujisuan();

//精英保留的實現

jingyingbaoliu();

//

guanjiancanshujisuan();

delete [] peiduishuzu;

delete [] pipeichi;

delete [] pipeiguodu;

}

void crossover(individual parent1,individual parent2,individual &child1,individual &child2)//交叉

{

int j;

unsigned *panduan;

panduan=new unsigned[lchrom];

parent1.chrom=new unsigned[lchrom];

parent2.chrom=new unsigned[lchrom];

child1.chrom=new unsigned[lchrom];

child2.chrom=new unsigned[lchrom];

//cout<<"jiaocha"<<endl;///////////////////////

bianma(parent1.geti,parent1.chrom);

bianma(parent2.geti,parent2.chrom);

if(flipc(parent1.fitness,parent2.fitness))

{

for(j=0;j<lchrom;j++)

panduan[j]=rnd(0,1);

//for(j=0;j<lchrom;j++)////////////////

// {

// cout<<panduan[j];/////////////

// }

// cout<<endl;////////////////

// system("pause");////////////////

for(j=0;j<lchrom;j++)

{

if(panduan[j]==1)

child1.chrom[j]=parent1.chrom[j];

else

child1.chrom[j]=parent2.chrom[j];

}

for(j=0;j<lchrom;j++)

{

if(panduan[j]==0)

child2.chrom[j]=parent1.chrom[j];

else

child2.chrom[j]=parent2.chrom[j];

}

//for(j=0;j<lchrom;j++)////////////////

//{

// cout<<child1.chrom[j];/////////////

// }

//cout<<endl;////////////////

// system("pause");////////////////

child1.geti=yima(child1.chrom);

child2.geti=yima(child2.chrom);

delete [] child2.chrom;

delete [] child1.chrom;

delete [] parent2.chrom;

delete [] parent1.chrom;

delete [] panduan;

}

else

{

for(j=0;j<lchrom;j++)

{

child1.chrom[j]=parent1.chrom[j];

child2.chrom[j]=parent2.chrom[j];

}

child1.geti=yima(child1.chrom);

child2.geti=yima(child2.chrom);

delete [] child2.chrom;

delete [] child1.chrom;

delete [] parent2.chrom;

delete [] parent1.chrom;

delete [] panduan;

}

}

void bianyi(individual &child)//變異

{

child.chrom=new unsigned[lchrom];

//cout<<"變異"<<endl;

bianma(child.geti,child.chrom);

for(int i=0;i<lchrom;i++)

if(flipm(child.fitness))

{

if(child.chrom[i]=0)

child.chrom[i]=1;

else

child.chrom[i]=0;

}

child.geti=yima(child.chrom);

delete [] child.chrom;

}

void bianma(double bianliang,unsigned *p)//編碼

{

unsigned *q;

unsigned *gray;

q=new unsigned[lchrom];

gray=new unsigned[lchrom];

int x=0;

int i=0,j=0;

if(bianliang<zuobianjie)///////////////////

{

cout<<"bianliang:"<<bianliang<<endl;/////////

system("pause");

}

//cout<<youbianjie-(zuobianjie)<<endl;

//system("pause");

x=(bianliang-(zuobianjie))*((pow(2,lchrom)-1)/(youbianjie-(zuobianjie)));

//cout<<x<<endl;///////////

if(x<0)

system("pause");///////////

for(i=0;i<lchrom;i++)

{

q[i]=0;

p[i]=0;

}

i=0;

while (x!=0&&(i!=lchrom))

{

q[i]=(unsigned)(x%2);

x=x/2;

i++;

}

// for(i=0;i<lchrom;i++)//////////////////

// cout<<q[i];///////////////

// cout<<endl;///////////

int w=lchrom-1;

if(q[w]!=0&&q[w]!=1)

system("pause");

for(j=0;j<lchrom&&w>0;j++)

{

p[j]=q[w];

w--;

}

//cout<<"yuanma"<<endl;

//for(j=0;j<lchrom;j++)///////////

// cout<<p[j];////////

//cout<<endl;////////////////////

gray[0]=p[0];

for(j=1;j<lchrom;j++)

{

if(p[j-1]==p[j])

gray[j]=0;

else if(p[j-1]!=p[j])

gray[j]=1;

}

for(j=0;j<lchrom;j++)

p[j]=gray[j];

//cout<<"geleima"<<endl;

//for(j=0;j<lchrom;j++)///////////

// cout<<p[j];////////

//cout<<endl;////////////////////

//system("pause");///////////

delete [] gray;

delete [] q;

}

double yima(unsigned *p) //譯碼

{

int i=0;

// for(i=0;i<lchrom;i++)/////////

// {

// cout<<p[i];//////

// }

// cout<<endl;/////////

// system("pause");//////////

int x=0;

unsigned *q;

q=new unsigned[lchrom];

q[0]=p[0];

// cout<<q[0]<<endl;//////////////////

// system("pause");//////////

for(int j=1;j<lchrom;j++)

{

if(q[j-1]==p[j])

q[j]=0;

else if(q[j-1]!=p[j])

q[j]=1;

}

// for(i=0;i<lchrom;i++)//////

// {

// cout<<q[i];//////////

// if(q[i]!=0&&q[i]!=1)

// {

// cout<<q[i];

// system("pause");

// }

// }

// cout<<endl;////////

// system("pause");///////////////////

for(i=0;i<lchrom;i++)

x=x+q[i]*pow(2,(lchrom-i-1));

if(x<0)

{

cout<<"譯碼出錯1"<<endl;

system("pause");

}

//cout<<"x:"<<x<<endl;

double bianliang;

//cout<<pow(2,22)<<endl;

//cout<<2000*x<<endl;

//cout<<(x*(2000/(pow(2,22)-1)))<<endl;

bianliang=(x*((youbianjie-(zuobianjie))/(pow(2,lchrom)-1)))+zuobianjie;

if(bianliang<zuobianjie)

{

cout<<"譯碼出錯2"<<endl;

system("pause");

}

delete [] q;

return bianliang;

}

double ran1(long *idum)

{

int j;

long k;

static long idum2=123456789;

static long iy=0;

static long iv[NTAB];

float temp;

if (*idum <= 0)

{

if (-(*idum) < 1) *idum=1;

else *idum = -(*idum);

idum2=(*idum);

for (j=NTAB+7;j>=0;j--)

{

k=(*idum)/IQ1;

*idum=IA1*(*idum-k*IQ1)-k*IR1;

if (*idum < 0) *idum += IM1;

if (j < NTAB) iv[j] = *idum;

}

iy=iv[0];

}

k=(*idum)/IQ1;

*idum=IA1*(*idum-k*IQ1)-k*IR1;

if (*idum < 0) *idum += IM1;

k=idum2/IQ2;

idum2=IA2*(idum2-k*IQ2)-k*IR2;

if (idum2 < 0) idum2 += IM2;

j=iy/NDIV;

iy=iv[j]-idum2;

iv[j] = *idum;

if (iy < 1) iy += IMM1;

if ((temp=AM*iy) > RNMX) return RNMX;

else return temp;

}

double suijibianli()//隨機遍歷

{

double i=ran1(a);

while(i>zhizhenjuli)

{

i=ran1(a);

}

//cout<<i<<endl;//////////////

return i;

}

int fuzhi(float p)//復制

{

int i;

double sum=0;

if(sumfitness!=0)

{

for(i=0;(sum<p)&&(i<zhongqunshu);i++)

sum+=nowpop[i].fitness/sumfitness;

}

else

i=rnd(1,zhongqunshu1);

return(i-1);

}

int rnd(int low, int high) /*在整數low和high之間產生壹個隨機整數*/

{

int i;

if(low >= high)

i = low;

else

{

i =(int)((ran1(a) * (high - low + 1)) + low);

if(i > high) i = high;

}

return(i);

}

int flipc(double p,double q)//判斷是否交叉

{

double pc1=0.9,pc2=0.6;

if((p-q)>0)

{

if(p>=avefitness)

{

pc=pc1-(pc1-pc2)*(p-avefitness)/(maxfitness-avefitness);

}

else

pc=pc1;

}

else

{

if(q>=avefitness)

{

pc=pc1-(pc1-pc2)*(q-avefitness)/(maxfitness-avefitness);

}

else

pc=pc1;

}

if(ran1(a)<=pc)

return(1);

else

return(0);

}

int flipm(double p)//判斷是否變異

{

double pm1=0.001,pm2=0.0001;

if(p>=avefitness)

{

pm=(pm1-(pm1-pm2)*(maxfitness-p)/(maxfitness-avefitness));

}

else

pm=pm1;

if(ran1(a)<=pm)

return(1);

else

return(0);

}

void glp(int n,int s,int *h,int (*q)[1],float (*xx)[1])//glp

{

int i=0,j=0;

//求解q

for(i=0;i<n;i++)

{

for(j=0;j<s;j++)

{

*(*(q+i)+j)=((i+1)*(*(h+j)))%n;

}

}

i=n-1;

for(j=0;j<s;j++)

{

*(*(q+i)+j)=n;

}

//求解x

for(i=0;i<n;i++)

{

for(j=0;j<s;j++)

{

*(*(xx+i)+j)=(float)(2*(*(*(q+i)+j))-1)/(2*n);

}

}

}

BOOL Exist(int Val, int Num, int *Array)//判斷壹個數是否在壹個數組的前Num個數中

{

BOOL FLAG = FALSE;

int i;

for (i=0; i<Num; i++)

if (Val == *(Array + i))

{

FLAG = TRUE;

break;

}

return FLAG;

}

  • 上一篇:請問開關主題怎麽改?
  • 下一篇:排序題怎麽評分
  • copyright 2024編程學習大全網