遗传算法的c语言程序

合集下载

遗传算法入门实例:对 PID 参数寻优

遗传算法入门实例:对 PID 参数寻优

遗传算法入门实例:对PID参数寻优[原创][这乌龟飙得好快啊]开始之前:假设你已经:能运用C语言,初步了解PID、遗传算法的原理。

遗传算法能干什么?(我有个毛病:每当遇到一个东东,我首先会设法知道:这个东东能干什么呢?)遗传算法可以解决非线性、难以用数学描述的复杂问题。

也许这样的陈述让你觉得很抽象,把它换成白话说就是:有个问题我不知道甚至不可能用数学的方法去推导、解算,那么也许我就可以用遗传算法来解决。

遗传算法的优点是:你不需要知道怎么去解决一个问题; 你需要知道的仅仅是,用怎么的方式对可行解进行编码,使得它能能被遗传算法机制所利用。

如果你运用过PID来控制某个系统,那你一定非常清楚:PID麻烦就在那三个参量的调整上,很多介绍PID的书上常搬一些已知数学模型的系统来做实例环节,但事实上我们面对的往往是不可能用数学模型描述的系统,这个时候该怎么取PID的参值呢?1、可以依靠经验凑试,耗时耗精力。

2、离线规划,这就是下文要做的事情3、在线规划,比方说神经网络PID(后续文章将推出,做个广告先^_^)。

一、 将PID用在本次试验中来个问题先:A VR怎样利用片上和少量的外围器件快速准确地实现D/A输出?(0~5V)1、实验电路的搭建:图1:实验原理图搭建这样的电路纯粹是为了本次实验的直观(超调、调整不足等现象通过示波器一目了然),当然,如果实际工程这么简单那也用不到PID,更用不到遗传算法了。

回归话题,解释下上面的电路:M16单片机的OC2输出0~100%占空比的PWM,经过RC,可以得到0~5V 的直流电压,这就实现了简易的D/A(实际实验,发现输出电压是1.XX伏~4.XX 伏,未带负载)。

用一个图表示:这个时候如果我要输出 3.5V (可以是其它值)电压,该加怎样的PWM呢?(有个简单的方法:标定,但是这种方法系统调整响应速度较为缓慢,理由见图5下附言)也许我们可以把这个输出电压加到A/D反馈到系统,这样就形成了闭环控制:系统输出PWM ——>> PWM 转换成电压——>>A/D 采集,获得实际值与目标值的偏差(例如3.5V )——>>将偏差进行PID 加载到PWM 输出(然后输出又影响下一次的输入……)把示波器加到测试点上,调整扫描周期,使示波器能看到完整的一个调整过程。

基于C语言的遗传算法应用研究

基于C语言的遗传算法应用研究

基于C语言的遗传算法应用研究介绍遗传算法是一种受生物学启发的优化算法,通过模拟进化过程来寻找最优解。

它被广泛应用于解决各种复杂问题,如组合优化、函数优化、机器学习等领域。

在本文中,我们将讨论基于C语言的遗传算法的应用研究。

遗传算法的原理遗传算法的原理是基于自然选择和遗传机制。

它模拟了生物进化过程中的选择、复制和变异等操作。

算法通过对一个种群进行迭代操作来逐步优化解的质量,直到找到全局最优解或最优近似解。

遗传算法主要包含以下几个关键步骤: 1. 初始化种群:随机生成一组个体作为初始种群。

2. 评估适应度:根据问题的定义,对每个个体计算适应度值。

3.选择操作:根据适应度值选择优秀的个体作为父代。

4. 交叉操作:通过交叉操作,将父代的基因进行混合,生成新的子代。

5. 变异操作:对子代进行变异,引入新的基因信息。

6. 更新种群:用新的个体替代原来的个体,形成新的种群。

7. 终止条件:根据预先设定的终止条件,决定算法是否结束。

C语言在遗传算法中的应用C语言作为一种通用的高级编程语言,具有高效、灵活和可移植的特点,非常适合在遗传算法中实现。

以下是C语言在遗传算法中的几个关键应用。

种群表示C语言可以使用数组或结构体等数据结构来表示遗传算法的种群。

每个个体可以用一个固定长度的二进制串或其他数据类型来表示。

C语言提供了强大的数组操作功能,使得种群的处理和操作更加简便和高效。

适应度函数C语言可以定义适应度函数来评估每个个体的适应度值。

适应度函数根据问题的特定要求来计算一个个体的适应度值,作为选择操作的依据。

C语言提供了丰富的数学函数库,使得适应度函数的计算更加方便。

选择操作C语言可以使用多种选择算法来选择优秀的个体作为父代。

例如,可以使用轮盘赌选择、锦标赛选择等方法来实现选择操作。

C语言提供了条件语句和随机数生成等功能,使得选择操作的实现简单而灵活。

交叉操作C语言可以通过交叉操作将父代的基因混合,生成新的子代。

2020年遗传算法matlab程序实例精编版

2020年遗传算法matlab程序实例精编版

