Advertisement

优化算法之遗传算法

阅读量:

具体原理不讲了,网上很有多博客,这里直接上代码:

1.编码

复制代码
 function [Pop,ChromLength,ParaLen,NumParameter] = Coding(PopSize,varargin)

    
 %对需要优化的参数进行编码
    
 %{
    
 输入:
    
 PopSize:种群数量
    
 varargin:可变输入参数,其中为需要优化的参数
    
  
    
 输出;
    
 Pop:初始化种群
    
 ChromLength:染色体长度
    
 ParaLen:每个优化参数转换成二进制的长度
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
 NumParameter = nargin-1;
    
 for i = 1:NumParameter
    
     ParaLen(i) = length(dec2bin( cell2mat( varargin(i) ) ) );
    
 end
    
 %染色体长度
    
 ChromLength = sum(ParaLen);
    
 %初始化种群
    
 Pop = round(rand(PopSize,ChromLength));

2.解码

复制代码
 function PopDec = DeCoding(Pop,NumParameter,ParaLen)

    
 %进行解码
    
 %{
    
 输入:
    
 BestIndividual:最优个体
    
 NumParameter:优化参数的数量
    
 ParaLen:每个优化参数的二进制长度
    
  
    
 输出:
    
 BestIndividualDec:最优个体的十进制编码形式(结构体)
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
 ParaLen = [1,ParaLen];
    
 PopSize = size(Pop,1);
    
 PopDec = zeros(PopSize,NumParameter);
    
 for i = 1:PopSize
    
 for j = 1:NumParameter
    
     PopDec(i,j) = bin2dec( num2str( Pop( i , ParaLen(j):ParaLen(j+1) ) ) );
    
 end
    
 end

3.选择

复制代码
 function NewPop = Selection(Pop,NumParameter,ParaLen)

    
 %根据适应度选择新的个体
    
 %{
    
 Pop:种群
    
  
    
 输出:
    
 NewPop:经过选择后的种群
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
 Fitness = CalFitness(Pop,NumParameter,ParaLen);
    
 [PopSize,ChromLength] = size(Pop);
    
 %轮盘赌算法
    
 TotalFitness = sum(Fitness);
    
 IndividualFitness = Fitness ./ TotalFitness;
    
 %构建轮盘
    
 IndividualFitness = cumsum(IndividualFitness);
    
 %随机产生概率
    
 Probability = sort( rand( PopSize,1) );
    
 %判断随机产生的概率所在从而选择种群
    
 NewPop = zeros(PopSize,ChromLength);
    
 NewLabel = 1;
    
 Label = 1;
    
 while NewLabel <= PopSize
    
     if Probability(NewLabel) < IndividualFitness(Label)
    
     NewPop(NewLabel,:) = Pop(Label,:);
    
     NewLabel = NewLabel+1;
    
     else
    
     Label = Label + 1;
    
     end
    
 end

4.交叉

复制代码
 function NewPop = CrossOver(Pop,CrossOverPro)

    
 %种群交叉
    
 %{
    
 输入:
    
 Pop:种群
    
 CrossOverPro:交叉概率
    
  
    
 输出:
    
 NewPop:交叉之后新的种群
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
 [PopSize,ChromLength] = size( Pop );
    
 NewPop = zeros(PopSize,ChromLength);
    
 for i = 1:2:PopSize-1
    
     if rand < CrossOverPro
    
     ChangePoint = round(rand*ChromLength);%交叉位置确定
    
     NewPop(i,:) = [Pop(i,1:ChangePoint) , Pop(i+1,ChangePoint+1:end)];
    
     NewPop(i+1,:) = [Pop(i+1,1:ChangePoint), Pop(i,ChangePoint+1:end)];
    
     else
    
     NewPop(i,:) = Pop(i,:);
    
     NewPop(i+1,:) = Pop(i+1,:)
    
     end
    
 end

5.变异

复制代码
 function  NewPop = Mutation(Pop,MutationPro)

    
 %种群变异
    
 %{
    
 输入:
    
 Pop:种群
    
 MutationPro:变异概率
    
  
    
 输出:
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
 [PopSize,ChromLength] = size(Pop);
    
 NewPop = zeros(PopSize,ChromLength);
    
 for i = 1:PopSize
    
     if rand < MutationPro
    
     MutationPoint = round(rand*ChromLength);
    
     if MutationPoint == 0
    
         MutationPoint = 1;
    
     end
    
     NewPop(i,:) = Pop(i,:);
    
     if NewPop(i,MutationPoint) == 0
    
         NewPop(i,MutationPoint) =1;
    
     else 
    
         NewPop(i,MutationPoint) =0;
    
     end
    
     else
    
     NewPop(i,:) = Pop(i,:);
    
     end
    
 end

6.计算适应度(根据自己问题更改适应度)

复制代码
 function Fitness = CalFitness(Pop,NumParameter,ParaLen)

    
 %计算种群中每个个体的适应度
    
 %{
    
 输入:
    
 Pop:种群
    
  
    
 输出:
    
  
    
 日期:
    
 20190902_ZD
    
 %}
    
  
    
 PopDec = DeCoding(Pop,NumParameter,ParaLen);
    
 PopSize = size(Pop,1);
    
 for i = 1:PopSize
    
     %计算适应度
    
     Fitness = 10*sin(5*PopDec)+abs(PopDec-5)+10;
    
 %     Fitness = 1 ./ Fitness;
    
 end

7.主函数

复制代码
 function main()

    
 clear;clc;close all;
    
 warning off
    
 %初始化参数
    
 PopSize = 10;%种群大小
    
 CrossOverPro = 0.06;%交叉概率
    
 MutationPro = 0.001;%变异概率
    
 %优化参数
    
 [Pop,ChromLength,ParaLen,NumParameter] = Coding(PopSize,1000);
    
  
    
 %循环
    
 for i = 1:300
    
     %计算适应度
    
     Fitness = CalFitness(Pop,NumParameter,ParaLen);
    
     %选择操作
    
     NewPop = Selection(Pop,NumParameter,ParaLen);
    
     %交叉操作
    
     NewPop = CrossOver(NewPop,CrossOverPro);
    
     %变异操作
    
     NewPop = Mutation(NewPop,MutationPro);
    
     %更新种群
    
     Pop = NewPop;
    
     %寻找最优参数
    
     [BestIndividual,BestFitness] = SelectBestIndividual(Pop,NumParameter,ParaLen);
    
     x2 = DeCoding(BestIndividual,NumParameter,ParaLen);
    
     x1 = DeCoding(Pop,NumParameter,ParaLen);
    
     y1 = CalFitness(Pop,NumParameter,ParaLen);
    
     if mod(i,100) == 0
    
     figure
    
     fplot('10*sin(5*x)+abs(x-5)+10');
    
     hold on
    
     plot(x1,y1,'*')
    
     title(['迭代次数为n=',num2str(i)]);
    
     end
    
 end

全部评论 (0)

还没有任何评论哟~