helen 发表于 2005-4-15 22:51

[原创]基于MATLAB6.5遗传算法程序

<P>function =fmaxga(FUN,LB,UB,eranum,popsize,pcross,pmutation,options)
% =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 t  LB &lt;= X &lt;= UB                           
%  BestPop--------最优的群体即为最优的染色体群
%  Trace----------最佳染色体所对应的目标函数值
%  FUN------------目标函数
%  LB-------------自变量下限
%  UB-------------自变量上限
%  eranum---------种群的代数,取100--1000(默认1000)
%  popsize--------每一代种群的规模;此可取50--100(默认50)
%  pcross---------交叉的概率,此概率一般取0.5--0.85之间较好(默认0.8)
%  pmutation------变异的概率,该概率一般取0.05-0.2左右较好(默认0.1)
%  options--------1×2矩阵,options(1)=0二进制编码(默认0),option(1)~=0十进制编码,option(2)设定求解精度(默认1e-4)
%                 
% 例如测试Shaffer's F6函数,自变量下限[-100,-100],上限,当x=时,MaxF6=1
% 运行得到相当好的结果:自变量为 0.00033379-4.7684e-005 时,最优值 1.000000
% 对应染色体是:1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  0  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1</P>
<P>T1=clock;
if nargin&lt;3, error('FMAXGA requires at least three input arguments'); end
if nargin==3, eranum=1000;popsize=50;pcross=0.8;pmutation=0.1;options=;end
if nargin==4, popsize=50;pcross=0.8;pmutation=0.1;options=;end
if nargin==5, pcross=0.8;pmutation=0.1;options=;end
if nargin==6, pmutation=0.1;options=;end
if nargin==7, options=;end
if find((LB-UB)&gt;0)
   error('数据输入错误,请重新输入(LB&lt;UB):');
