【GA】GA算法寻优

Genetic Algorithm

GA算法的主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具备隐并行性和较好的全局寻优能力。GA在进行全局搜索和优化搜索时不依赖梯度信息,只需要搜索方向的目标函数和相应的适应度函数,所以GA提供了一种求解复杂系统问题的通用框架。

GA算法的特点

  • GA从问题的串集开始搜索,而不是从单个解开始,传统优化算法从单个值开始求最优解,容易陷入局部最优解。GA从串集开始搜索,覆盖面大,有利于全局寻优。
  • GA同时对搜索空间多个解进行评估,算法本身支持并行化
  • GA算法仅用适应度函数值进行个体评估,并在此基础上进行遗传操作,适应度函数不仅不受连续可微的约束,而且其定义域可以任意设定
  • GA采用概率变迁的规则指导搜索方向
  • GA具有自组织,自适应和自学习性。GA利用进化过程中获得的信息自行组织搜索,适应度大的个体具有较高的生存概率

编码

GA不能直接处理问题空间的参数,必须将其转为遗传空间由基因按一定结构组成的染色体或者个体,这种转换操作就是编码,评估编码的策略采用以下3种规范:

  1. 完备性(completeness):问题空间中的所有点(候选解)都能作为GA空间中的染色体表现
  2. 健全性(soundness):GA空间中的染色体能对应所有问题空间中的候选解
  3. 非冗余性(nonredundancy):染色体和候选解一一对应

目前常用的编码方式有二进制编码,浮点数编码,字符编码和编程编码等。

初始群体

随机产生 N N N个初始串结构数据,其中每个串数据为一个个体 N N N个个体构成一个群体,参数 N N N的选择需要根据问题的规模而确定。

杂交

杂交是GA中的主要遗传操作,由交换概率挑选的每两个父代通过将相异的部分信息进行交换,从而产生新的个体。

适应度值评估检测

适应度是用来度量种群中个体优劣的指标,适应度是特征组合的判据的值,该判据的选取是遗传算法的关键。GA在搜索进化的过程中一般不需要外部信息,仅用评估函数来评估个体或者解的优劣,并作为之后遗传的依据。在GA中,适应度函数需要进行比较排序并在此基础上计算选择概率。
适应度函数的设计需要满足以下条件:

  1. 单值、连续、非负、最大化
  2. 合理、一致性
  3. 计算量小
  4. 通用性强

选择

选择的目的是为了从交换后的群体中选出优良的个体,使得适应性强的个体为下一代贡献的概率变大。

变异

变异首先会在群体中随机选择一定数量的个体,对于选中的个体以一定的概率随机改变串结构数据中的某个基因值。

中止

中止的条件一般有3种:

  1. 给定一个最大的遗传代数,算法迭代到最大数时停止
  2. 给定问题一个下界计算方法,当进化中达到要求的偏差 ε \varepsilon ε时,算法中止
  3. 当发现算法进化到无法改进解的性能时停止算法

GA Demo

