?? 遺傳算法f1.cpp
字號(hào):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
//#include <values.h>
#include <string.h>
//定義控制參數(shù)
#define POPSIZE 200 //定義種群的大小
#define NVARS 2 //定義參數(shù)的個(gè)數(shù)
#define PXOVER 0.9 //定義交叉率
#define PMUTATION 0.15 //定義突變率
typedef struct //定義基因,種群中的一個(gè)個(gè)體
{
double chrom[NVARS]; //變量串(本例中是a,b,c三參數(shù))
double lsquare; //個(gè)體的適應(yīng)度,存放的是評(píng)價(jià)函數(shù)的返回值,即誤差平方和的大小
double r; //個(gè)體的相關(guān)系數(shù)
int fitness; //相關(guān)適應(yīng)度
}individual;
static individual newpop[POPSIZE+1]; //新種群
static individual oldpop[POPSIZE+1]; //老種群
static int location[POPSIZE+1]; //排序后的個(gè)體的位置
static int gen; //當(dāng)前代數(shù)
static int maxgen=1000; //最大代數(shù)
static int change=0; //適應(yīng)性沒(méi)有改進(jìn)的代數(shù)
static double a[NVARS],b[NVARS]; //變量的上下限 a[]下限,b[]上限
//隨機(jī)數(shù)發(fā)生器的宏定義
#define rdint(i) (rand()%(int)(i))
#define rdft() ((double)rdint(16384)/(16383.0))
#define rnd(a,b) (rdint((int)(b)-(int)(a)+1)+(int)(a))
//評(píng)估函數(shù):使用到用戶定義的衰減模型,每次如果被改變則要重新編譯,當(dāng)前所用的模型是f(x)=a-b*c^x
//返回值是誤差的平方和,顯然返回值越大則表示評(píng)價(jià)的結(jié)果越差
double evaluate(double *prms) //參數(shù)為個(gè)體基因中的參數(shù)串charm[]
{
double x, serr=0.0;
x=sqrt(prms[0]*prms[0]+prms[1]*prms[1]);
serr=0.5-(pow(sin(x),2)-0.5)/pow((1+0.001*(prms[0]*prms[0]+prms[1]*prms[1])),2);
return (serr);
}
//用于確定數(shù)組選擇區(qū)域函數(shù),通過(guò)快速排序法實(shí)現(xiàn),(二分法排序,降序)
void quick_sort(double *item,int left,int right,int *locat) //<號(hào)升序>號(hào)降序
//item:需排序的數(shù)組,left:數(shù)組的下標(biāo)下界,
//right:數(shù)組的下標(biāo)上界,locat:數(shù)組中各元素在原數(shù)組中的位置
//求最大值則用升序,求最小值用降序
{ int i,j,k;
double fa,fb;
i=left; j=right;
fa=item[(left+right)/2];
do{
while((item[i]<fa)&&(i<right)) i++;
while((fa<item[j])&&(j>left)) j--;
if(i<=j)
{
fb=item[i];
item[i]=item[j];
item[j]=fb;
k=locat[i];
locat[i]=locat[j];
locat[j]=k;
i++;j--;
}
}while(i<=j);
if(left<j) quick_sort(item,left,j,locat);
if(i<right) quick_sort(item,i,right,locat);
}
//用于確定在種群中的個(gè)體選擇位置和規(guī)格化適應(yīng)度的函數(shù)
void normalfitness(individual *pop) //參數(shù)是種群數(shù)組newpop[]等
{
double fit[POPSIZE];
int i;
for(i=0;i<POPSIZE;i++)
{
fit[i]=pop[i].lsquare; //個(gè)體的適應(yīng)性
location[i]=i;
}
quick_sort(fit,0,POPSIZE-1,location); //按適應(yīng)度由大到小排序
for(i=0;i<POPSIZE;i++)
pop[location[i]].fitness=2*(i+1); //重新計(jì)算適應(yīng)度,計(jì)算后原先適應(yīng)度大的將變小
//因初始適應(yīng)度是用評(píng)價(jià)函數(shù)的返回值表示的,而評(píng)價(jià)函數(shù)返回的是誤差,
//故原先的適應(yīng)度大的表示實(shí)際誤差大,實(shí)際的適應(yīng)性較差
//規(guī)格化運(yùn)算后,適應(yīng)度的值正比地 反映了該個(gè)體的適應(yīng)程度
}
//初始化種群的函數(shù),用隨機(jī)生成的數(shù)初始化參數(shù)a,b,c;
//用評(píng)估函數(shù)的返回值作為個(gè)體的適應(yīng)度,同時(shí)規(guī)格化適應(yīng)度確定個(gè)體的選擇位置
void initpop(void)
{
int i,j;
for(i=0;i<POPSIZE;i++)
{
for(j=0;j<NVARS;j++)
oldpop[i].chrom[j]=a[j]+rdft()*(b[j]-a[j]);//個(gè)體中的參數(shù)a,b,c隨即生成
oldpop[i].lsquare=evaluate(oldpop[i].chrom);//用評(píng)估函數(shù)的返回值作為個(gè)體的適應(yīng)度
//可見(jiàn)評(píng)估函數(shù)值越小則適應(yīng)性越強(qiáng)
oldpop[i].fitness=0;
}
normalfitness(oldpop);//確定個(gè)體的選擇位置和規(guī)格化適應(yīng)度
oldpop[POPSIZE]=oldpop[location[POPSIZE-1]];
}
//選擇函數(shù):采用賭盤選擇方法
int select(individual *pop)
{
double rand1;
int partsum=0;
int i=0;
rand1=rdft()*POPSIZE*(POPSIZE+1);
for(i=0;(rand1>=partsum);i++)
partsum+=pop[i].fitness;//部分和是基因適應(yīng)度的和
return (i-1);
}
//突變:
double mutate(int i)
{
return a[i]+rdft()*(b[i]-a[i]);//產(chǎn)生參數(shù)上下限內(nèi)的隨機(jī)數(shù)
}
//交叉和突變函數(shù):數(shù)學(xué)交叉
void xover(double *parent1,double *parent2,double *child1,double *child2)
//參數(shù)為個(gè)體基因中的參數(shù)串charm[]
{
double alpha;
int 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(rdft()<PMUTATION)
child1[i]=mutate(i);
if(rdft()<PMUTATION)
child2[i]=mutate(i);
}
}
//初始化函數(shù):
void initialize(void) //void initialize(int argc,char *argv[])
{
srand(time(NULL)); //初始化隨機(jī)函數(shù)發(fā)生器
printf("非線性參數(shù)進(jìn)化評(píng)估器\n");
printf("G-代數(shù) U-沒(méi)有改變的代數(shù)");
printf("ERR-最小平方誤差 r-相關(guān)系數(shù)\n\n");
printf("輸入?yún)?shù)的下限和上限\n");
a[0]=-100;
a[1]=-100;
b[0]=100;
b[1]=100;
location[POPSIZE]=POPSIZE;
initpop(); //初始化種群
}
//重組函數(shù):通過(guò)選擇、交叉和變異由老的一代產(chǎn)生新的一代
void recombine(void)
{
int i=0;
int mate1,mate2;
while(i<POPSIZE){
//從老一代中選擇兩個(gè)雙親
mate1=select(oldpop);
do
{
mate2=select(oldpop);
}while(mate1==mate2);
//對(duì)選擇的個(gè)體進(jìn)行交叉和突變操作
if(rdft()<PXOVER)
{
xover(oldpop[mate1].chrom,oldpop[mate2].chrom,
newpop[i].chrom,newpop[i+1].chrom);
newpop[i].lsquare=evaluate(newpop[i].chrom); //確定交叉后產(chǎn)生的新個(gè)體的適應(yīng)度
newpop[i+1].lsquare=evaluate(newpop[i+1].chrom);
}
else
{
newpop[i]=oldpop[mate1];
newpop[i+1]=oldpop[mate2];
}
i+=2;
}
//在新的種群中隨機(jī)選擇一個(gè)個(gè)體,若它比原種群中最好的個(gè)體好,則替代它,否則不做改變
i=rnd(0,POPSIZE-1);
if(newpop[i].lsquare<oldpop[POPSIZE].lsquare)
newpop[i]=oldpop[POPSIZE];
// printf("\n######################################################################\n");
normalfitness(newpop); //確定個(gè)體在種群中的選擇位置和規(guī)格化適應(yīng)度
//printf("\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
//如果新的種群中的最好的個(gè)體比過(guò)去的種群中的最好的個(gè)體好,
//就從新的種群中拷貝這個(gè)最好的否則用過(guò)去的種群中的最好的個(gè)體替代當(dāng)前的最好個(gè)體
//注意:這個(gè)最好的個(gè)體不包括直接進(jìn)化產(chǎ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) //結(jié)果報(bào)告
{
int i;
printf("\r G=%3d U=%2d change=%d ",gen,change,gen-change);
for(i=0;i<NVARS;i++)
printf("par%d=%lf ",i,newpop[POPSIZE].chrom[i]);
printf("err=%lf\n",newpop[POPSIZE].lsquare);
//printf("\n************************************************************************\n");
}
//主函數(shù):
void main(void) //void main(int argc,char *argv[])
{
int i;
gen=0;
initialize(); //initialize(argc,argv);
for(gen=1;gen<=maxgen;gen++)
{
recombine();
report(gen);
//拷貝新種群到老種群
for(i=0;i<=POPSIZE;i++)
oldpop[i]=newpop[i];
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -