Bootstrap

遗传算法——matlab实现

1. 遗传算法的原理

网上实在太多了,这里就不过多赘述了

2. 主函数

% 遗传算法 
%sum(x)的最小值(具体要求见fun.m)
clc;clear

nVar = 100; % x的长度
nPop = 30;  % 种群规模大小为30
maxIt = 2000; % 最大迭代次数
nPc = 0.8; % 子代规模的比例
nC = round(nPop * nPc/2)*2;% 子代规模的大小 round()得出最接近的整数,同时进行偶数化操作
nMu = 0.01; % 变异概率为0.01

% 用结构体方式来存储变量,使得x,y有一个绑定的关系
template.x = []; % 模板
template.y = []; % 模板
% repmat函数主要是用于快速的产生一个大的矩阵
Parent = repmat(template,nPop,1); % 父染色体,产生一个30*1的矩阵,每行包括x和y

% 初始化种群
for i = 1 : nPop
    Parent(i).x = randi([0,1],1,nVar); % 随机生成100个【0,1】的x值
    Parent(i).y = fun(Parent(i).x); % 计算适应度,也就是目标函数
end

for It = 1 : maxIt
    Offspring = repmat(template,nC/2,2); % 分成两列为了好进行数据的交叉操作
    for j = 1 : nC/2
        p1 = SelectPop(Parent);
        p2 = SelectPop(Parent);
        [Offspring(j,1).x, Offspring(j,2).x] = crossPop(p1.x, p2.x); % 进行交叉操作
    end
    Offspring = Offspring(:); % 变成列的形式,便于写for循环

    for k = 1 : nC
        Offspring(k).x = mutatePop(Offspring(k).x,nMu); % 进行变异操作
        Offspring(k).y = fun(Offspring(k).x);
    end
    newPop = [Parent;Offspring]; % 新的种群
    % ~是不输出此参数,sort返回的第一个参数是数值大小,第二个是索引,’ascend’为升序排列
    [~,so]= sort([newPop.y],'ascend'); % 从小到大对y值进行排列
    newPop = newPop(so); % 刷新种群排序
    Parent = newPop(1 : nPop);
    
    disp(['迭代次数:',num2str(It), ', 最小值为: ', num2str(Parent(1).y)])
end

3 . 选择函数

% 选择函数
function p = SelectPop(Parent)
    % 锦标赛选择法
    % 锦标赛方法选择策略每次从种群中取出一定数量个体,然后选择其中最好的一个进入子代种群
    % 重复该操作,直到新的种群规模达到原来的种群规模
    n = numel(Parent); % 父代种群的个数
    index = randperm(n); % 随机打乱序列,选中前两个
    p1 = Parent(index(1));% 第一个
    p2 = Parent(index(2));% 第二个
    if p1.y < p2.y
        p = p1;
    else
        p = p2;
    end
end

4.交叉函数(单点交叉)

% 交叉函数
function [y1,y2] = crossPop(x1, x2)
    %单点交叉
    
    n = numel(x1);% 算出x1的长度
    s = randi([1, n-1]);% 随机选出一个交叉点,-1操作是因为如果选择最后一位,就相当于没有交叉
    
    y1 = [x1(1:s) x2(s+1:end)];% 重组
    y2 = [x2(1:s) x1(s+1:end)];% 重组
end

5.变异函数(单点变异)

% 变异函数
function p = mutatePop(x,mu)
   % 单点变异
   if rand <= mu % 单独一个rand是得到一个在(0,1)之间均匀分布的伪随机数
       n = numel(x);
       s = randi([1,n]);
       if x(s) == 0
           x(s) = 1;
       elseif x(s) ==1
           x(s) = 0;
       end
   end
   p = x;
   
end

6.适应度函数

function y = fun(x)
    % 计算输入x的和,x是【0,1】区间的正整数
    y = sum(x);    
end

% randi()函数
% randi(limin,imax].[m n])
% 产生m*n矩阵,这个矩阵的元素都是处于imin和imax之间的整数
;