遺傳演算法求解最大值
㈠ 遺傳演算法默認的是求最大值么
Matlab工具箱函數 ga 是求最小值,所有優化工具箱函數都是求最小值,你如果要求最大值,把目標函數取負,然後求得最小值實際上就是原始目標函數的最大值了。這也是為什麼matlab里所有優化工具箱函數都是求最小值了
㈡ 用遺傳演算法求極值和求最大值在計算時哪裡的步驟不一樣
導數為零的點都是極值點,其中最大的點就是最大值點。
遺傳演算法不用在演算法中特意區分極值點和最大值點。
只有在求解多目標優化問題時涉及到非劣解的概念,這時求出的非劣解邊緣就是極值點(相對最優點)。
否則的話遺傳演算法最忌諱的就是陷入局部最優點(就是極值點),所以大家都盡量避免演算法收斂於局部極值點,沒有人特意去求所有的極值點的。
㈢ matlab遺傳演算法編程求最大值的問題
(1)關於fitness value,你要自己定義一個函數,如你所說從25個x變數經過一系列運算得到y值 可以其作專為屬fitness value
(2)由於x的取值是離散的 染色體不一定要是二進制 最簡單的做法是一個5進制的長為25的串
㈣ 求助:人工智慧「遺傳演算法求解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畫圖驗證了,沒問題。
希望再給加點分,呵呵
//中國電子科技集團公司
//第一研究室
//呼文韜
//[email protected]
//隨機初始種群
//編碼方式為格雷碼
//選擇方法為隨機遍歷
//採用了精英保存策略
//採用了自適應的交叉率和變異率
//採用了與模擬退火演算法相結合的尺度變換
//採用了均勻交叉法
#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 zhenjuli 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 hunn;
//double c=4;
//設置全局變數
struct indivial
{
unsigned *chrom; //染色體;
double geti;//變數值
double shiying; //目標函數的值;
double fitness; //變換後的適應度值;
};
indivial *zuiyougeti;//精英保存策略
int zhongqunshu; //種群大小
indivial *nowpop;//當前代
indivial *newpop;//新一代
double sumfitness;//當代的總適應度fitness
double sumshiying;//當代的總適應度shiying
double maxfitness;//最大適應度
double avefitness;//平均適應度
double maxshiying;//最大適應度
double avgshiying;//平均適應度
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 fu(float );//選擇要復制的個體
void crossover(indivial ,indivial ,indivial &,indivial &);//交叉
void bianyi(indivial &);//變異
void mubiaohanshu(indivial &);//計算適應度
void chibianhuan(indivial &);//對shiying進行尺度變換賦給fitness
double ran1(long *);//隨機數初始
void bianma(double bianliang,unsigned *p);//編碼
double yima(unsigned *p);
void guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成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=((indivial *)p1)->shiying;//現在是按照"適應度"排序,改成"個體"的話就是按照"個體"排序
float j=((indivial *)p2)->shiying;
return i<j ? -1:(i==j ? 0:1);//現在是按升序牌排列,將1和-1互換後就是按降序排列
}
void main()
{
initialize();
cout<<zuiyougeti->geti<<" "<<zuiyougeti->shiying<<endl;/////////////
for(gen=1;gen<maxgen;gen++)
{ generation();
}
jingyingbaoliu();
cout<<setiosflags(ios::fixed)<<setprecision(6)<<zuiyougeti->geti<<" "<<setiosflags(ios::fixed)<<setprecision(6)<<(zuiyougeti->shiying)<<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 indivial;//最優個體的生成
zhongqunshu=200;//種群數量
nowpop=new indivial[zhongqunshu1];//當代
newpop=new indivial[zhongqunshu1];//新一代
maxgen=150;//最大代數
gen=0;//起始代
lchrom=22;//基因數量的初始化
mysrand(time(0));//隨機數種子
a[0]=seed;//隨機數種子
//對最優個體的初始化
zuiyougeti->geti=0;
zuiyougeti->fitness=0;
zuiyougeti->shiying=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();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
}
void jingyingbaoliu() //精英保留的實現
{
indivial *zuiyougetiguo;
zuiyougetiguo=new indivial[zhongqunshu1];//建立一個過渡數組
for(int i=0;i<zhongqunshu;i++)//將當代個體復制到過渡數組中
zuiyougetiguo[i]=nowpop[i];
qsort(zuiyougetiguo,zhongqunshu1,sizeof(indivial),&cmpfitness);//按fitness升序排序
// cout<<"zuiyougetiguo適應度:"<<zuiyougetiguo[zhongqunshu1-1].shiying<<endl;///////////
// cout<<"zuiyougeti適應度:"<<zuiyougeti->shiying<<endl;///////////////////
//system("pause");
if(zuiyougetiguo[zhongqunshu-1].shiying>zuiyougeti->shiying)
{
*zuiyougeti=zuiyougetiguo[zhongqunshu1-1];//如果最優個體的fitness比當代最大的fitness小則用當代的代替之
//cout<<"zuiyougetiguo個體:"<<zuiyougetiguo[zhongqunshu1-1].geti<<endl;/////////////
//cout<<"zuiyougeti個體:"<<zuiyougeti->geti<<endl;/////////////
}
else
nowpop[rnd(0,(zhongqunshu1-1))]=*zuiyougeti;//否則的話從當代中隨機挑選一個用最優個體代替之
delete [] zuiyougetiguo;//釋放過渡數組
}
void guanjiancanshujisuan()//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
{
for(int i=0;i<zhongqunshu;i++)//計算shiying
mubiaohanshu(nowpop[i]);
for(i=0;i<zhongqunshu;i++)//對shiying進行尺度變換變成fitness
chibianhuan(nowpop[i]);
preselectfitness();//根據fitness計算sumfitness,avefitness,maxfitness
}
void mubiaohanshu(indivial &bianliang)//計算shiying
{
bianliang.shiying=(bianliang.geti*cos(bianliang.geti)+2.0);//目標函數
}
void chibianhuan(indivial &bianliang)//對shiying進行尺度變換變成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].shiying/T);
bianliang.fitness=exp(bianliang.shiying/T)/sum;//算出fitness
}
void preselectfitness()//根據fitness計算sumfitness,avefitness,maxfitness
{
int j;
sumfitness=0;
for(j=0;j<zhongqunshu;j++)
sumfitness+=nowpop[j].fitness;
indivial *guo;
guo=new indivial[zhongqunshu1];
for(j=0;j<zhongqunshu;j++)
guo[j]=nowpop[j];
qsort(guo,zhongqunshu1,sizeof(indivial),&cmpfitness);
maxfitness=guo[zhongqunshu1-1].fitness;
avefitness=sumfitness/zhongqunshu1;
delete [] guo;
}
void generation()
{
indivial fuqin1,fuqin2,*pipeiguo,*pipeichi;
int *peiishuzu;//用來存放產生的隨機配對
pipeiguo=new indivial[zhongqunshu1];
pipeichi=new indivial[zhongqunshu1];
peiishuzu=new int[zhongqunshu1];
int member1,member2,j=0,fujishu=0,i=0,temp=0,tt=0;
float zhen;
//隨機遍歷的實現
for(zhen=suijibianli();zhen<1;(zhen=zhen+zhenjuli))//設定指針1/66
{
pipeichi[fujishu]=nowpop[fu(zhen)];
fujishu++;
}
//交叉與變異的實現
//交叉
for(i=0;i<zhongqunshu1;i++)
{
peiishuzu[i]=-1;
}
for (i=0; i<zhongqunshu1; i++)
{
temp =rnd(0,zhongqunshu1-1); //產生值在0-zhongqunshu1-1的隨機數
while(Exist(temp, i, peiishuzu))//判斷產生的隨機數是否已經產生過,如果是,則再產生一個隨機數
{
temp =rnd(0,zhongqunshu1-1);
}
//如果沒有的話,則把產生的隨機數放在peiishuzu中
*(peiishuzu+i) = temp;
}
for(i=0;i<zhongqunshu1-1;i=i+2)
{
fuqin1=pipeichi[peiishuzu[i]];
fuqin2=pipeichi[peiishuzu[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 [] peiishuzu;
delete [] pipeichi;
delete [] pipeiguo;
}
void crossover(indivial parent1,indivial parent2,indivial &child1,indivial &child2)//交叉
{
int j;
unsigned *panan;
panan=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++)
panan[j]=rnd(0,1);
//for(j=0;j<lchrom;j++)////////////////
// {
// cout<<panan[j];/////////////
// }
// cout<<endl;////////////////
// system("pause");////////////////
for(j=0;j<lchrom;j++)
{
if(panan[j]==1)
child1.chrom[j]=parent1.chrom[j];
else
child1.chrom[j]=parent2.chrom[j];
}
for(j=0;j<lchrom;j++)
{
if(panan[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 [] panan;
}
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 [] panan;
}
}
void bianyi(indivial &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 *im)
{
int j;
long k;
static long im2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*im <= 0)
{
if (-(*im) < 1) *im=1;
else *im = -(*im);
im2=(*im);
for (j=NTAB+7;j>=0;j--)
{
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
if (j < NTAB) iv[j] = *im;
}
iy=iv[0];
}
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
k=im2/IQ2;
im2=IA2*(im2-k*IQ2)-k*IR2;
if (im2 < 0) im2 += IM2;
j=iy/NDIV;
iy=iv[j]-im2;
iv[j] = *im;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
double suijibianli()//隨機遍歷
{
double i=ran1(a);
while(i>zhenjuli)
{
i=ran1(a);
}
//cout<<i<<endl;//////////////
return i;
}
int fu(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;
}
㈤ 利用遺傳演算法求解區間【0,31】上的二次函數y=x*x的最大值(MATLAB/C語言都行),謝謝
你可以自己先做一做,我也可以給你一個C程序參考
㈥ 遺傳演算法 求函數最大值
用matlab直接用工具箱
㈦ Matlab遺傳演算法求函數最大值
figure(1);
fplot('variable.*sin(10*pi*variable)+2.0',[-1,2]);
NIND=40;
MAXGEN=25;
PRECI=20;
GGAP=0.9;
trace=zeros(2,MAXGEN);
FieldD=[20;-1;2;1;0;1;1];
Chrom=CRTBP(NIND,PRECI);
gen=0;
variable=BS2RV(Chrom,FieldD);
ObjV=variable.*sin(10*pi*variable)+2.0;
while gen<MAXGEN,
FitnV=ranking(-ObjV);
SelCh=SELECT('SUS',Chrom,FitnV,GGAP);
SelCh=RECOMBIN('XOVSP',SelCh,0.7)
SelCh=MUT(SelCh);
variable=BS2RV(SelCh,FieldD);
ObjVSel=variable.*sin(10*pi*variable)+2.0;
[Chrom,ObjV]=REINS(Chrom,SelCh,1,1,ObjV,ObjVSel);
gen=gen+1;
[Y,I]=max(ObjV),hold on;
plot(variable(I),Y,'bo');
trace(1,gen)=max(ObjV);
trace(2,gen)=sum(ObjV)/length(ObjV);
end
variable=BS2RV(Chrom,FieldD);
hold on;
grid;
plot(variable',ObjV','b*');
figure(2);
plot(trace(1,:)');
hold on;
plot(trace(2,:)','-.');
grid;
看看這個能用得上么
㈧ 遺傳演算法matlab編程求函數最大值
X1X2要先轉成二進制編碼,然後取隨機數,從X1X2中,按這個隨機數指定的位置開始交換數據,然後轉回十進制.染色體還需要拆開嗎?
求最大值:
len = length(fit);
max = fit(1);
position = 1;
for i=2:len
if max<fit(i)
max = fit(i);
position = i;
end
end
㈨ MATLAB用遺傳演算法ga求最大值中的最小值
MATLAB用遺傳演算法ga求含有最大值的最小值問題專,可以這樣處理:由屬於最大值問題的反問題就是最小值問題,所以 max=-min。因此,你的問題就可以改寫為
min ( min -(3*x1+4*x2+...))