%-----------------------------------------------%---------------------------------------------------遗传算法程序(一):说明: fga.m 为遗传算法的主程序; 采用二进制Gray编码,采用基于轮盘赌法的非线性排名选择, 均匀交叉,变异操作,而且还引入了倒位操作!function [BestPop,Trace]=fga(FUN,LB,UB,eranum,popsize,pCross,pMutation,pInversion,options) % [BestPop,Trace]=fmaxga(FUN,LB,UB,eranum,popsize,pcross,pmutation)% Finds a maximum of a function of several variables.% fmaxga solves problems of the form:% max F(X) subject to: LB <= X <= UB% BestPop - 最优的群体即为最优的染色体群% Trace - 最佳染色体所对应的目标函数值% FUN - 目标函数% LB - 自变量下限% UB - 自变量上限% eranum - 种群的代数,取100--1000(默认200)% popsize - 每一代种群的规模;此可取50--200(默认100)% pcross - 交叉概率,一般取0.5--0.85之间较好(默认0.8)% pmutation - 初始变异概率,一般取0.05-0.2之间较好(默认0.1)% pInversion - 倒位概率,一般取0.05-0.3之间较好(默认0.2)% options - 1*2矩阵,options(1)=0二进制编码(默认0),option(1)~=0十进制编%码,option(2)设定求解精度(默认1e-4)%% ------------------------------------------------------------------------T1=clock;if nargin<3, error('FMAXGA requires at least three input arguments'); endif nargin==3, eranum=200;popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];endif nargin==4, popsize=100;pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];endif nargin==5, pCross=0.8;pMutation=0.1;pInversion=0.15;options=[0 1e-4];endif nargin==6, pMutation=0.1;pInversion=0.15;options=[0 1e-4];endif nargin==7, pInversion=0.15;options=[0 1e-4];endif find((LB-UB)>0)error('数据输入错误,请重新输入(LB<UB):');ends=sprintf('程序运行需要约%.4f 秒钟时间,请稍等......',(eranum*popsize/1000));disp(s);global m n NewPop children1 children2 VarNumbounds=[LB;UB]';bits=[];VarNum=size(bounds,1);precision=options(2);%由求解精度确定二进制编码长度bits=ceil(log2((bounds(:,2)-bounds(:,1))' ./ precision));%由设定精度划分区间[Pop]=InitPopGray(popsize,bits);%初始化种群[m,n]=size(Pop);NewPop=zeros(m,n);children1=zeros(1,n);children2=zeros(1,n);pm0=pMutation;BestPop=zeros(eranum,n);%分配初始解空间BestPop,TraceTrace=zeros(eranum,length(bits)+1);i=1;while i<=eranumfor j=1:mvalue(j)=feval(FUN(1,:),(b2f(Pop(j,:),bounds,bits)));%计算适应度end[MaxValue,Index]=max(value);BestPop(i,:)=Pop(Index,:);Trace(i,1)=MaxValue;Trace(i,(2:length(bits)+1))=b2f(BestPop(i,:),bounds,bits);[selectpop]=NonlinearRankSelect(FUN,Pop,bounds,bits);%非线性排名选择[CrossOverPop]=CrossOver(selectpop,pCross,round(unidrnd(eranum-i)/eranum));%采用多点交叉和均匀交叉,且逐步增大均匀交叉的概率%round(unidrnd(eranum-i)/eranum)[MutationPop]=Mutation(CrossOverPop,pMutation,VarNum);%变异[InversionPop]=Inversion(MutationPop,pInversion);%倒位Pop=InversionPop;%更新pMutation=pm0+(i^4)*(pCross/3-pm0)/(eranum^4);%随着种群向前进化,逐步增大变异率至1/2交叉率p(i)=pMutation;i=i+1;endt=1:eranum;plot(t,Trace(:,1)');title('函数优化的遗传算法');xlabel('进化世代数(eranum)');ylabel('每一代最优适应度(maxfitness)');[MaxFval,I]=max(Trace(:,1));X=Trace(I,(2:length(bits)+1));hold on; plot(I,MaxFval,'*');text(I+5,MaxFval,['FMAX=' num2str(MaxFval)]);str1=sprintf ('进化到%d 代,自变量为%s 时,得本次求解的最优值%f\n对应染色体是:%s',I,num2str(X),MaxFval,num2str(BestPop(I,:)));disp(str1);%figure(2);plot(t,p);%绘制变异值增大过程T2=clock;elapsed_time=T2-T1;if elapsed_time(6)<0elapsed_time(6)=elapsed_time(6)+60; elapsed_time(5)=elapsed_time(5)-1;endif elapsed_time(5)<0elapsed_time(5)=elapsed_time(5)+60;elapsed_time(4)=elapsed_time(4)-1;end %像这种程序当然不考虑运行上小时啦str2=sprintf('程序运行耗时%d 小时%d 分钟%.4f 秒',elapsed_time(4),elapsed_time(5),elapsed_time(6));disp(str2);%初始化种群%采用二进制Gray编码,其目的是为了克服二进制编码的Hamming悬崖缺点function [initpop]=InitPopGray(popsize,bits)len=sum(bits);initpop=zeros(popsize,len);%The whole zero encoding individualfor i=2:popsize-1pop=round(rand(1,len));pop=mod(([0 pop]+[pop 0]),2);%i=1时,b(1)=a(1);i>1时,b(i)=mod(a(i-1)+a(i),2)%其中原二进制串:a(1)a(2)...a(n),Gray串:b(1)b(2)...b(n)initpop(i,:)=pop(1:end-1);endinitpop(popsize,:)=ones(1,len);%The whole one encoding individual%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%解码function [fval] = b2f(bval,bounds,bits)% fval - 表征各变量的十进制数% bval - 表征各变量的二进制编码串% bounds - 各变量的取值范围% bits - 各变量的二进制编码长度scale=(bounds(:,2)-bounds(:,1))'./(2.^bits-1); %The range of the variablesnumV=size(bounds,1);cs=[0 cumsum(bits)];for i=1:numVa=bval((cs(i)+1):cs(i+1));fval(i)=sum(2.^(size(a,2)-1:-1:0).*a)*scale(i)+bounds(i,1);end%选择操作%采用基于轮盘赌法的非线性排名选择%各个体成员按适应值从大到小分配选择概率:%P(i)=(q/1-(1-q)^n)*(1-q)^i, 其中P(0)>P(1)>...>P(n), sum(P(i))=1function [selectpop]=NonlinearRankSelect(FUN,pop,bounds,bits)global m nselectpop=zeros(m,n);fit=zeros(m,1);for i=1:mfit(i)=feval(FUN(1,:),(b2f(pop(i,:),bounds,bits)));%以函数值为适应值做排名依据endselectprob=fit/sum(fit);%计算各个体相对适应度(0,1)q=max(selectprob);%选择最优的概率x=zeros(m,2);x(:,1)=[m:-1:1]';[y x(:,2)]=sort(selectprob);r=q/(1-(1-q)^m);%标准分布基值newfit(x(:,2))=r*(1-q).^(x(:,1)-1);%生成选择概率newfit=cumsum(newfit);%计算各选择概率之和rNums=sort(rand(m,1));fitIn=1;newIn=1;while newIn<=mif rNums(newIn)<newfit(fitIn)selectpop(newIn,:)=pop(fitIn,:);newIn=newIn+1;elsefitIn=fitIn+1;endend%交叉操作function [NewPop]=CrossOver(OldPop,pCross,opts)%OldPop为父代种群,pcross为交叉概率global m n NewPopr=rand(1,m);y1=find(r<pCross);y2=find(r>=pCross);len=length(y1);if len>2&mod(len,2)==1%如果用来进行交叉的染色体的条数为奇数,将其调整为偶数y2(length(y2)+1)=y1(len);y1(len)=[];endif length(y1)>=2for i=0:2:length(y1)-2if opts==0[NewPop(y1(i+1),:),NewPop(y1(i+2),:)]=EqualCrossOver(OldPop(y1(i+1),:),OldPop(y1(i+2),:));else[NewPop(y1(i+1),:),NewPop(y1(i+2),:)]=MultiPointCross(OldPop(y1(i+1),:),OldPop(y1(i+2),:));endendendNewPop(y2,:)=OldPop(y2,:);%采用均匀交叉function [children1,children2]=EqualCrossOver(parent1,parent2)global n children1 children2hidecode=round(rand(1,n));%随机生成掩码crossposition=find(hidecode==1);holdposition=find(hidecode==0);children1(crossposition)=parent1(crossposition);%掩码为1,父1为子1提供基因children1(holdposition)=parent2(holdposition);%掩码为0,父2为子1提供基因children2(crossposition)=parent2(crossposition);%掩码为1,父2为子2提供基因children2(holdposition)=parent1(holdposition);%掩码为0,父1为子2提供基因%采用多点交叉,交叉点数由变量数决定function [Children1,Children2]=MultiPointCross(Parent1,Parent2)global n Children1 Children2 VarNumChildren1=Parent1;Children2=Parent2;Points=sort(unidrnd(n,1,2*VarNum));for i=1:VarNumChildren1(Points(2*i-1):Points(2*i))=Parent2(Points(2*i-1):Points(2*i));Children2(Points(2*i-1):Points(2*i))=Parent1(Points(2*i-1):Points(2*i));end%变异操作function [NewPop]=Mutation(OldPop,pMutation,VarNum)global m n NewPopr=rand(1,m);position=find(r<=pMutation);len=length(position);if len>=1for i=1:lenk=unidrnd(n,1,VarNum); %设置变异点数,一般设置1点for j=1:length(k)if OldPop(position(i),k(j))==1OldPop(position(i),k(j))=0;elseOldPop(position(i),k(j))=1;endendendendNewPop=OldPop;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%倒位操作function [NewPop]=Inversion(OldPop,pInversion)global m n NewPopNewPop=OldPop;r=rand(1,m);PopIn=find(r<=pInversion);len=length(PopIn);if len>=1for i=1:lend=sort(unidrnd(n,1,2));if d(1)~=1&d(2)~=nNewPop(PopIn(i),1:d(1)-1)=OldPop(PopIn(i),1:d(1)-1);NewPop(PopIn(i),d(1):d(2))=OldPop(PopIn(i),d(2):-1:d(1));NewPop(PopIn(i),d(2)+1:n)=OldPop(PopIn(i),d(2)+1:n);endendend遗传算法程序(二):function youhuafunD=code;N=50; % Tunablemaxgen=50; % Tunablecrossrate=0.5; %Tunablemuterate=0.08; %Tunablegeneration=1;num = length(D);fatherrand=randint(num,N,3);score = zeros(maxgen,N);while generation<=maxgenind=randperm(N-2)+2; % 随机配对交叉A=fatherrand(:,ind(1:(N-2)/2));B=fatherrand(:,ind((N-2)/2+1:end));% 多点交叉rnd=rand(num,(N-2)/2);ind=rnd tmp=A(ind);A(ind)=B(ind);B(ind)=tmp;% % 两点交叉% for kk=1:(N-2)/2% rndtmp=randint(1,1,num)+1;% tmp=A(1:rndtmp,kk);% A(1:rndtmp,kk)=B(1:rndtmp,kk);% B(1:rndtmp,kk)=tmp;% endfatherrand=[fatherrand(:,1:2),A,B];% 变异rnd=rand(num,N);ind=rnd [m,n]=size(ind);tmp=randint(m,n,2)+1;tmp(:,1:2)=0;fatherrand=tmp+fatherrand;fatherrand=mod(fatherrand,3);% fatherrand(ind)=tmp;%评价、选择scoreN=scorefun(fatherrand,D);% 求得N个个体的评价函数score(generation,:)=scoreN;[scoreSort,scoreind]=sort(scoreN);sumscore=cumsum(scoreSort);sumscore=sumscore./sumscore(end);childind(1:2)=scoreind(end-1:end);for k=3:Ntmprnd=rand;tmpind=tmprnd difind=[0,diff(tmpind)];if ~any(difind)difind(1)=1;endchildind(k)=scoreind(logical(difind));endfatherrand=fatherrand(:,childind);generation=generation+1;end% scoremaxV=max(score,[],2);minV=11*300-maxV;plot(minV,'*');title('各代的目标函数值');F4=D(:,4);FF4=F4-fatherrand(:,1);FF4=max(FF4,1);D(:,5)=FF4;save DData Dfunction D=codeload youhua.mat% properties F2 and F3F1=A(:,1);F2=A(:,2);F3=A(:,3);if (max(F2)>1450)||(min(F2)<=900)error('DATA property F2 exceed it''s range (900,1450]')end% get group property F1 of data, according to F2 valueF4=zeros(size(F1));for ite=11:-1:1index=find(F2<=900+ite*50);F4(index)=ite;endD=[F1,F2,F3,F4];function ScoreN=scorefun(fatherrand,D)F3=D(:,3);F4=D(:,4);N=size(fatherrand,2);FF4=F4*ones(1,N);FF4rnd=FF4-fatherrand;FF4rnd=max(FF4rnd,1);ScoreN=ones(1,N)*300*11;% 这里有待优化for k=1:NFF4k=FF4rnd(:,k);for ite=1:11F0index=find(FF4k==ite);if ~isempty(F0index)tmpMat=F3(F0index);tmpSco=sum(tmpMat);ScoreBin(ite)=mod(tmpSco,300);endendScorek(k)=sum(ScoreBin);endScoreN=ScoreN-Scorek;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%遗传算法程序(三):%IAGAfunction best=gaclearMAX_gen=200; %最大迭代步数best.max_f=0; %当前最大的适应度STOP_f=14.5; %停止循环的适应度RANGE=[0 255]; %初始取值范围[0 255]SPEEDUP_INTER=5; %进入加速迭代的间隔advance_k=0; %优化的次数popus=init; %初始化for gen=1:MAX_genfitness=fit(popus,RANGE); %求适应度f=fitness.f;picked=choose(popus,fitness); %选择popus=intercross(popus,picked); %杂交popus=aberrance(popus,picked); %变异if max(f)>best.max_fadvance_k=advance_k+1;x_better(advance_k)=fitness.x;best.max_f=max(f);best.popus=popus;best.x=fitness.x;endif mod(advance_k,SPEEDUP_INTER)==0RANGE=minmax(x_better);RANGEadvance=0;endendreturn;function popus=init%初始化M=50;%种群个体数目N=30;%编码长度popus=round(rand(M,N));return;function fitness=fit(popus,RANGE)%求适应度[M,N]=size(popus);fitness=zeros(M,1);%适应度f=zeros(M,1);%函数值A=RANGE(1);B=RANGE(2);%初始取值范围[0 255]for m=1:Mx=0;for n=1:Nx=x+popus(m,n)*(2^(n-1));endx=x*((B-A)/(2^N))+A;for k=1:5f(m,1)=f(m,1)-(k*sin((k+1)*x+k));endendf_std=(f-min(f))./(max(f)-min(f));%函数值标准化fitness.f=f;fitness.f_std=f_std;fitness.x=x;return;function picked=choose(popus,fitness)%选择f=fitness.f;f_std=fitness.f_std;[M,N]=size(popus);choose_N=3; %选择choose_N对双亲picked=zeros(choose_N,2); %记录选择好的双亲p=zeros(M,1); %选择概率d_order=zeros(M,1);%把父代个体按适应度从大到小排序f_t=sort(f,'descend');%将适应度按降序排列for k=1:Mx=find(f==f_t(k));%降序排列的个体序号d_order(k)=x(1);endfor m=1:Mpopus_t(m,:)=popus(d_order(m),:);endpopus=popus_t;f=f_t;p=f_std./sum(f_std); %选择概率c_p=cumsum(p)'; %累积概率for cn=1:choose_Npicked(cn,1)=roulette(c_p); %轮盘赌picked(cn,2)=roulette(c_p); %轮盘赌popus=intercross(popus,picked(cn,:));%杂交endpopus=aberrance(popus,picked);%变异return;function popus=intercross(popus,picked) %杂交[M_p,N_p]=size(picked);[M,N]=size(popus);for cn=1:M_pp(1)=ceil(rand*N);%生成杂交位置p(2)=ceil(rand*N);p=sort(p);t=popus(picked(cn,1),p(1):p(2));popus(picked(cn,1),p(1):p(2))=popus(picked(cn,2),p(1):p(2));popus(picked(cn,2),p(1):p(2))=t;endreturn;function popus=aberrance(popus,picked) %变异P_a=0.05;%变异概率[M,N]=size(popus);[M_p,N_p]=size(picked);U=rand(1,2);for kp=1:M_pif U(2)>=P_a %如果大于变异概率,就不变异continue;endif U(1)>=0.5a=picked(kp,1);elsea=picked(kp,2);endp(1)=ceil(rand*N);%生成变异位置p(2)=ceil(rand*N);if popus(a,p(1))==1%0 1变换popus(a,p(1))=0;elsepopus(a,p(1))=1;endif popus(a,p(2))==1popus(a,p(2))=0;elsepopus(a,p(2))=1;endendreturn;function picked=roulette(c_p) %轮盘赌[M,N]=size(c_p);M=max([M N]);U=rand;if U<c_p(1)picked=1;return;endfor m=1:(M-1)if U>c_p(m) & U<c_p(m+1)picked=m+1;break;endend全方位的两点杂交、两点变异的改进的加速遗传算法(IAGA)%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%。

遗传算法的C语言程序案例

遗传算法的C语言程序案例

遗传算法的C语言程序案例一、说明1.本程序演示的是用简单遗传算法随机一个种群,然后根据所给的交叉率,变异率,世代数计算最大适应度所在的代数2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的命令;相应的输入数据和运算结果显示在其后。

3.举个例子,输入初始变量后,用y= (x1*x1)+(x2*x2),其中-2.048<=x1,x2<=2.048作适应度函数求最大适应度即为函数的最大值4.程序流程图5.类型定义int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individual{char chrom[chromlength+1];double value;double fitness; //适应度};int generation; //世代数int best_index;int worst_index;struct individual bestindividual; //最佳个体struct individual worstindividual; //最差个体struct individual currentbest;struct individual population[POPSIZE];3.函数声明void generateinitialpopulation();void generatenextpopulation();void evaluatepopulation();long decodechromosome(char *,int,int);void calculateobjectvalue();void calculatefitnessvalue();void findbestandworstindividual();void performevolution();void selectoperator();void crossoveroperator();void mutationoperator();void input();void outputtextreport();6.程序的各函数的简单算法说明如下:(1).void generateinitialpopulation ()和void input ()初始化种群和遗传算法参数。

遗传算法的C语言实现(二)-----以求解TSP问题为例

遗传算法的C语言实现(二)-----以求解TSP问题为例

遗传算法的C语⾔实现(⼆)-----以求解TSP问题为例上⼀次我们使⽤遗传算法求解了⼀个较为复杂的多元⾮线性函数的极值问题,也基本了解了遗传算法的实现基本步骤。

这⼀次,我再以经典的TSP问题为例,更加深⼊地说明遗传算法中选择、交叉、变异等核⼼步骤的实现。

⽽且这⼀次解决的是离散型问题,上⼀次解决的是连续型问题,刚好形成对照。

⾸先介绍⼀下TSP问题。

TSP(traveling salesman problem,旅⾏商问题)是典型的NP完全问题,即其最坏情况下的时间复杂度随着问题规模的增⼤按指数⽅式增长,到⽬前为⽌还没有找到⼀个多项式时间的有效算法。

TSP问题可以描述为:已知n个城市之间的相互距离,某⼀旅⾏商从某⼀个城市出发,访问每个城市⼀次且仅⼀次,最后回到出发的城市,如何安排才能使其所⾛的路线最短。

换⾔之,就是寻找⼀条遍历n个城市的路径,或者说搜索⾃然⼦集X={1,2,...,n}(X的元素表⽰对n个城市的编号)的⼀个排列P(X)={V1,V2,....,Vn},使得Td=∑d(V i,V i+1)+d(V n,V1)取最⼩值,其中,d(V i,V i+1)表⽰城市V i到V i+1的距离。

TSP问题不仅仅是旅⾏商问题,其他许多NP完全问题也可以归结为TSP问题,如邮路问题,装配线上的螺母问题和产品的⽣产安排问题等等,也使得TSP问题的求解具有更加⼴泛的实际意义。

再来说针对TSP问题使⽤遗传算法的步骤。

(1)编码问题:由于这是⼀个离散型的问题,我们采⽤整数编码的⽅式,⽤1~n来表⽰n个城市,1~n的任意⼀个排列就构成了问题的⼀个解。

可以知道,对于n个城市的TSP问题,⼀共有n!种不同的路线。

(2)种群初始化:对于N个个体的种群,随机给出N个问题的解(相当于是染⾊体)作为初始种群。

这⾥具体采⽤的⽅法是:1,2,...,n作为第⼀个个体,然后2,3,..n分别与1交换位置得到n-1个解,从2开始,3,4,...,n分别与2交换位置得到n-2个解,依次类推。

遗传算法及其MATLAB程序代码

遗传算法及其MATLAB程序代码

遗传算法及其MATLAB程序代码遗传算法及其MATLAB实现主要参考书:MATLAB 6.5 辅助优化计算与设计飞思科技产品研发中⼼编著电⼦⼯业出版社2003.1遗传算法及其应⽤陈国良等编著⼈民邮电出版社1996.6主要内容:遗传算法简介遗传算法的MATLAB实现应⽤举例在⼯业⼯程中,许多最优化问题性质⼗分复杂,很难⽤传统的优化⽅法来求解.⾃1960年以来,⼈们对求解这类难解问题⽇益增加.⼀种模仿⽣物⾃然进化过程的、被称为“进化算法(evolutionary algorithm)”的随机优化技术在解这类优化难题中显⽰了优于传统优化算法的性能。

⽬前,进化算法主要包括三个研究领域:遗传算法、进化规划和进化策略。

其中遗传算法是迄今为⽌进化算法中应⽤最多、⽐较成熟、⼴为⼈知的算法。

⼀、遗传算法简介遗传算法(Genetic Algorithm, GA)最先是由美国Mic-hgan⼤学的John Holland于1975年提出的。

遗传算法是模拟达尔⽂的遗传选择和⾃然淘汰的⽣物进化过程的计算模型。

它的思想源于⽣物遗传学和适者⽣存的⾃然规律,是具有“⽣存+检测”的迭代过程的搜索算法。

遗传算法以⼀种群体中的所有个体为对象,并利⽤随机化技术指导对⼀个被编码的参数空间进⾏⾼效搜索。

其中,选择、交叉和变异构成了遗传算法的遗传操作;参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定等5个要素组成了遗传算法的核⼼内容。

遗传算法的基本步骤:遗传算法是⼀种基于⽣物⾃然选择与遗传机理的随机搜索算法,与传统搜索算法不同,遗传算法从⼀组随机产⽣的称为“种群(Population)”的初始解开始搜索过程。

种群中的每个个体是问题的⼀个解,称为“染⾊体(chromos ome)”。

染⾊体是⼀串符号,⽐如⼀个⼆进制字符串。

这些染⾊体在后续迭代中不断进化,称为遗传。

在每⼀代中⽤“适值(fitness)”来测量染⾊体的好坏,⽣成的下⼀代染⾊体称为后代(offspring)。

用遗传算法求解多目标函数优化c++程序

用遗传算法求解多目标函数优化c++程序

遗传算法是一种优化搜索方法,它模拟了自然选择和遗传学中的一些概念,如基因突变、交叉和选择。

这种方法可以用于解决多目标优化问题,其中多个目标之间可能存在冲突。

以下是一个使用C++和OpenCV库实现遗传算法的基本示例。

这个例子解决的是一个简单的多目标优化问题,目标是找到一个最优的图像分割方案,使得两个目标(分割的精度和计算的效率)同时最大化。

注意:这个示例是为了演示遗传算法的基本概念,并不一定适用于所有问题。

你可能需要根据你的具体需求来调整遗传算法的参数和约束条件。

```cpp#include <iostream>#include <vector>#include <algorithm>#include <opencv2/opencv.hpp>// 多目标函数优化struct ObjectiveFunction {std::vector<double> values;void operator()(const std::vector<double>& x) const {// 这里应该根据你的具体问题来定义函数的具体形式// 这里只是一个简单的示例,只考虑了分割精度和计算效率两个目标values.resize(x.size(), 0); // 初始化所有目标值为0values[0] = 1.0; // 精度目标values[1] = 1.0; // 效率目标}};class GeneticAlgorithm {public:GeneticAlgorithm(int populationSize, int generations, double crossoverRate, double mutationRate) : populationSize(populationSize), generations(generations), crossoverRate(crossoverRate), mutationRate(mutationRate) {} std::vector<std::vector<double>> optimize(const std::vector<std::vector<double>>& inputs) {std::vector<std::vector<double>>bestSolution(inputs.size(),std::vector<double>(populationSize, 0)); // 初始化最优解double bestScore = -1; // 初始最佳分数为-1,通常需要先运行一次算法以找到初始最佳分数for (int generation = 0; generation <generations; ++generation) {std::vector<std::vector<double>>population(populationSize,std::vector<double>(populationSize, 0)); // 初始化种群for (int i = 0; i < populationSize; ++i) { std::vector<double>randomSolution(inputs.size(), 0); // 随机生成解for (int j = 0; j < inputs.size(); ++j) {randomSolution[j] = inputs[j][rand() % inputs[j].size()]; // 在输入范围内随机选择一个数作为解}population[i] = randomSolution; // 将随机解加入种群}while (!population.empty()) { // 当种群不为空时继续迭代std::sort(population.begin(), population.end(), [](const std::vector<double>& a, const std::vector<double>& b) { // 对种群进行排序,根据适应度进行排序(这里适应度是解的分数)return ObjectiveFunction()(a) > ObjectiveFunction()(b); // 如果分数更高,则适应度更好,优先选择这个解作为下一代解的一部分});std::vector<double>nextGeneration(population[0]); // 选择当前种群中的第一个解作为下一代解的一部分for (int j = 1; j < populationSize; ++j) { // 对剩余的解进行交叉和变异操作,生成下一代解if (rand() / double(RAND_MAX) < crossoverRate) { // 如果满足交叉条件,则进行交叉操作for (int k = 0; k < inputs.size(); ++k) { // 将两个解的部分基因进行交叉操作,生成新的基因序列nextGeneration[k] = population[j][k]; // 将两个解的部分基因复制到下一代解中if (rand() / double(RAND_MAX) < mutationRate) { // 如果满足变异条件,则对部分基因进行变异操作,增加种群的多样性nextGeneration[k] = nextGeneration[k] * (1 - mutationRate) + population[j][k] * mutationRate; // 对部分基因进行变异操作,增加种群的多样性}}} else { // 如果不满足交叉条件,则直接复制当前解作为下一代解的一部分for (int k = 0; k < inputs.size(); ++k) { // 将当前解的部分基因复制到下一代解中 nextGeneration[k] = population[。

遗传算法的原理及MATLAB程序实现

遗传算法的原理及MATLAB程序实现

遗传算法的原理及MATLAB程序实现1 遗传算法的原理1.1 遗传算法的基本思想遗传算法(genetic algorithms,GA)是一种基于自然选择和基因遗传学原理,借鉴了生物进化优胜劣汰的自然选择机理和生物界繁衍进化的基因重组、突变的遗传机制的全局自适应概率搜索算法。

遗传算法是从一组随机产生的初始解(种群)开始,这个种群由经过基因编码的一定数量的个体组成,每个个体实际上是染色体带有特征的实体。

染色体作为遗传物质的主要载体,其内部表现(即基因型)是某种基因组合,它决定了个体的外部表现。

因此,从一开始就需要实现从表现型到基因型的映射,即编码工作。

初始种群产生后,按照优胜劣汰的原理,逐代演化产生出越来越好的近似解。

在每一代,根据问题域中个体的适应度大小选择个体,并借助于自然遗传学的遗传算子进行组合交叉和变异,产生出代表新的解集的种群。

这个过程将导致种群像自然进化一样,后代种群比前代更加适应环境,末代种群中的最优个体经过解码,可以作为问题近似最优解。

计算开始时,将实际问题的变量进行编码形成染色体,随机产生一定数目的个体,即种群,并计算每个个体的适应度值,然后通过终止条件判断该初始解是否是最优解,若是则停止计算输出结果,若不是则通过遗传算子操作产生新的一代种群,回到计算群体中每个个体的适应度值的部分,然后转到终止条件判断。

这一过程循环执行,直到满足优化准则,最终产生问题的最优解。

图1-1给出了遗传算法的基本过程。

1.2 遗传算法的特点1.2.1 遗传算法的优点遗传算法具有十分强的鲁棒性,比起传统优化方法,遗传算法有如下优点:1. 遗传算法以控制变量的编码作为运算对象。

传统的优化算法往往直接利用控制变量的实际值的本身来进行优化运算,但遗传算法不是直接以控制变量的值,而是以控制变量的特定形式的编码为运算对象。

这种对控制变量的编码处理方式,可以模仿自然界中生物的遗传和进化等机理,也使得我们可以方便地处理各种变量和应用遗传操作算子。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一需求分析1.本程序演示的是用简单遗传算法随机一个种群,然后根据所给的交叉率,变异率,世代数计算最大适应度所在的代数2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的命令;相应的输入数据和运算结果显示在其后。

3.测试数据输入初始变量后用y=100*(x1*x1-x2)*(x1*x2-x2)+(1-x1)*(1-x1)其中-2.048<=x1,x2<=2.048作适应度函数求最大适应度即为函数的最大值二概要设计1.程序流程图2.类型定义int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individual{char chrom[chromlength+1];double value;double fitness; //适应度};int generation; //世代数int best_index;int worst_index;struct individual bestindividual; //最佳个体struct individual worstindividual; //最差个体struct individual currentbest;struct individual population[POPSIZE];3.函数声明void generateinitialpopulation();void generatenextpopulation();void evaluatepopulation();long decodechromosome(char *,int,int);void calculateobjectvalue();void calculatefitnessvalue();void findbestandworstindividual();void performevolution();void selectoperator();void crossoveroperator();void mutationoperator();void input();void outputtextreport();4.程序的各函数的简单算法说明如下:(1).void generateinitialpopulation ()和void input ()初始化种群和遗传算法参数。

input() 函数输入种群大小,染色体长度,最大世代数,交叉率,变异率等参数。

(2)void calculateobjectvalue();计算适应度函数值。

根据给定的变量用适应度函数计算然后返回适度值。

(3)选择函数selectoperator()在函数selectoperator()中首先用rand ()函数产生0~1间的选择算子,当适度累计值不为零时,比较各个体所占总的适应度百分比的累计和与选择算子,直到达到选择算子的值那个个体就被选出,即适应度为fi的个体以fi/∑fk的概率继续存在;显然,个体适应度愈高,被选中的概率愈大。

但是,适应度小的个体也有可能被选中,以便增加下一代群体的多样性。

(4)染色体交叉函数crossoveroperator()这是遗传算法中的最重要的函数之一,它是对个体两个变量所合成的染色体进行交叉,而不是变量染色体的交叉,这要搞清楚。

首先用rand ()函数产生随机概率,若小于交叉概率,则进行染色体交叉,同时交叉次数加1。

这时又要用rand()函数随机产生一位交叉位,把染色体的交叉位的后面部分交叉即可;若大于交叉概率,则进行简单的染色体复制即可。

(5)染色体变异函数mutation()变异是针对染色体字符变异的,而不是对个体而言,即个体变异的概率是一样。

随机产生比较概率,若小于变异概率,则1变为0,0变为1,同时变异次数加1。

(6)long decodechromosome(char *,int,int)本函数是染色体解码函数,它将以数组形式存储的二进制数转成十进制数,然后才能用适应度函数计算。

(7)void findbestandworstindividual()本函数是求最大适应度个体的,每一代的所有个体都要和初始的最佳比较,如果大于就赋给最佳。

(8)void outputtextreport () 输出种群统计结果输出每一代的种群的最大适应度和平均适应度,最后输出全局最大值三运行环境本程序的开发工具是VC++,在VC++下运行。

四源代码#include <stdio.h>#include<stdlib.h>#include<time.h>#include<math.h>#define POPSIZE 500#define maximization 1#define minimization 2#define cmax 100#define cmin 0#define length1 10#define length2 10#define chromlength length1+length2 //染色体长度int functionmode=maximization;int popsize; //种群大小int maxgeneration; //最大世代数double pc; //交叉率double pm; //变异率struct individual{char chrom[chromlength+1];double value;double fitness; //适应度};int generation; //世代数int best_index;int worst_index;struct individual bestindividual; //最佳个体struct individual worstindividual; //最差个体struct individual currentbest;struct individual population[POPSIZE];//函数声明void generateinitialpopulation();void generatenextpopulation();void evaluatepopulation();long decodechromosome(char *,int,int);void calculateobjectvalue();void calculatefitnessvalue();void findbestandworstindividual();void performevolution();void selectoperator();void crossoveroperator();void mutationoperator();void input();void outputtextreport();void generateinitialpopulation( ) //种群初始化{int i,j;for (i=0;i<popsize; i++){for(j=0;j<chromlength;j++){population[i].chrom[j]=(rand()%10<5)?'0':'1';}population[i].chrom[chromlength]='\0';}}void generatenextpopulation() //生成下一代{selectoperator();crossoveroperator();mutationoperator();}void evaluatepopulation() //评价个体,求最佳个体{calculateobjectvalue();calculatefitnessvalue();findbestandworstindividual();}long decodechromosome(char *string ,int point,int length) //给染色体解码{int i;long decimal=0;char*pointer;for(i=0,pointer=string+point;i<length;i++,pointer++)if(*pointer-'0'){decimal +=(long)pow(2,i);}return (decimal);}void calculateobjectvalue() //计算函数值{int i;long temp1,temp2;double x1,x2;for (i=0; i<popsize; i++){temp1=decodechromosome(population[i].chrom,0,length1);temp2=decodechromosome(population[i].chrom,length1,length2);x1=4.096*temp1/1023.0-2.048;x2=4.096*temp2/1023.0-2.048;population[i].value=100*(x1*x1-x2)* (x1*x1-x2)+(1-x1)*(1-x1);}}void calculatefitnessvalue()//计算适应度{int i;double temp;for(i=0;i<popsize;i++){if(functionmode==maximization){if((population[i].value+cmin)>0.0){temp=cmin+population[i].value;}else{temp=0.0;}}else if (functionmode==minimization){if(population[i].value<cmax){temp=cmax-population[i].value;}else{ temp=0.0;}}population[i].fitness=temp;}}void findbestandworstindividual( ) //求最佳个体和最差个体{int i;double sum=0.0;bestindividual=population[0];worstindividual=population[0];for (i=1;i<popsize; i++){if (population[i].fitness>bestindividual.fitness){bestindividual=population[i];best_index=i;}else if (population[i].fitness<worstindividual.fitness) {worstindividual=population[i];worst_index=i;}sum+=population[i].fitness;}if (generation==0){currentbest=bestindividual;}else{if(bestindividual.fitness>=currentbest.fitness){currentbest=bestindividual;}}}void performevolution() //演示评价结果{if (bestindividual.fitness>currentbest.fitness){currentbest=population[best_index];}else{population[worst_index]=currentbest;}}void selectoperator() //比例选择算法{int i,index;double p,sum=0.0;double cfitness[POPSIZE];struct individual newpopulation[POPSIZE];for(i=0;i<popsize;i++){sum+=population[i].fitness;}for(i=0;i<popsize; i++){cfitness[i]=population[i].fitness/sum;}for(i=1;i<popsize; i++){cfitness[i]=cfitness[i-1]+cfitness[i];}for (i=0;i<popsize;i++){p=rand()%1000/1000.0;index=0;while (p>cfitness[index]){index++;}newpopulation[i]=population[index];}for(i=0;i<popsize; i++){population[i]=newpopulation[i];}}void crossoveroperator() //交叉算法{int i,j;int index[POPSIZE];int point,temp;double p;char ch;for (i=0;i<popsize;i++){index[i]=i;}for (i=0;i<popsize;i++){point=rand()%(popsize-i);temp=index[i];index[i]=index[point+i];index[point+i]=temp;}for (i=0;i<popsize-1;i+=2){p=rand()%1000/1000.0;if (p<pc){point=rand()%(chromlength-1)+1;for (j=point; j<chromlength;j++){ch=population[index[i]].chrom[j];population[index[i]].chrom[j]=population[index[i+1]].chrom[j];population[index[i+1]].chrom[j]=ch;}}}}void mutationoperator() //变异操作{int i,j;double p;for (i=0;i<popsize;i++){for(j=0;j<chromlength;j++){p=rand()%1000/1000.0;if (p<pm){population[i].chrom[j]=(population[i].chrom[j]=='0')?'1':'0';}}}}void input() //数据输入{ printf("初始化全局变量:\n");printf(" 种群大小(50-500):");scanf("%d", &popsize);if((popsize%2) != 0){printf( " 种群大小已设置为偶数\n");popsize++;};printf(" 最大世代数(100-300):");scanf("%d", &maxgeneration);printf(" 交叉率(0.2-0.99):");scanf("%f", &pc);printf(" 变异率(0.001-0.1):");scanf("%f", &pm);}void outputtextreport()//数据输出{int i;double sum;double average;sum=0.0;for(i=0;i<popsize;i++){sum+=population[i].value;}average=sum/popsize;printf("当前世代=%d\n当前世代平均函数值=%f\n当前世代最高函数值=%f\n",generation,average,population[best_index].value);}void main() //主函数{ int i;printf("本程序为求函数y=100*(x1*x1-x2)*(x1*x2-x2)+(1-x1)*(1-x1)的最大值\n其中-2.048<=x1,x2<=2.048\n");generation=0;input();generateinitialpopulation();evaluatepopulation();while(generation<maxgeneration){generation++;generatenextpopulation();evaluatepopulation();performevolution();outputtextreport();}printf("\n");printf(" 统计结果: ");printf("\n");printf("最大函数值等于:%f\n",currentbest.fitness);printf("其染色体编码为:");for (i=0;i<chromlength;i++){printf("%c",currentbest.chrom[i]);}printf("\n"); }六测试结果。

相关文档
最新文档