end
s=sprintf('程序运行需要约%.4f 秒钟时间,请稍等......',(eranum*popsize*40/(1000*50)));
disp(s);
bounds=';bits=[];
precision=options(2);%由求解精度确定二进制编码长度
bits=ceil(log2((bounds(:,2)-bounds(:,1))' ./ precision));%由设定精度划分区间
=initpop(popsize,bits);%初始化种群
=size(Pop);
pm0=pmutation;
BestPop=zeros(eranum,n);Trace=zeros(eranum,length(bits)+1);%分配初始解空间
i=1;
while i&lt;=eranum
    for j=1:m
        value(j)=feval(FUN(1,:),(b2f(Pop(j,:),bounds,bits)));%计算适应度
    end
    =max(value);
    BestPop(i,:)=Pop(Index,:);
    Trace(i,1)=MaxValue;
    Trace(i,(2:length(bits)+1))=b2f(BestPop(i,:),bounds,bits);
    =SelectChrom(FUN,Pop,bounds,bits);%选择
    =CrossOver(selectpop,pcross);%交叉
    =Mutation(CrossOverPop,pmutation);%变异
    Pop=NewPop;%更新
    pmutation=pm0+(i^4)*(pcross/2-pm0)/(eranum^4); %随着种群向前进化,逐步增大变异率
    p(i)=pmutation;
    i=i+1;
end
t=1:eranum;
plot(t,Trace(:,1)');
title('函数优化的遗传算法');xlabel('进化世代数(eranum)');ylabel('每一代最优适应度(maxfitness)');
=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;
CostTime=T2-T1;
if CostTime(6)&lt;0
    CostTime(6)=CostTime(6)+60; CostTime(5)=CostTime(5)-1;
end
if CostTime(5)&lt;0
    CostTime(5)=CostTime(5)+60;CostTime(4)=CostTime(4)-1;
end  %像这种程序当然不考虑运行上小时啦
str2=sprintf('程序运行耗时 %d 小时 %d 分钟 %.4f 秒',CostTime(4),CostTime(5),CostTime(6));
disp(str2);</P>
<P>%初始化种群,采用二进制编码
function =initpop(popsize,bits)
len=sum(bits);
pop(1,:)=zeros(1,len);%The whole zero encoding
for i=2:popsize-1
    pop(i,:)=round(rand(1,len));
end
pop(popsize,:)=ones(1,len);%The whole one encoding</P>
<P>%解码
function = b2f(bval,bounds,bits)
% fval   - 表征各变量的十进制数
% bval   - 表征各变量的二进制编码串
% bounds - 各变量的取值范围
% bits   - 各变量的二进制编码长度
scale=(bounds(:,2)-bounds(:,1))'./(2.^bits-1); %The range of the variables
numV=size(bounds,1);
cs=;
for i=1:numV
  a=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>
<P>%选择操作
function =SelectChrom(FUN,pop,bounds,bits)%计算各个体的适应度并采用轮盘赌进行选择
=size(pop);
for i=1:m
    fit(i)=feval(FUN(1,:),(b2f(pop(i,:),bounds,bits)));%以函数值为适应度
end
selectprob=fit/sum(fit);%选择概率
prob=cumsum(selectprob);%累计选择概率
sumprob=;
for i=1:m
    selectpop(i,:)=pop(length(find(rand&gt;=sumprob)),:);
end   
   
%交叉操作
function =CrossOver(OldPop,pcross)%OldPop为父代种群,pcross为交叉概率
=size(OldPop);
r=rand(1,m);
y1=find(r&lt;pcross);
y2=find(r&gt;=pcross);
len=length(y1);
if len&gt;2&amp;mod(len,2)==1%如果用来进行交叉的染色体的条数为奇数,将其调整为偶数
    y2(length(y2)+1)=y1(len);
    y1(len)=[];
end
if length(y1)&gt;=2
   for i=0:2:length(y1)-2
       =EqualCrossOver(OldPop(y1(i+1),:),OldPop(y1(i+2),:));
   end     
end
NewPop(y2,:)=OldPop(y2,:);</P>
<P>function =EqualCrossOver(parent1,parent2)
%采用均匀交叉 例:
%父1:0 1 1 1 0 0 1 1 0 1 0
%父2:1 0 1 0 1 1 0 0 1 0 1
%掩码:0 1 1 0 0 0 1 1 0 1 0
%交叉后新个体:
%子1:1 1 1 0 1 1 1 1 1 1 1
%子2:0 0 1 1 0 0 0 0 0 0 0
L=length(parent1);
hidecode=round(rand(1,L));%随机生成掩码,如hidecode=;
children1=zeros(1,L);
children2=zeros(1,L);
children1(find(hidecode==1))=parent1(find(hidecode==1));%掩码为1,父1为子1提供基因
children1(find(hidecode==0))=parent2(find(hidecode==0));%掩码为0,父2为子1提供基因
children2(find(hidecode==1))=parent2(find(hidecode==1));%掩码为1,父2为子2提供基因
children2(find(hidecode==0))=parent1(find(hidecode==0));%掩码为0,父1为子2提供基因</P>
<P>%变异操作
function =Mutation(OldPop,pmutation)
=size(OldPop);
r=rand(1,m);
position=find(r&lt;=pmutation);
len=length(position);
if len&gt;=1
   for i=1:len
       k=unidrnd(n,1,1); %设置变异点数,一般设置1点
       for j=1:length(k)
           if OldPop(position(i),k(j))==1
              OldPop(position(i),k(j))=0;
           else
              OldPop(position(i),k(j))=1;
           end
       end
   end
end
NewPop=OldPop;
    </P>

more_er 发表于 2005-11-14 10:15

<P>使劲顶</P>

海燕 发表于 2005-10-18 16:26

不胜感谢!

birdnick 发表于 2005-11-25 21:28

<P>ding!!!</P>

小杰200521 发表于 2006-2-2 10:30

<P>还不错</P>

ligoden 发表于 2006-3-20 07:02

好象matlab里有<strong>遗传工具箱可用</strong>

j_zh_cui 发表于 2006-5-11 10:09

谢谢

echo5183 发表于 2006-11-29 14:18

denghuiyang205 发表于 2007-2-1 03:14

看看

yelin5147 发表于 2006-12-27 15:31

<p>谢谢啦</p>
页: [1] 2 3 4 5
查看完整版本: [原创]基于MATLAB6.5遗传算法程序