实验五:遗传算法求解函数最值问题实验
遗传算法实例,多项式求最值
求解高次函数在区间上的最大值
问题描述
求解函数 f(x) = x + 10*sin(5*x) + 7*cos(4*x) 在区间[0,9]的最大值。
遗传算法特性
遵循『适者生存』、『优胜劣汰』的原则
是一类借鉴生物界自然选择和自然遗传机制的随机化搜索算法。
遗传算法模拟一个人工种群的进化过程,通过选择(Selection)、交叉(Crossover) 以及变异(Mutation)等机制,在每次迭代中都保留一组候选个体,重复此过程, 种群经过若干代进化后,理想情况下其适应度达到***近似最优***的状态。
种群的每一次进化,都会产生一个最优个体。种群所有世代的最优个体,可能就 是函数f(x)最大值对应的定义域中的点。
如果种群无休止地进化,那总能找到最好的解。但实际上,我们的时间有限,通 常在得到一个看上去不错的解时,便终止了进化。
赋予种群进化的能力
选择
交叉
变异
选择(selection)
色体按照变异概率(mutate_rate)进行染色体的变异
用单点变异法,也可以使用其他变异方法
交叉概率和变异概率
一般来说,交叉概率(cross_rate)比较大,变异概率(mutate_rate)极低。像求解 函数最大值这类问题,我设置的交叉概率(cross_rate)是0.6,变异概率 (mutate_rate)是0.01。 因为遗传算法相信2条优秀的父母染色体交叉更有可能产生优秀的后代,而变异 的话产生优秀后代的可能性极低,不过也有存在可能一下就变异出非常优秀的后 代。这也是符合自然界生物进化的特征的。
最新遗传算法解决最大值问题_免费下载-药学医学精品资料
• 可见,经交叉后得到的新的种群为: • S01=10001,S02=11010,S03=01101,S04=11001
• ⑹变异 • 变异概率一般都很小,假设本次循环中没有发生变异,则变异 前的种群即为进化后所得到的第1代种群。即: • S11=10001,S12=11010,S13=01101,S14=11001 • 然后,对第1代种群重复上述(4)——(6)的操作。 • 对第1代种群,同样重复上述(4)——(6)的操作。其选择情况如 图所示: • 第1代种群的选择情况表 • 编号 染色体 x 适应值 百分比% 累计百分比% 选中次数 • S11 10001 27 289 16.43 16.437 1 • S12 11010 26 676 38.43 54.86 2 • S13 01101 13 169 9.61 64.47 0 • S14 11001 25 625 35.53 100 1
• • • • • • • • •
初始种群情况表
编号 染色体 x 适应值 百分比% 累计百分比% 选中次数 S01 01101 13 169 14.44 14.44 1 S02 11001 25 625 52.88 67.18 2 S03 01000 8 64 5.41 72.59 0 S04 10010 18 324 27.41 100 1 ⑷选择操作 假设采用轮盘赌方式选择个体,且依次生成的4个随机数(相 当于轮盘上指针所指的数)为0.85、0.32、0.12和0.46,经选择后得到 的新的种群为: • S01=10010,S02=11001,S03=01101,S04=11001 • 其中,染色体11001在种群中出现了2次,而原染色体01000则 因适应值太小而被淘汰。
• • •
• • • • • •
遗传算法求函数最大值实验报告
遗传算法求函数最大值实验报告遗传算法是一种模拟自然界进化过程的优化算法,它通过模拟生物进化过程中的遗传、交叉和变异等机制,逐步优化解空间中的个体,以找到问题的最优解。
在本次实验中,我们利用遗传算法来求解一个函数的最大值。
下面我们将详细介绍实验的过程和结果。
首先,我们选择了一个简单的函数作为实验对象,即f(x) = x^2,在x的范围为[-10, 10]。
我们的目标是找到使函数值最大的x。
首先,我们需要定义遗传算法中的基本元素,包括编码方式、适应度函数、选择策略、交叉和变异操作等。
在本实验中,我们选择二进制编码方式,将x的范围[-10, 10]离散化为10位的二进制编码。
适应度函数即为f(x) = x^2,它表示个体的适应度。
选择策略采用轮盘赌选择算法,交叉操作采用单点交叉,变异操作采用随机位变异。
接下来,我们需要初始化种群,并迭代进行交叉和变异操作,直到满足终止条件。
在每一代中,我们根据适应度函数对种群中的个体进行评估,并根据选择策略选择父代个体进行交叉和变异操作。
通过交叉和变异操作,产生新的子代个体,并替代原有种群中的个体。
在本次实验中,我们设置了100个个体的种群,并进行了100代的迭代。
实验结果显示,经过多次迭代,算法逐渐优化到了最优解。
最终找到了使函数值最大的x,即x=10,对应的函数值为100。
总结起来,本次实验利用遗传算法求解函数的最大值,展示了遗传算法在优化问题中的应用。
通过适当选择编码方式、适应度函数和操作策略,我们可以有效地找到问题的最优解。
在后续的研究中,我们可以进一步探索遗传算法在更复杂问题上的应用,并通过改进算法的参数和操作策略来提高算法的性能。
实验五:遗传算法求解函数最值问题实验
EJdoublefitness(constCh^crrcscrcRc)
{
doublek,y;
decode(cx# y);
retiurnf(x, y)+5;
2•交叉操作
首先是根据交叉概率probCross选择要交叉的个体进行交叉
//根据交叉槪率进行交叉
for(inti=pre = -1;i<N; i++)
//根据变异概率迸行变异
for (inti=0;i<N; i++)
if(randQm61() < probMutation)
mutate(group[i]);
变异时先随机生成变异的位置,然后把改位的01值翻转。
//变异操作
Hvoidmutate(ChrcfnosomeS c)
{
//随机选行翻转
inti-rand()%len; c-g[i] =
//骑越
boolflag-令;
for(inti = j=0; i<1.亡n;i++)
swap(d.g[l]Jc2.g[i]);
if(i== crosspcint[j])
//妇杲若干个交叉点重合”则效果叠加 "偃数个交叉点效果瑁当于没有交叉点while(j<
flag = [flag;
3.变异操作
首先是根据变异概率probMutation选择要变异的个体
经过一定的进化之后得到最终种群,从中选择最优的个体即可得
到最终的结果。
//获取种群最优你
-intgetOptimal(Ch^crescr:-oup[mxn]doubled—double&』doubled\)
遗传算法求函数极大值(matlab实现)
遗传算法求函数最大值(matlab实现)一、题目:寻找f(x)=x2,,当x在0~31区间的最大值。
二、源程序:%遗传算法求解函数最大值%本程序用到了英国谢菲尔德大学(Sheffield)开发的工具箱GATBX,该工具箱比matlab自带的GATOOL使用更加灵活,但在编写程序方面稍微复杂一些Close all;Clear all;figure(1);fplot('variable*variable',[0,31]); %画出函数曲线%以下定义遗传算法参数GTSM=40; %定义个体数目ZDYCDS=20; %定义最大遗传代数EJZWS=5; %定义变量的二进制位数DG=0.9; %定义代沟trace=zeros(2, ZDYCDS); %最优结果的初始值FieldD=[5;-1;2;1;0;1;1]; %定义区域描述器的各个参数%以下为遗传算法基本操作部分,包括创建初始种群、复制、交叉和变异Chrom=crtbp(GTSM, EJZWS); %创建初始种群,即生成给定规模的二进制种群和结构gen=0; %定义代数计数器初始值variable=bs2rv(Chrom, FieldD); %对生成的初始种群进行十进制转换ObjV=variable*variable; %计算目标函数值f(x)=x2 while gen<ZDYCDS %进行循环控制,当当前代数小于定义的最大遗传代数时,继续循环,直至代数等于最大遗传代数FitnV=ranking(-ObjV); %分配适应度值SelCh=select('sus', Chrom, FitnV, DG); %选择,即对个体按照他们的适配值进行复制SelCh=recombin('xovsp', SelCh, 0.7); %交叉,即首先将复制产生的匹配池中的成员随机两两匹配,再进行交叉繁殖SelCh=mut(SelCh); %变异,以一个很小的概率随机地改变一个个体串位的值variable=bs2rv(SelCh, FieldD); %子代个体的十进制转换ObjVSel=variable*variable; %计算子代的目标函数值[Chrom ObjV]=reins(Chrom, SelCh, 1, 1, ObjV, ObjVSel);%再插入子代的新种群,其中Chrom为包含当前种群个体的矩阵,SelCh为包好当前种群后代的矩阵variable=bs2rv(Chrom, FieldD); %十进制转换gen=gen+1; %代数计数器增加%输出最优解及其序号,并在目标函数图像中标出,Y为最优解,I 为种群的%序号[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*'); %将结果画出三、运行结果:由图可见该函数为单调递增函数,即当X=31时,该取得最大值f(x)max=961。
利用遗传算法求解函数的最大值
利用遗传算法求解函数的最大值蒋赛赵玉芹1 遗传算法的基本原理遗传算法是模拟生物遗传学和自然选择机理,通过人工方式构造的一类优化搜索算法,是对生物进化过程进行的一种数学仿真,是进化计算的一种重要形式。
遗传算法与传统数学模型截然不同,它为那些难以找到传统数学模型的难题找出了一个解决方法。
同时,遗传算法借鉴了生物科学中的某些知识,从而体现了人工智能的这一交叉学科的特点。
遗传算法是一种通用的优化算法,其编码技术和遗传操作比较简单,优化不受限制条件的约束,不需要有先验条件。
其搜索过程是从问题解的一个随机产生的集合开始的,而不是从单个个体开始的,具有隐含并行搜索特性,也就大大减少可陷入局部极小值的可能。
在解决可能在求解过程中产生组合爆炸的问题时会产生很好的效果。
遗传算法需选择一种合适的编码方式表示解, 并选择一种评价函数用来每个解的适应值, 适应值高的解更容易被选中并进行交叉和变异, 然后产生新的子代。
选择、交叉和变异的过程一直循环 , 直到求得满意解或满足其他终止条件为止。
算法的运行过程具有很强的指向性, 适合众多复杂问题的求解。
具体操作步骤如下:1)初始化种群;2)计算种群上每个个体的适应度值;3)按由个体适应度值所决定的某个规则选择将进入下一代的个体进行交叉操作4)按概率PC进行变异操作5)按概率PC6)若没有满足某种停止条件,则转步骤2),否则进入下一步;7)输入种群中适应度值最优的染色体作为问题的满足解或最优解本例运用遗传算法求解函数优化的问题2 遗传求解举例(Rosenbrock函数的全局最大值计算)2.0 求解函数介绍函数f(x1,x2) = 100 (x21-x2)2 + (1-x2)2是非凸函数,又称Rosenbrock函数,是由De Jong提出的,现已成为测试遗传算法的标准函数。
该函数在极小值附近沿曲线x2=x12有陡峭的峡谷,很容易陷入局部极小,它的全局最小点是(1,1),最小值是0.该函数有两个局部极大点,分别是:f(2.048, -2.048)=3897.7342 和 (-2.048,-2.048)=3905.9262其中后者为全局最大值点。
遗传算法求解函数最大值
人工智能遗传算法函数优化目录1引言1.1 摘要函数优化是遗传算法的经典应用领域,也是对遗传算法进行性能评价的常用算例。
本文将用一个详细的例子来说明用遗传算法解一个简单参数优化问题的过程。
这里求解的是一个函数的最大值的问题。
1.2 背景遗传算法采纳自然进化模型。
通过保持一个潜在解的群体执行了多方向的搜索并支持这些方向上的信息构成和交换。
群体经过一个模拟进化的过程:在每一代,相对“好”的解产生,相对“差”的解死亡。
为区别不同解,我们使用了一个目标(评价)函数,它起着一个环境的作用。
选择是用来确定管理费用或交叉个体,以及被选个体将产生多少个代个体。
杂交组合了两个亲代染色体的特征,并通过交换父代相应的片断形成了两个相似的后代。
杂交算子的意图是在不同潜在解之间进行信息交换。
变异是通过用一个等于变异率的概率随机地改变被选择染色体上的一个或多个基因。
变异算子的意图是向群体引入一些额外的变化性。
运用遗传算法解题必经的五个步骤:1.对问题潜在解的遗传表达。
2.产生潜在解初始群体的方法。
3.起环境作用的用“适应值”评价解的适应程度的评价函数。
4.改变后代组成的各种遗传算子。
5.遗传算法所使用的各种参数:群体规模、应用遗传算子的概率等。
2 实验过程2.1 程序目标在实验过程中,我们应用遗传算法来模拟一个函数优化的问题。
程序所要解决的问题是求f(x1,x2)=21.5+x1*sin(4pi*x1)+x2*sin(20pi*x2)的最大值,其中-3.0≤x1≤12.1及4.1≤x2≤5.8。
2.2 实验原理及步骤1 )首先确立变量x1的定义域长度为15.1;所要求的小数点以后第四位精度意味着区间[-3.0, 12.1]应该至少被分成15.1*10000个等距区间,即染色体的第一部分需要18位;自变量x2域长度为 1.7,精度要求区间[4.1, 5.8]应该至少被分成1.7*10000个等距区间,即染色体的第二部分需要15位。
使用遗传算法求解多元函数最值(实例)
public void roulettewheel() {
decoding(); fitness();
double sum=0; for (int i = 0; i <POP_SIZE; i++) { sum=fitness[i]+sum; } for (int i = 0; i < POP_SIZE; i++) { p[i]=fitness[i]/sum; q[i]=0; } for (int i = 0; i < POP_SIZE; i++) { for (int j = 0; j < i+1; j++) {
public void mutation() {
for (int i = 0; i < pop.length; i++) { for (int j = 0; j < LENGTH; j++) {
double k=random.nextDouble();
if(PM>k) {
mutation(i,j); } } } } public void mutation(int i,int j) { String s=pop[i]; StringBuffer sb=new StringBuffer(s); if(sb.charAt(j)=='0') sb.setCharAt(j, '1'); else sb.setCharAt(j, '0'); pop[i]=sb.toString();
使用遗传算法求解多元函数最值
这是我们的待求解问题模型,下面是我们的实现代码: package test;
遗传算法计算最大值
s3’’ =11000(24), s4’’ = 10011(19)
这一轮仍然不会发生变异。
于是,得第三代种群S3:
s1=11100(28), s2=01001(9)
s3=11000(24), s4=10011(19)
第三代种群S3中各染色体的情况 染色体 s1=11100 s2=01001 s3=11000 适应度 784 81 576 选择概率 0.44 0.04 0.32 积累概率 0.44 0.48 0.80 估计的 选中次数 2 0 1
s4 0.31
s30.06
s1 0.14 s2 0.49
赌轮选择示意
在算法中赌轮选择法可用下面的子过程来模拟: ① 在[0, 1]区间内产生一个均匀分布的随机数r。 ② 若r≤q1,则染色体x1被选中。 ③ 若qk-1<r≤qk(2≤k≤N), 则染色体xk被选中。 其中的qi称为染色 体xi (i=1, 2, …, n)的积累概率, 其计算公式为 :
2.
● 适应度(fitness)就是借鉴生物个体对环境的
适应程度,而对问题中的个体对象所设计的 表征其优劣的一种测度。 ● 适应度函数(fitness function)就是问题中的 全体个体与其适应度之间的一个对应关系。
它一般是一个实值函数。该函数就是遗传算
法中指导搜索的评价函数。
3. 染色体与基因 染色体(chromosome)就是问题中个体的某种字符 串形式的编码表示。字符串中的字符也就称为基因( gene)。 例如: 个体 9 ---染色体 1001
步6 按交叉率Pc所决定的参加交叉的染色体数c, 从S1中随机确定c个染色体,配对进行交叉操作,并用 产生的新染色体代替原染色体,得群体S2; 步7 按变异率Pm所决定的变异次数m,从S2中随机
遗传算法求函数最大值
遗传算法求函数最大值
遗传算法是一种基于自然进化的搜索算法,它可以用来求解复杂的优化问题。
它的基本思想是模拟自然界中的进化过程,通过繁殖、变异和选择来改善解决方案。
遗传算法可以用
来求解函数最大值问题,它的基本步骤如下:
1. 初始化种群:首先,需要初始化一个种群,种群中的每个个体都是一个可能的解决方案,每个个体都有一个与之对应的适应度值。
2. 计算适应度:然后,需要计算每个个体的适应度值,适应度值越高,表明该个体越有可
能是最优解。
3. 选择:接下来,需要根据适应度值对种群中的个体进行选择,选择出适应度值较高的个体,以便在下一代中繁殖。
4. 交叉:然后,需要对选择出的个体进行交叉,以产生新的个体,新的个体具有父代个体
的特征。
5. 变异:最后,需要对新的个体进行变异,以产生新的特征,以提高搜索的效率。
通过上述步骤,可以不断迭代,直到找到最优解为止。
遗传算法可以用来求解函数最大值问题,它可以有效地搜索出最优解,而且可以在复杂的环境中取得良好的效果。
基于遗传算法求函数最大值
土豆学习小组基于遗传算法求函数最大值先给出实例:设函数为:]7,1[,10)3sin()5cos()(∈+−=x x x x f ,取种群大小20,搜索精度0.0001,交叉概率0.6,变异概率0.1,遗传20代。
下面根据这个例子来叙述如何通过遗传算法来计算最大值。
遗传算法的概念和相关知识可以去网上查看,这里主要介绍和程序相关的知识。
遗传算法的流程图如下:遗传算法流程图种群的产生一般由随机数产生固定长度的01序列,可以理解成染色体,例如:1111010011100001011000,这表示一个单独个体的染色体,那么结合这个例子就是产生20个这样的染色体。
种群适应度估计,因为是求最大值,所以适应度可以通过求函数值来确定,函数值越大,越适合生存。
选择,这是一个自然选择的过程,这里用轮盘赌选择法,土豆学习小组轮盘赌选择法交叉用单点交叉:单点交叉变异的形式如下:变异当然变异的概率相对较低。
注意:选择和交叉方法还很多,也比这来的有效,只是这种方法较为简单,易于程序实现。
MATLAB命令窗口:>>[xv,fv]=GA(@fitness,1,7,20,20,0.6,0.1,0.0001)xv=3.6723土豆学习小组fv=11.8830函数图形结果基本符合。
函数文件1:fitness.m用于存放需要求的函数function F=fitness(x)F=cos(5*x)-sin(3*x)+10;函数文件2:GA.m遗传算法文件function[xv,fv]=GA(fitness,a,b,NP,NG,pc,pm,eps) %上限a%下限b%种群大小:NP%遗传代数:NG%交叉概率:pc%变异概率:pm%离散精度:eps%第一步产生初始种群x,产生之前需要根据离散精度确定串长L L=ceil(log2((b-a)/eps));x=Initial(L,NP);for i=1:NPxdec(i)=dec(a,b,x(i,:),L);end%第二步选择交叉变异要循环好几代for i=1:NG%选择轮盘赌选择法fx=fitness(xdec);%适应度fxp=fx/sum(fx);%选择概率fxa(1)=fxp(1);%累计概率土豆学习小组for j=2:NPfxa(j)=fxa(j-1)+fxp(j);end%开始选择父体sat=rand();for k=1:NPif sat<=fxa(k)father=k;break;endend%随机选取母体mother=ceil(rand()*NP);nx=x;%单点交叉cutp=ceil(rand()*L);r1=rand();if r1<=pcnx(i,1:cutp)=x(father,1:cutp);nx(i,cutp+1:L)=x(mother,cutp+1:L);r2=rand();%是否变异if r2<pmcum=ceil(rand()*L);nx(i,cum)=~nx(i,cum);endendx=nx;for i=1:NPxdec(i)=dec(a,b,x(i,:),L);end%选择较好的子代fv=-inf;for i=1:NPfitx=fitness(dec(a,b,x(i,:),L));if fitx>fvfv=fitx;xv=dec(a,b,x(i,:),L);endendend土豆学习小组%种群初始化函数function t=Initial(L,NP)t=zeros(NP,L);for i=1:NPfor j=1:Ltemp=rand();t(i,j)=round(temp);endend%解码函数转换成十进制function d=dec(a,b,num,L)i=L-1:-1:0;dd=sum((2.^i).*num);d=a+dd*(b-a)/(2^L-1);其中:dec函数将某个个体转换到【1,7】之间的数000000000000=1;111111111111=7;。
遗传算法求解函数最大值
精选文档S311067019 李麒星用遗传算法经过复制交错过程循环求解函数f(x)=x^2 在 [0,31]区间上的最大值点 x。
代码以下:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespaceProject2{class Class1{public int ff( int a){return a * a;}public int Max( int [] args){int s = 0;int m = args[0];for ( int i = 0; i < args.Length; i++){if (m < args[i]){m = args[i];s = i;}}return s;}public int Min( int [] args){int s = 0;int m = args[0];for ( int i = 0; i < args.Length; i++){if (m > args[i]){m = args[i];s = i;}}return s;}static void Main( String [] args){string [] A = new string [4];A[0] = "01101" ;A[1] = "11000" ;A[2] = "01000" ;A[3] = "10011" ;Class1 cl = new Class1 ();Randoma = new Random();int [] x = new int [4]; // 储存 x值float [] C = new float [4]; // 储存每个适配值所占比率int [] B = new int [4]; // 储存 x对应的 y值int k1 = 0; // 交错时所需的随机整数范围在0-4 之间int k2 = 0; // 交错时所需的随机整数范围在0-4 之间int max = 0; // 适配值总最大的值在 x中的下标int sum = 0; // 全部适配值对应的函数值的总和int min = 0; // 适配值总最小的值在 x中的下标int t1 = 0; // 初始最大值int ave1 = 0; // 初始均匀值int t2 = 0; // 每次循环得出的最大值int ave2 = 0; // 每次循环得出的均匀值int smax = 20; // 循环最大次数for ( int l = 1; l < smax; l++){for ( int i = 0; i < 4; i++){x[i] =Convert .ToInt32(A[i],2);//x[i] = Int32.Parse(A[i]);//怎么把二进制数转变为十进制数}for ( int i = 0; i < 4; i++){B[i] = cl.ff(x[i]);// 求出 f(x)=x^2 的值存入 B中sum += B[i];}for ( int i = 0; i < 4; i++){C[i] = B[i] / sum;}max =cl.Max(x);min = cl.Min(x);t2 = x[max];// 用来记录每次循环的最大值ave2 = sum / 4;// 用来记录每次循环的均匀值if (t2 < t1 && ave2 < ave1){break ;}else{t1 = t2;ave1 = ave2;}for ( int i = 0; i < 4; i++)// 输出每次循环的结果{System. Console .Write(x[i]); //System.Console .Write( ' ' );} System. Console .Write( "\n" ); // 换行A[min] = A[max];// 适配值较小的被裁减,由最大的代替 k1 = a.Next(1,4);// 从 1-4 之间选一个随机数 k2 =a.Next(1,4);if (max + min != 3){string s1 = A[max].Substring(k1); // 从第 k 个数开始获 得后边的子串string s2 = A[min].Substring(k2);string s3 = A[3 - max].Substring(k1);string s4 = A[3 - min].Substring(k2); A[max] = A[max].Substring(0, k1) + s3; A[min] = A[min].Substring(0, k2) + s4; A[3 - max] = A[3 - max].Substring(0,k1) + s1; A[3 - min] = A[3 - min].Substring(0,k2) + s2; }else{ if ((max > min) && (min + 1 == max)) //max=2 min=1string s1 = A[max].Substring(k1); // 从第 k 个数开 始获取后边的子串string s2 = A[min].Substring(k2); string s3 = A[3].Substring(k1); string s4 = A[0].Substring(k2);A[max] = A[max].Substring(0,k1) + s3; A[min] = A[min].Substring(0,k2) + s4; A[3] = A[3].Substring(0,k1) + s1;.S311067019李麒星}elseif ((max < min) &&(min == max+ 1))//max=1 min=2 {string s1 = A[max].Substring(k1); // 从第 k 个数开始获取后边的子串string s2 = A[min].Substring(k2);string s3 = A[0].Substring(k1);string s4 = A[3].Substring(k2);A[max] = A[max].Substring(0,k1) + s3;A[min] = A[min].Substring(0,k2) + s4;A[0] = A[0].Substring(0,k1) + s1;A[3] = A[3].Substring(0,k2) + s2;}elseif ((max > min) && (max ==min + 3))//max=3 min=0{string s1 = A[max].Substring(k1);// 从第 k个数开始获取后边的子串string s2 = A[min].Substring(k2);string s3 = A[2].Substring(k1);string s4 = A[1].Substring(k2);A[max] = A[max].Substring(0,k1) + s3;A[min] = A[min].Substring(0,k2) + s4;A[2] = A[2].Substring(0,k1) + s1;A[1] = A[1].Substring(0,k2) + s2;}elseif((max < min) && ( min==max +3 )) //max=0 min=3{string s1 =A[max].Substring(k1);// 从第 k个数开始获取后边的子串string s2 = A[min].Substring(k2);string s3 = A[1].Substring(k1);string s4 = A[2].Substring(k2);A[max] = A[max].Substring(0,k1) +s3;A[min] = A[min].Substring(0,k2) +s4;A[1] = A[1].Substring(0,k1) + s1;A[1] = A[1].Substring(0,k2) + s2;}}Console .WriteLine( " 最大值是 ={0}" , t1);}}}输出以下:结论:由图可知每次循环结果不独一。
python实现遗传算法求函数最大值(人工智能作业)
python实现遗传算法求函数最⼤值(⼈⼯智能作业)题⽬:⽤遗传算法求函数f(a,b)=2a x sin(8PI x b) + b x cos(13PI x a)最⼤值,a:[-3,7],b:[-4:10]实现步骤:初始化种群计算种群中每个个体的适应值淘汰部分个体(这⾥是求最⼤值,f值存在正值,所以淘汰所有负值)轮盘算法对种群进⾏选择进⾏交配、变异,交叉点、变异点随机分析:为了⽅便,先将⾃变量范围调整为[0,10]、[0,14]有两个变量,种群中每个个体⽤⼀个列表表⽰,两个列表项,每项是⼀个⼆进制字符串(分别由a、b转化⽽来)种群之间交配时需要确定交叉点,先将个体染⾊体中的两个⼆进制字符串拼接,再确定⼀个随机数作为交叉点为了程序的数据每⼀步都⽐较清晰正确,我在select、crossover、mutation之后分别都进⾏了⼀次适应值的重新计算具体代码:import mathimport randomdef sum(list):total = 0.0for line in list:total += linereturn totaldef rand(a, b):number = random.uniform(a,b)return math.floor(number*100)/100PI = math.pidef fitness(x1,x2):return 2*(x1-3)*math.sin(8*PI*x2)+(x2-4)*math.cos(13*PI*x1)def todecimal(str):parta = str[0:4]partb = str[4:]numerical = int(parta,2)partb = partb[::-1]for i in range(len(partb)):numerical += int(partb[i])*math.pow(0.5,(i+1))return numericaldef tobinarystring(numerical):numa = math.floor(numerical)numb = numerical - numabina = bin(numa)bina = bina[2:]result = "0"*(4-len(bina))result += binafor i in range(7):numb *= 2result += str(math.floor(numb))numb = numb - math.floor(numb)return resultclass Population:def __init__(self):self.pop_size = 500 # 设定种群个体数为500self.population = [[]] # 种群个体的⼆进制字符串集合,每个个体的字符串由⼀个列表组成[x1,x2]self.individual_fitness = [] # 种群个体的适应度集合self.chrom_length = 22 # ⼀个染⾊体22位self.results = [[]] # 记录每⼀代最优个体,是⼀个三元组(value,x1_str,x2_str)self.pc = 0.6 # 交配概率self.pm = 0.01 # 变异概率self.distribution = [] # ⽤于种群选择时的轮盘def initial(self):for i in range(self.pop_size):x1 = rand(0,10)x2 = rand(0,14)x1_str = tobinarystring(x1)x2_str = tobinarystring(x2)self.population.append([x1_str,x2_str]) # 添加⼀个个体fitness_value = fitness(x1,x2)self.individual_fitness.append(fitness_value) # 记录该个体的适应度self.population = self.population[1:]self.results = self.results[1:]def eliminate(self):for i in range(self.pop_size):if self.individual_fitness[i]<0:self.individual_fitness[i] = 0.0def getbest(self):"取得当前种群中的⼀个最有个体加⼊results集合"index = self.individual_fitness.index(max(self.individual_fitness))x1_str = self.population[index][0]x2_str = self.population[index][1]value = self.individual_fitness[index]self.results.append((value,x1_str,x2_str,))def select(self):"轮盘算法,⽤随机数做个体选择,选择之后会更新individual_fitness对应的数值""第⼀步先要初始化轮盘""选出新种群之后更新individual_fitness"total = sum(self.individual_fitness)begin = 0for i in range(self.pop_size):temp = self.individual_fitness[i]/total+beginself.distribution.append(temp)begin = tempnew_population = []new_individual_fitness = []for i in range(self.pop_size):num = random.random() # ⽣成⼀个0~1之间的浮点数j = 0for j in range(self.pop_size):if self.distribution[j]<num:continueelse:breakindex = j if j!=0 else (self.pop_size-1)new_population.append(self.population[index])new_individual_fitness.append(self.individual_fitness[index])self.population = new_populationself.individual_fitness = new_individual_fitnessdef crossover(self):"选择好新种群之后要进⾏交配""注意这只是⼀次种群交配,种群每⼀次交配过程,会让每两个相邻的染⾊体进⾏信息交配"for i in range(self.pop_size-1):if random.random()<self.pc:cross_position = random.randint(1,self.chrom_length-1)i_x1x2_str = self.population[i][0]+self.population[i][1] # 拼接起第i个染⾊体的两个⼆进制字符串i1_x1x2_str = self.population[i+1][0]+self.population[i+1][1] # 拼接起第i+1个染⾊体的两个⼆进制字符串 str1_part1 = i_x1x2_str[:cross_position]str1_part2 = i_x1x2_str[cross_position:]str2_part1 = i1_x1x2_str[:cross_position]str2_part2 = i1_x1x2_str[cross_position:]str1 = str1_part1+str2_part2str2 = str2_part1+str1_part2self.population[i] = [str1[:11],str1[11:]]self.population[i+1] = [str2[:11],str2[11:]]"然后更新individual_fitness"for i in range(self.pop_size):x1_str = self.population[i][0]x2_str = self.population[i][1]x1 = todecimal(x1_str)x2 = todecimal(x2_str)self.individual_fitness[i] = fitness(x1,x2)def mutation(self):"个体基因变异"for i in range(self.pop_size):if random.random()<self.pm:x1x2_str = self.population[i][0]+self.population[i][1]pos = random.randint(0,self.chrom_length-1)bit = "1" if x1x2_str[pos]=="0" else "0"x1x2_str = x1x2_str[:pos]+bit+x1x2_str[pos+1:]self.population[i][0] = x1x2_str[:11]self.population[i][1] = x1x2_str[11:]"然后更新individual_fitness"for i in range(self.pop_size):x1_str = self.population[i][0]x2_str = self.population[i][1]x1 = todecimal(x1_str)x2 = todecimal(x2_str)self.individual_fitness[i] = fitness(x1, x2)def solving(self,times):"进⾏times次数的整个种群交配变异""先获得初代的最优个体"self.getbest()for i in range(times):"每⼀代的染⾊体个体和适应值,需要先淘汰,然后选择,再交配、变异,最后获取最优个体。
遗传算法求解函数最大值
遗传算法求解函数最大值研究者们广泛使用各种数学方法来求解函数的最大值,其中遗传算法是一种有效的解决方案。
遗传算法是一种仿生算法,使用相似的进化过程来搜索函数的最大值,这种算法在解决复杂问题时尤其有效。
遗传算法的工作原理是利用遗传操作来进行搜索。
它的步骤大致如下:首先,从初始种群中随机选择一定数量的个体,并进行多次重复,对其属性进行多次迭代,形成较优个体。
然后,根据结果,重建种群,以提高适应度。
在这个过程中,种群中的属性将不断改变,个体之间会遗传和变异,从而改变函数的最大值。
当属性变化趋于稳定时,这种改变的步骤就会停止,最大值就得到了。
为了更好地理解遗传算法,我们先来看一个例子。
一维函数f(x)=x^2-2x+5可以用遗传算法来求最大值。
我们以染色体序列长度为10作为种群大小,创建初始种群,并在每一代经历重复,变异,选择和交叉过程之后,依次获得较优个体。
在这个过程中,染色体序列不断变异,最后形成二进制数f(x)的最大值,最终求得f(x)的最大值为9。
遗传算法具有很多优点,其中最重要的是,它可以解决最优化问题,而且能够在有限的时间里达到不错的效果。
此外,遗传算法不会受到维度或者变量数量的限制,而且它可以根据需要改变变量的组合,从而获得更好的运算结果。
最后,遗传算法也可以应用在实际工程中,这就是遗传算法求解函数最大值的重要应用之一。
总的来说,遗传算法是一种通用的解决方案,能有效地搜索函数的最大值。
虽然它具有很多优点,但也有一些限制。
例如,算法的效率跟种群的大小有关,种群大小越大,搜索效率就越低,而且有时它也会陷入局部最优解中,从而无法搜索到全局最优解。
遗传算法可以给出不错的搜索结果,可以有效地求解函数最大值,是一种普遍应用的有效搜索方法。
因此,在未来,它将继续受到研究者们的广泛关注,并为世人带来更多的益处。
遗传算法求解函数最大值最小值
遗传算法是一种模拟自然选择和遗传机制的优化搜索算法,它能够通过模拟生物进化的过程来寻找最优解。
在数学和计算领域,遗传算法被广泛应用于求解函数的最大值和最小值问题。
1. 遗传算法的基本原理遗传算法是一种基于裙体的优化算法,它模拟了自然界中的优胜劣汰和随机性变异的过程。
其基本原理包括遗传、变异、选择和适应度评价。
1.1 遗传:遗传算法通过模拟生物的交配过程来产生新的个体,其中将两个个体的染色体交叉并产生新的后代。
1.2 变异:遗传算法引入随机性的变异操作,以增加搜索空间的多样性,使算法不至于陷入局部最优解。
1.3 选择:个体的适应度评价后,根据一定的选择策略选择出部分个体作为下一代的种裙,通常适应度高的个体有更大的概率被选择。
1.4 适应度评价:遗传算法通过适应度函数对个体进行评价,以确定个体在种裙中的适应度。
适应度函数通常是需要优化的函数。
2. 遗传算法在求解函数最大值和最小值问题中的应用遗传算法作为一种全局搜索算法,具有寻找函数最大值和最小值的能力。
对于一个给定的函数,遗传算法能够在较短的时间内找到该函数的全局最优解。
2.1 函数最大值求解:对于函数的最大值求解问题,可以将函数的负值作为适应度函数,通过遗传算法来求解负值最小化的问题,从而达到求解函数最大值的目的。
2.2 函数最小值求解:对于函数的最小值求解问题,则可以直接将函数的值作为适应度函数,通过遗传算法来求解函数最小值问题。
3. 遗传算法在实际应用中的优势遗传算法作为一种全局搜索算法,在求解函数最大值和最小值问题中具有以下优势:3.1 并行性:遗传算法能够并行处理多个个体,从而加速搜索过程,尤其适合于复杂的高维优化问题。
3.2 全局搜索能力:遗传算法不容易陷入局部最优解,能够在较短的时间内找到函数的全局最优解。
3.3 适应性强:遗传算法能够适应不同类型的函数和问题,具有较强的通用性。
4. 遗传算法在求解函数最大值和最小值问题中的应用实例以下是一些实际应用中遗传算法在求解函数最大值和最小值问题中的应用实例:4.1 Rosenbrock函数最小值求解:Rosenbrock函数是一个经典的优化测试函数,遗传算法在求解Rosenbrock函数的最小值时具有良好的表现。
实验五:遗传算法求解函数最值问题实验
实验五:遗传算法求解函数最值问题实验一、实验目的使用遗传算法求解函数在及y的最大值。
二、实验内容使用遗传算法进行求解,篇末所附源代码中带有算法的详细注释。
算法中涉及不同的参数,参数的取值需要根据实际情况进行设定,下面运行时将给出不同参数的结果对比。
定义整体算法的结束条件为,当种群进化次数达到maxGeneration时停止,此时种群中的最优解即作为算法的最终输出。
设种群规模为N,首先是随机产生N个个体,实验中定义了类型Chromosome表示一个个体,并且在默认构造函数中即进行了随机的操作。
然后程序进行若干次的迭代,在每次迭代过程中,进行选择、交叉及变异三个操作。
1.选择操作首先计算当前每个个体的适应度函数值,这里的适应度函数即为所要求的优化函数,然后归一化求得每个个体选中的概率,然后用轮盘赌的方法以允许重复的方式选择选择N个个体,即为选择之后的群体。
但实验时发现结果不好,经过仔细研究之后发现,这里在x、y 取某些值的时候,目标函数计算出来的适应值可能会出现负值,这时如果按照把每个个体的适应值除以适应值的总和的进行归一化的话会出现问题,因为个体可能出现负值,总和也可能出现负值,如果归一化的时候除以了一个负值,选择时就会选择一些不良的个体,对实验结果造成影响。
对于这个问题,我把适应度函数定为目标函数的函数值加一个正数,保证得到的适应值为正数,然后再进行一般的归一化和选择的操作。
实验结果表明,之前的实验结果很不稳定,修正后的结果比较稳定,趋于最大值。
2.交叉操作首先是根据交叉概率probCross选择要交叉的个体进行交叉。
这里根据交叉参数crossnum进行多点交叉,首先随机生成交叉点位置,允许交叉点重合,两个重合的交叉点效果互相抵消,相当于没有交叉点,然后根据交叉点进行交叉操作,得到新的个体。
3.变异操作首先是根据变异概率probMutation选择要变异的个体。
变异时先随机生成变异的位置,然后把改位的01值翻转。
实验五:遗传算法求解函数最值问题实验
selectld[i] * j;break;
(j—N-1) selectld[i] = j;
//把种群更新为新选挥的个体集合
for(inti=0;i< N;temGroup[i]=g^oup[i]
for (inti «ft; i < N;group[i]=temOrcupfselectId[i]];
Chromosome。//默认构造函数,构造随机染色体
for (i nt i = 0; i < len; i++) g[i] = ran d()%
2;
}
Chromosome(c onst Chromosome& c)//拷贝构造函数,
进行深复制
{
for (i nt i = 0; i < len; i++) g[i] = c.g[i];
实验五:遗传算法求解函数最值问题实验
一、实验目的
使用遗传算法求解函数
f
在m及yDll的最大值。
使用遗传算法进行求解,篇末所附源代码中带有算法的详细注 释。算法中涉及不同的参数,参数的取值需要根据实际情况进行设定,
F面运行时将给出不同参数的结果对比。
//参数
const intN-2&0;"种群的个休数
但实验时发现结果不好,经过仔细研究之后发现,这里在
取某些值的时候,目标函数计算出来的 适应值可能会出现负值,这时 如果按照把每个个体的适应值除以适应值的总和的进行归一化的话 会出现问题,因为个体可能出现负值,总和也可能出现负值,如果归 一化的时候除以了一个负值,选择时就会选择一些不良的个体, 对实 验结果造成影响。对于这个问题,我把适应度函数定为目标函数的函 数值加一个正数,保证得到的适应值为正数,然后再进行一般的归一 化和选择的操作。实验结果表明,之前的实验结果很不稳定,修正后 的结果比较稳定,趋于最大值。
遗传算法实验报告泽
遗传算法实验报告一、 问题描述已知函数10090060)(23++-=x x x x f , x[0,35 ],求函数的最大值。
05101520253035050010001500200025003000350040004500上图为函数10090060)(23++-=x x x x f 在x [0,35 ]区间上的曲线图像。
可以看出,该函数有多个极值点,如果使用其他的搜寻方法,很容易陷入局部最小点,而不能搜寻到真正的全局最小点,遗传算法具有通用、并行、稳健、简单与全局优化能力强等突出优点,适用于解决这种全局优化问题。
二、 方法原理遗传算法:遗传算法是借鉴生物界自然选择和群体进化机制形成的一种全局寻优算法。
与传统的优化算法相比,遗传算法具有如下优点:不是从单个点,而是从多个点构成的群体开始搜索;在搜索最优解过程中,只需要由目标函数值转换得来的适应值信息,而不需要导数等其它辅助信息;搜索过程不易陷入局部最优点。
目前,该算法已渗透到许多领域,并成为解决各领域复杂问题的有力工具。
在遗传算法中,将问题空间中的决策变量通过一定编码方法表示成遗传空间的一个个体,它是一个基因型串结构数据;同时,将目标函数值转换成适应值,它用来评价个体的优劣,并作为遗传操作的依据。
遗传操作包括三个算子:选择、交叉和变异。
选择用来实施适者生存的原则,即把当前群体中的个体按与适应值成比例的概率复制到新的群体中,构成交配池(当前代与下一代之间的中间群体)。
选择算子的作用效果是提高了群体的平均适应值。
由于选择算子没有产生新个体,所以群体中最好个体的适应值不会因选择操作而有所改进。
交叉算子可以产生新的个体,它首先使从交配池中的个体随机配对,然后将两两配对的个体按某种方式相互交换部分基因。
变异是对个体的某一个或某一些基因值按某一较小概率进行改变。
从产生新个体的能力方面来说,交叉算子是产生新个体的主要方法,它决定了遗传算法的全局搜索能力;而变异算子只是产生新个体的辅助方法,但也必不可少,因为它决定了遗传算法的局部搜索能力.交叉和变异相配合,共同完成对搜索空间的全局和局部搜索. 三、 实现过程(1)编码:使用二进制编码,随机产生一个初始种群。
遗传算法_解决无约束目标函数的最大值问题
遗传算法_解决⽆约束⽬标函数的最⼤值问题遗传算法基本原理借鉴物种进化的思想,将欲求解问题编码,把可⾏解转化为字符串形式。
初始化随机产⽣⼀个种群,⽤合理的评价函数对种群进⾏评估,在此基础上进⾏选择、交叉、变异的操作。
选择算⼦根据⽗代中个体适值⼤⼩进⾏选择或淘汰,保证了算法的最优搜索⽅向。
交叉算⼦模拟基因重组及随机信息交换,产⽣更好的1个体,使其在可⾏域中有效搜索。
变异算⼦模拟基因突变,保证了算法的全局搜索能⼒,避免陷⼊局部最优。
遗传算法基本过程1.编码有多种编码⽅式,⼀般采⽤⼆进制编码2.解码⽬的是为了将不直观的⼆进制数据串还原成⼗进制3.初始种群利⽤随机函数产⽣k位(假设⼆进制数的最⼤长度为k)的0、1排列,将该排列数表⽰⼀个染⾊体,每个染⾊体代表⼀个初始值4.选择根据个体适应值的⽐例来确定个体的选择概率,是⼀个随机采⽤的过程,⼀般再⽤轮盘赌算法来进⾏选择。
这⾥来举个 栗⼦来解释轮盘赌算法个体序号 1 2 3 4 5 6 7 8 9 10适应度 8 2 17 2 12 11 7 3 7适应度累计值 8 10 27 34 36 48 59 66随机数 23 49 76 13 1 27 57被选中的个体号 3 7 10 3 1 3 7设个体序号为i ,适应度累计值为个体序号1~i的适应度的累加和;被选中的个体号为⽐随机数⼤的最⼩的适应度累计值的索引5.交叉随机产⽣⼀个1到k-1的数(假设⼆进制数的最⼤长度为k),个体A、B在该位后的染⾊体进⾏交换6.变异为了避免在算法迭代后期出现种群过早收敛,随机选取1~k中的某位若其为0将其变为1,若其为1将其变为07.个体适应度评估在设计适应度函数时要考虑:1.适应度函数能否反映解的优劣2.该函数是否时单值的和⾮负的对于函数优化问题,适应度可取为函数值8.复制将⼦代复制为⽗代⽆约束⽬标函数的最⼤值的求解%target.m% 案例⼀:⽆约束⽬标函数的最⼤值% 求解maxf(x)=200*e(−0.05x)*sinx; x∈[−2,2]%主程序:⽤遗传算法求解y=200*exp(-0.05*x).*sin(x)在[-2 2]区间上的最⼤值clc;global BitLength %全局变量,计算如果满⾜求解精度⾄少需要编码的长度global boundsbegin %全局变量,⾃变量的起始点global boundsend %全局变量,⾃变量的终⽌点bounds=[-2 2];%⼀维⾃变量的取值范围precision=0.0001;%运算精度boundsbegin=bounds(:,1);boundsend=bounds(:,2);%计算满⾜求解精度⾄少需要多长的染⾊体BitLength=ceil(log2((boundsend-boundsbegin)'./precision));popsize=50;%初始种群⼤⼩Generationnmax=20;%最⼤代数pcrossover=0.9;%交配概率pmutation=0.09;%变异概率%产⽣初始种群%Round函数返回⼀个数值,该数值是按照指定的⼩数位数进⾏四舍五⼊运算的结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验五:遗传算法求解函数最值问题实验一、实验目的使用遗传算法求解函数在及y的最大值。
二、实验容使用遗传算法进行求解,篇末所附源代码中带有算法的详细注释。
算法中涉及不同的参数,参数的取值需要根据实际情况进行设定,下面运行时将给出不同参数的结果对比。
定义整体算法的结束条件为,当种群进化次数达到maxGeneration时停止,此时种群中的最优解即作为算法的最终输出。
设种群规模为N,首先是随机产生N个个体,实验中定义了类型Chromosome表示一个个体,并且在默认构造函数中即进行了随机的操作。
然后程序进行若干次的迭代,在每次迭代过程中,进行选择、交叉及变异三个操作。
1.选择操作首先计算当前每个个体的适应度函数值,这里的适应度函数即为所要求的优化函数,然后归一化求得每个个体选中的概率,然后用轮盘赌的方法以允许重复的方式选择选择N个个体,即为选择之后的群体。
但实验时发现结果不好,经过仔细研究之后发现,这里在x、y 取某些值的时候,目标函数计算出来的适应值可能会出现负值,这时如果按照把每个个体的适应值除以适应值的总和的进行归一化的话会出现问题,因为个体可能出现负值,总和也可能出现负值,如果归一化的时候除以了一个负值,选择时就会选择一些不良的个体,对实验结果造成影响。
对于这个问题,我把适应度函数定为目标函数的函数值加一个正数,保证得到的适应值为正数,然后再进行一般的归一化和选择的操作。
实验结果表明,之前的实验结果很不稳定,修正后的结果比较稳定,趋于最大值。
2.交叉操作首先是根据交叉概率probCross选择要交叉的个体进行交叉。
这里根据交叉参数crossnum进行多点交叉,首先随机生成交叉点位置,允许交叉点重合,两个重合的交叉点效果互相抵消,相当于没有交叉点,然后根据交叉点进行交叉操作,得到新的个体。
3.变异操作首先是根据变异概率probMutation选择要变异的个体。
变异时先随机生成变异的位置,然后把改位的01值翻转。
经过一定的进化之后得到最终种群,从中选择最优的个体即可得到最终的结果。
4.运行结果借助matlab软件,我们可以知道该函数在该定义域下的图像为:以下设置不同的参数值进行对比试验:表1 不同参数的对比实验N lencrossnummaxGenerationprobCrossprobMutate实验一实验二以上我们主要对种群规模N,个体染色体长度len,迭代次数maxGeneration进行比较。
可以看出,随着种群规模的增大,染色体长度的增长,迭代次数的增加,算法得到的结果越来越精确。
当参数规模达到一定程度时,再增加参数的值会明显地增加程序运行时间,但却不一定能明显改善解的质量,反而可能因为一些随机因数而产生质量更差的解,如第6组实验一所示。
同时也大概比较了一下多点交叉的交叉点个数crossnum,交叉概率probCross,变异概率probMutate等参数,由于参数太多,这里没有一一进行控制变量的比较。
大致估算可知,交叉概率及交叉点的个数影响交叉操作产生新个体的质量,过多的交叉及变化过大的交叉可能会产生不好的结果,而过多的变异也应该会造成算法的不稳定。
下面给出以上几个实验结果的实验截图,其中到现在为止结果最好的一个为:其余若干个为:5.实验代码改进后的源代码如下:#include <iostream>#include <iomanip>#include <algorithm>#include <cmath>#include <ctime>using namespace std;// 程序欲分配存的数组大小const int mxn = 10000; // 最大的种群规模const int mxlen = 1000; // 最大的染色体长度// 遗传算法关键参数const int N = 200; // 种群的个体数const int len = 30; // 每个个体的染色体的长度,x和y各占一半const int crossnum = 4; // 交叉操作时多点交叉的交叉点个数const int maxGeneration = 2000; // 最大进化代数const double probCross = 0.85; // 交叉概率const double probMutation = 0.15; // 变异概率// 个体的染色体类class Chromosome{public:bool g[mxlen]; // 二进制编码的编码数组Chromosome() // 默认构造函数,构造随机染色体{for (int i = 0; i < len; i++) g[i] = rand() % 2;}Chromosome(const Chromosome& c) // 拷贝构造函数,进行深复制{for (int i = 0; i < len; i++) g[i] = c.g[i];}void operator=(const Chromosome& c) // 重载=号,进行深复制{for (int i = 0; i < len; i++) g[i] = c.g[i];}};double bestval; // 记录当前所得的最优值Chromosome bestC; // 记录当前最优值对应的个体染色体Chromosome group[mxn], temGroup[mxn]; // 个体的种群,辅助数组// 目标函数double f(double x, double y){return x * sin(6 * y) + y * cos(8 * x);}// 解码函数,从染色体得到x和y的值void decode(const Chromosome& c, double& x, double &y) {double num = pow(2.0, len / 2.0);int tem = 0;for (int i = len - 1, q = 1; i >= len / 2; i--)tem += c.g[i] * q, q = q * 2;y = 1 + (2 - 1) / num * tem;tem = 0;for (int i = len / 2 - 1, q = 1; i >= 0; i--)tem += c.g[i] * q, q = q * 2;x = 1 + (2 - 1) / num * tem;}// 适应度函数,为避免负值,把目标函数加一个正数double fitness(const Chromosome& c){double x, y;decode(c, x, y);return f(x, y) + 5;}// 辅助函数,生成0-1之间的随机小数double inline random01(){return rand() % 10000 / 10000.0;}// 选择操作void select(Chromosome group[mxn]){// 计算每个个体的选择概率double fitnessVal[mxn];for (int i = 0; i < N; i++) fitnessVal[i] = fitness(group[i]);double sum = 0;for (int i = 0; i < N; i++) sum += fitnessVal[i];double prob[mxn];for (int i = 0; i < N; i++) prob[i] = fitnessVal[i] / sum;// 随机选择N个个体组成新种群int selectId[mxn];for (int i = 1; i < N; i++) prob[i] += prob[i-1];for (int i = 0; i < N; i++){// 使用轮盘赌算法选择个体double randNum = random01();int j;for (j = 0; j < N - 1; j++){if (randNum < prob[j]){selectId[i] = j;break;}}if (j == N - 1)selectId[i] = j;}// 把种群更新为新选择的个体集合for (int i = 0; i < N; i++) temGroup[i] = group[i];for (int i = 0; i < N; i++) group[i] = temGroup[selectId[i]];}// 交叉操作,使用多点交叉void crossover(Chromosome& c1, Chromosome& c2){// 生成交叉点位置,并排序int crosspoint[mxn];for(int i = 0; i < crossnum; i++) crosspoint[i] = rand() % len;sort(crosspoint, crosspoint+crossnum);// 进行交叉bool flag = 0;for(int i = 0, j = 0; i < len; i++){if(!flag)swap(c1.g[i], c2.g[i]);if (i == crosspoint[j]){// 如果若干个交叉点重合,则效果叠加// 偶数个交叉点效果相当于没有交叉点while(j < crossnum && i == crosspoint[j]){j++; flag = !flag;}}}}// 变异操作void mutate(Chromosome& c){// 随机选择一位进行翻转int i = rand() % len;c.g[i] = !c.g[i];}// 获取种群最优个体int getOptimal(Chromosome group[mxn], double& x, double& y, double& val){// 计算适应值,遍历得到最优值并进行解码double fitnessVal[mxn];for (int i = 0; i < N; i++) fitnessVal[i] = fitness(group[i]);int id = 0;for (int i = 1; i < N; i++)if (fitnessVal[i] > fitnessVal[id])id = i;decode(group[id], x, y);val = f(x, y);return id;}// 遗传算法总代码void GA(double& x, double& y, double& val){// 初始化种群for (int i = 0; i < N; i++)group[i] = Chromosome();//bestC = group[getOptimal(group, x, y, bestval)];// 控制进化代数for (int g = 0; g < maxGeneration; g++){// 选择操作select(group);// 根据交叉概率进行交叉for (int i = 0, pre = -1; i < N; i++){if (random01() < probCross){if (pre == -1)pre = i;else{crossover(group[pre], group[i]);pre = -1;}}}// 根据变异概率进行变异for (int i = 0; i < N; i++)if (random01() < probMutation)mutate(group[i]);// 防止种群退化double temval;int bestId = getOptimal(group, x, y, temval);if (temval < bestval){// 如果新种群的最优值变差,把较优的个体替换进新种群group[bestId] = bestC;}else{// 如果新种群的最优值变好,则更新最优值记录bestC = group[bestId];bestval = temval;}}// 获取最优值getOptimal(group, x, y, val);}int main (){srand(time(0));double x, y, maxval;GA(x, y, maxval);cout << "函数在点(" << fixed << setprecision(15) << x << ", "<< y << ")取得最大值:" << maxval << endl;system("pause");}三、实验体会以上实验得到的最好结果仍然是差强人意,这里对算法做一个小的优化,即添加防止种群退化的操作。