求解如下线性规划
min ⁡ 5 x 1 + 4 x 2 + 6 x 3 s . t . { x 1 − x 2 + x 3 ≤ 20 3 x 1 + 2 x 2 + 4 x 3 ≤ 42 3 x 1 + 2 x 2 ≤ 30 0 ≤ x 1 , 0 ≤ x 2 , 0 ≤ x 3 \begin{aligned} \min& 5x_1+4x_2+6x_3\\ s.t.& \begin{cases} x_1-x_2+x_3\leq 20\\ 3x_1+2x_2+4x_3\leq 42\\ 3x_1+2x_2\leq 30\\ 0\leq x_1, 0\leq x_2, 0\leq x_3 \end{cases} \end{aligned} mins.t.5x1+4x2+6x3x1x2+x3203x1+2x2+4x3423x1+2x2300x1,0x2,0x3

objective function

function y = func2(x)
    y=5*x(1)+4*x(2)+6*x(3);
end

GA main function

clc;
close all;
clear all;

%% initialize parameters
popsize = 100;
lenchrom = 3;
pc = 0.7; % probability of crossover
pm = 0.3; % probability of mutation
maxgen = 100; % # of generations

% population
popmax = 50;
popmin = 0;
bound = [popmin popmax; popmin popmax; popmin popmax];

% initialization particles
for i=1:popsize
    % generate a population randomly 
    GApop(i, :) = Code(lenchrom, bound);
    % calculate the fitness
    fitness(i) = func(GApop(i, :));
end

% find the best chromesome
[bestfitness, bestindex] = min(fitness);
zbest = GApop(bestindex, :); % the global best
gbest = GApop; % the individual best
fitnessgbest = fitness;
fitnesszbest = bestfitness;

% find the optimal value iteratelly
for i=1:maxgen
    i
    % update population: GA
    GApop = Select(GApop, fitness, popsize);
    % cross
    GApop = Cross(pc, lenchrom, GApop, popsize, bound);
    % mutation
    GApop = Mutation(pm, lenchrom, GApop, popsize, [i maxgen], bound);
    pop = GApop;
    for j = 1:popsize
        % fitness
        if pop(j, 1)-pop(j, 2)+pop(j, 3)<=20
            if 3*pop(j, 1)+2*pop(j, 2)+4*pop(j, 3)<=42
                if 3*pop(j, 1)+2*pop(j, 2)<=30
                    fitness(j)=func(pop(j, :));
                end
            end
        end
        
        % update the optimal value of individual
        if fitness(j) < fitnessgbest(j)
            gbest(j, :) = pop(j, :);
            fitnessgbest(j) = fitness(j);
        end
        
        % update the optimal value of population
        if fitness(j) < fitnesszbest
            zbest = pop(j, :);
            fitnesszbest = fitness(j);
        end
    end
    yy(i) = fitnesszbest;
end

%% results
disp '********************best particle number********************'
zbest
plot(yy, 'linewidth', 2);
title(['Fitness curve ', 'Generation of Stopping: ' num2str(maxgen)]);
xlabel('Generation of evolution');
ylabel('Fitness');
grid on;

编码算子(Code)

function ret = Code(lenchrom, bound)
    flag = 0;
    while flag == 0
        pick = rand(1, lenchrom);
        ret = bound(:, 1)'+(bound(:, 2)-bound(:, 1))'.*pick;
        flag = test(lenchrom, bound, ret); % verify the feasibility of the chromesome
    end
end

验证函数(test)

function flag = test(lenchrom, bound, code)
flag = 1;
[n, ~] = size(code);
for i=1:n
    if code(i)<bound(i, 1) || code(i)>bound(i, 2)
        flag = 0;
    end
end

选择算子(Select)

function ret = Select(individuals, fitness, sizepop)
    fitness = 1./fitness;
    sumfitness = sum(fitness);
    sumf = fitness./sumfitness;
    index = [];
    for i=1:sizepop % Turn sizepop roulette
        pick = rand;
        while pick == 0
            pick = rand;
        end
        for j=1:sizepop
            pick = pick-sumf(j);
            if pick<0
                index = [index j];
                break;
            end
        end
    end
    individuals = individuals(index, :);
    fitness = fitness(index);
    ret = individuals;
end

变异算子(Mutation)

function ret = Mutation(pmutation, lenchrom, chrom, sizepop, pop, bound)
    for i=1:sizepop
        % select a chromosome for mutation randomly
        pick = rand;
        while pick == 0
            pick = rand;
        end
        index = ceil(pick*sizepop);
        % the probability of mutation decide wheter to mutate in this round
        pick = rand;
        if pick > pmutation
            continue;
        end
        flag = 0;
        while flag == 0
            % position of mutation
            pick = rand;
            while pick == 0
                pick = rand;
            end
            pos = ceil(pick*sum(lenchrom)); % select the pos variable to mutate
            v = chrom(i, pos);
            v1 = v-bound(pos, 1);
            v2 = bound(pos, 2)-v;
            pick = rand;
            if pick > 0.5
                delta = v2*(1-pick^((1-pop(1)/pop(2))^2));
                chrom(i, pos) = v+delta;
            else
                delta = v1*(1-pick^((1-pop(1)/pop(2))^2));
                chrom(i, pos) = v-delta;
            end
            flag = test(lenchrom, bound, chrom(i, :)); % test the feasibility of chromosome
        end
    end
    ret = chrom;
end

交叉算子(Cross)

function ret = Cross(pcross, lenchrom, chrom, sizepop, bound)
    for i = 1:sizepop
        pick = rand(1, 2);
        while prod(pick) == 0
            pick = rand(1, 2);
        end
        index = ceil(pick.*sizepop);
        % the probability for crossing
        pick = rand;
        while pick == 0
            pick = rand;
        end
        
        if pick>pcross
            continue;
        end
        flag = 0;
        while flag == 0
            % select the position for crossing randomly
            pick = rand;
            while pick == 0
                pick = rand;
            end
            pos = ceil(pick.*sum(lenchrom));
            pick = rand;
            v1 = chrom(index(1), pos);
            v2 = chrom(index(2), pos);
            chrom(index(1), pos)=pick*v2+(1-pick)*v1;
            chrom(index(2), pos)=pick*v1+(1-pick)*v2;
            % test the feasibility of chromosome
            flag1 = test(lenchrom, bound, chrom(index(1), :));
            flag2 = test(lenchrom, bound, chrom(index(2), :));
            if flag1 * flag2 == 0
                flag = 0;
            else
                flag = 1;
            end
        end
    end
    ret = chrom;
end

ga fit

算法对比:PSO

clc;
clear all;
close all;

% initialize parameters
c1 = 1.49445;
c2 = 1.49445;

maxgen = 200; % numbers of generation
sizepop = 200;% size of population

% velocity of particle 
Vmax = 1;
Vmin = -1;

% population
popmax = 20;
popmin = 0;

% best particle number
par_num = 3;

% initialize
for i=1:sizepop
    % generate a population randomly
    pop(i, :) = 2.*abs(rands(1, par_num)); % population
    V(i, :) = 1.*rands(1, par_num); % velocity
    % fitness
    fitness(i) = func(pop(i, :));
end

% find the best fitness
[bestfitness, bestindex] = min(fitness);
zbest = pop(bestindex, :);
gbest = pop;
fitnessgbest = fitness;
fitnesszbest = bestfitness;

% find the optimal value iteratively
for i = 1:maxgen
    i
    for j = 1:sizepop
        % update velocity
        V(j, :) = V(j, :)+c1*rand*(gbest(j, :)-pop(j, :))+c2*rand*(zbest-pop(j, :));
        V(j, find(V(j, :)>Vmax))=Vmax;
        V(j, find(V(j, :)<Vmin))=Vmin;
        
        % update population
        pop(j, :)=pop(j, :)+0.5*V(j, :);
        pop(j, find(pop(j, :)>popmax)) = popmax;
        pop(j, find(pop(j, :)<popmin)) = popmin;
        
        % adaptive mutation
        if rand > 0.8
            k = ceil(par_num*rand);
            pop(j, k) = rand;
        end
        
        % fitness value
        if pop(j, 1)-pop(j, 2)+pop(j, 3)<=20
            if 3*pop(j, 1)+2*pop(j, 2)+4*pop(j, 3)<=42
                if 3*pop(j, 1)+2*pop(j, 2)<=30
                    fitness(j) = func(pop(j, :));
                end
            end
        end
        
        % update the individual optimal value
        if fitness(j) < fitnessgbest(j)
            gbest(j, :)=pop(j, :);
            fitnessgbest(j) = fitness(j);
        end
        
        % update the population optimal value
        if fitness(j)<fitnesszbest
            zbest = pop(j, :);
            fitnesszbest = fitness(j);
        end
    end
    yy(i) = fitnesszbest;
end

%%
disp '************best particle number*************'
zbest

plot(yy);
title(['Fitness Curve ' 'Generation of stopping: ' num2str(maxgen)]);
xlabel('Generation of evolution');
ylabel('Fitness');

pso fit对比GA和PSO可以发现,GA极值寻优计算具有较好的鲁棒性,收敛较快,PSO存在早熟现象

Reference

MATLAB优化算法案例分析与应用 余胜威

猜你喜欢

转载自blog.csdn.net/qq_18822147/article/details/116401503
GA