遗传算法求解yx2副本Word格式.docx
《遗传算法求解yx2副本Word格式.docx》由会员分享,可在线阅读,更多相关《遗传算法求解yx2副本Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
的适应值,显然,适应值最高的个体被随机选定的概率就越大,被选择的次数就越多,从而被繁殖的次数也就越多。
(2)单点交叉。
单点交叉又称简单交叉,是遗传算法所使用的交叉操作方法。
选择一个交叉点,子代在交叉点前面的基因从一个父代基因那里得到,后面的部分从另外一个父代基因那里得到。
如:
交叉前:
100|10
101|01
交叉后:
100|01
101|10
(3)基本位变异。
基本位变异石最简单和最基本的变异操作,也是基本遗传算法中所使用的变异操作方法。
对于基本遗传算法中用二进制编码符号串所表示的个体,对需要进行变异操作的某一基因,若原有基因值为0,则变异操作将该基因值变为1;
反之,若原有基因值为1,则变异操作将其变为0.
基本位变异算子是指对个体编码串随机指定的某一位或某几位基因作变异运算。
对于基本遗传算法中用二进制编码符号串所表示的个体,若需要进行变异操作的某一基因座上的原有基因值为0,则变异操作将其变为1;
反之,若原有基因值为1,则变异操作将其变为0。
变异前:
1001|0
变异后:
1001|1
(4)基本遗传算法的运行参数
本例中指定四个基本参数
种群大小:
popsize
最大世代数maxgeneration
交叉率pc
变异率pm
至于遗传算法的终止条件,还可以利用某种判定准则,当判定出群体已经进化成熟且不再有进化趋势时就可终止算法的运行过程。
如连续几代个体平均适应度的差异小于某一个极小的值;
或者群体中所有个体适应度的方差小于某一个极小的值。
这4个参数对遗传算法的搜索结果及搜索效率都有一定的影响,目前尚无合理选择它们的理论根据在遗传算法的实际应用中,往往需要经过多次的试算后才能确定出这些参数合理的取值范围或取值大小
4、遗传算法的应用步骤如下:
遗传算法提供了一种求解复杂系统优化问题的通用框架,它不依赖于问题的领域和种类。
对一个需要进行优化计算的实际应用问题,一般可按下述步骤来构造求解该问题的遗传算法。
第一步:
建立优化模型,即确定出目标函数、决策变量及各种约束条件以及数学描述形式或量化方法。
第二步:
确定表示可行解的染色体编码方法,也即确定出个体的基因型x及遗传算法的搜索空间。
第三步:
确定解码方法,即确定出个体基因型x到个体表现型x的对应关系或转换方法。
第四步:
确定个体适应度的量化评价方法,即确定出由目标函数值
到个体适应度
的转换规则。
第五步:
设计遗传操作方法,即确定出选择运算、交叉运算、变异运算等具体操作方法。
第六步:
确定遗传算法的有关运行参数,即确定出遗传算法的种群大小(popsize)、最大世代数(maxgeneration)、交叉率(pc)、变异率(pm)等参数。
由上述构造步骤可以看出,可行解的编码方法、遗传操作的设计是构造遗传算法时需要考虑的两个主要问题,也是设计遗传算法时的两个关键步骤。
对不同的优化问题需要使用不同的编码方法和不同的遗传操作,它们与所求解的具体问题密切相关,因而对所求解问题的理解程度是遗传算法应用成功与否的关键。
本例c语言代码
////////////////////////////////////
//遗传算法解决y=x2问题
//编译环境vc++6.0
//声明:
部分代码来自网
#include<
stdio.h>
#include<
stdlib.h>
time.h>
math.h>
#definePOPSIZE500//种群大小
#definechromlength5//染色体长
intpopsize;
//种群大小
intmaxgeneration;
//最大世代数
doublepc=0.0;
//交叉率
doublepm=0.0;
//变异率
structindividual//定义染色体个体结构体
{
intchrom[chromlength];
//定义染色体二进制表达形式,editbyppme将char转为int
doublevalue;
//染色体的值
doublefitness;
//染色体的适应值
};
intgeneration;
//当前执行的世代数
intbest_index;
//最好的染色体索引序号
intworst_index;
//最差的染色体索引序号
structindividualbestindividual;
//最佳染色体个体
structindividualworstindividual;
//最差染色体个体
structindividualcurrentbest;
//当前最好的染色体个体currentbest
structindividualpopulation[POPSIZE];
//种群数组
//函数声明
voidgenerateinitialpopulation();
//ok-初始化当代种群
voidgeneratenextpopulation();
//产生下一代种群
voidevaluatepopulation();
//评价种群
voidcalculateobjectfitness();
//计算种群适应度
doubledecodechromosome(int,int);
//染色体解码
voidfindbestandworstindividual();
//寻找最好的和最坏的染色体个体
voidperformevolution();
//进行演变进化
voidselectoperator();
//选择操作
voidcrossoveroperator();
//交换操作
voidmutationoperator();
//变异操作
voidinput();
//输入接口
voidoutputtextreport();
//输出文字报告
voidmain()//主函数
{
inti;
srand((unsigned)time(NULL));
//强制类型转化,以当前时间戳定义随机数种子
printf("
本程序为求函数y=x*x的最大值\n"
);
generation=0;
//初始化generation当前执行的代
input();
//初始化种群大小、交叉率、变异率
/*editbyppme*/
//调试用。
。
显示input()结果
种群规模(popsize):
%d;
\n最大世代数(maxgeneration)%d;
\n交叉率(pc)%f;
变异率(pm)%f\n\n"
popsize,maxgeneration,pc,pm);
generateinitialpopulation();
//产生初始化种群
evaluatepopulation();
//评价当前种群,(A.计算种群/个体的适应度;
B.找出最好和最差的个体)
while(generation<
maxgeneration)//小于最大世代数,执行循环体
{
generation++;
generatenextpopulation();
//生成子代种群(A.选择;
B.交叉;
C.变异)
evaluatepopulation();
//评价新生子代种群
performevolution();
//进行子代进化
outputtextreport();
//输入当代最终种群
}
\n"
统计结果:
"
最大函数值等于:
%f\n"
currentbest.fitness);
其染色体编码为:
"
//计算currentbest的value
for(i=0;
i<
chromlength;
i++)
printf("
%d"
currentbest.chrom[i]);
}
voidgenerateinitialpopulation()//种群初始化
inti,j;
for(i=0;
i<
popsize;
i++)
for(j=0;
j<
chromlength;
j++)
{
population[i].chrom[j]=(rand()%10<
5)?
0:
1;
//rand()%10随机产生0-9的整数
//,小于5标注0,否则标注1
}
//调试显示初始化结果
显示初始化结果:
for(i=0;
popsize;
for(j=0;
j<
j++)
population[i].chrom[j]);
}
voidgeneratenextpopulation()//生成下一代
selectoperator();
crossoveroperator();
mutationoperator();
voidevaluatepopulation()//评价种群?
?
calculateobjectfitness();
//计算种群?
个体的适应度
findbestandworstindividual();
//赵到最好和最差的染色体个体
voidcalculateobjectfitness()//计算染色体个体适应值和适应度
intj;
calculateobjectfitnessisexecuting!
for(i=0;
i++)
doubletemp;
temp=decodechromosome(i,chromlength);
//计算个体适应值
population[i].value=(double)temp;
population[i].fitness=population[i].value*population[i].value;
//调试用
显示当前种群结果:
for(j=0;
printf("
%lf"
population[i].value);
population[i].fitness);
doubledecodechromosome(intpop_index,intlength)//给染色体解码
doubledecimal=0;
for(i=length;
i>
=0;
i--)
decimal+=population[pop_index].chrom[i]*pow(2,i);
//遍历染色体二进制编码,
return(decimal);
//并计算出其10进制的value值
voidfindbestandworstindividual()//求最佳个体和最差个体
doublesum=0.0;
bestindividual=population[0];
worstindividual=population[0];
for(i=1;
if(population[i].fitness>
bestindividual.fitness)//依次比较,找出最佳个体
bestindividual=population[i];
best_index=i;
elseif(population[i].fitness<
worstindividual.fitness)//依次比较,找出最差个体
worstindividual=population[i];
worst_index=i;
sum+=population[i].fitness;
//sum存放种群总体适应值
}//for
if(generation==0)
currentbest=bestindividual;
//第一代最好的暂时存放在currentbest
else
if(bestindividual.fitness>
=currentbest.fitness)//第n代最好的,通过比较大于以往最好个体的话,
{//暂时存放在currentbest
currentbest=bestindividual;
voidperformevolution()//演示评价结果
if(bestindividual.fitness>
currentbest.fitness)
currentbest=population[best_index];
population[worst_index]=currentbest;
voidselectoperator()//比例选择算法
inti,index;
doublep,sum=0.0;
//p存放随机概率,sum存放个体适应率和累计适应率
doublecfitness[POPSIZE];
//当代种群染色体个体的适应率
structindividualnewpopulation[POPSIZE];
//新种群
srand((unsigned)time(NULL));
//种下随机种子
i++)//
//sum存放种群适应值总和
i++){
cfitness[i]=population[i].fitness/sum;
//cfitness[]=fitness/sum得到个体适应率
for(i=1;
cfitness[i]=cfitness[i-1]+cfitness[i];
//cfitness[]=cfitness[i-1]+cfitness[i]得到种群
}//累计适应率
i++)//for循环实现轮盘赌算法
p=rand()%1000/1000.0;
//得到千分位小数
index=0;
while(p>
cfitness[index])
index++;
newpopulation[i]=population[index];
//选出的个体组成新的一代,暂时存放于newpopulation[]中
population[i]=newpopulation[i];
//全局变量populaiton存放新的种群(有重复的值)
voidcrossoveroperator()//交叉算法
intindex[POPSIZE];
intpoint,temp;
doublep;
i++){//初始化index[]数组
index[i]=i;
i++){//for循环实现种群内随机两两交换
point=rand()%(popsize-i);
//打乱种群顺序
temp=index[i];
index[i]=index[point+i];
index[point+i]=temp;
popsize-1;
i+=2){
if(p<
pc){//单点交叉算法
point=rand()%(chromlength-1)+1;
for(j=point;
j<
j++){
temp=population[index[i]].chrom[j];
population[index[i]].chrom[j]=population[index[i+1]].chrom[j];
population[index[i+1]].chrom[j]=temp;
}
voidmutationoperator()//变异操作
i++){
p=rand()%1000/1000.0;
if(p<
pm){
population[i].chrom[j]=(population[i].chrom[j]==0)?
1:
0;
voidinput()//数据输入
初始化全局变量:
种群大小(4-500偶数):
scanf("
%d"
&
popsize);
//输入种群大小,必须为偶数
if((popsize%2)!
=0)
种群大小已设置为偶数\n"
popsize++;
};
最大世代数(10-300):
//输入最大世代数
maxgeneration);
交叉率(0.2-1.0):
//输入交叉率
%lf"
pc);
变异率(0.00):
//输入变异率
pm);
voidoutputtextreport()//数据输出
doublesum;
doubleaverage;
sum=0.0;
sum+=population[i].value;
average=sum/popsize;
当前世代=%d\n当前世代染色体平均值=%f\n当前世代染色体最高值=%f\n"
generation,average,population[best_index].value);
运行结果:
/*
本程序为求函数y=x*x的最大值
4
5
0.9
0.01
4;
最大世代数(maxgeneration)5;
交叉率(pc)0.900000;
变异率(pm)0.010000
01001
11111
00010
01111
显示当前种群结