Navigator
Genetic Algorithm
GA算法的主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具备隐并行性和较好的全局寻优能力。GA在进行全局搜索和优化搜索时不依赖梯度信息,只需要搜索方向的目标函数和相应的适应度函数,所以GA提供了一种求解复杂系统问题的通用框架。
GA算法的特点
- GA从问题的串集开始搜索,而不是从单个解开始,传统优化算法从单个值开始求最优解,容易陷入局部最优解。GA从串集开始搜索,覆盖面大,有利于全局寻优。
- GA同时对搜索空间多个解进行评估,算法本身支持并行化
- GA算法仅用适应度函数值进行个体评估,并在此基础上进行遗传操作,适应度函数不仅不受连续可微的约束,而且其定义域可以任意设定
- GA采用概率变迁的规则指导搜索方向
- GA具有自组织,自适应和自学习性。GA利用进化过程中获得的信息自行组织搜索,适应度大的个体具有较高的生存概率
编码
GA不能直接处理问题空间的参数,必须将其转为遗传空间由基因按一定结构组成的染色体或者个体,这种转换操作就是编码,评估编码的策略采用以下3种规范:
- 完备性(
completeness
):问题空间中的所有点(候选解)都能作为GA空间中的染色体表现 - 健全性(
soundness
):GA空间中的染色体能对应所有问题空间中的候选解 - 非冗余性(
nonredundancy
):染色体和候选解一一对应
目前常用的编码方式有二进制编码,浮点数编码,字符编码和编程编码等。
初始群体
随机产生 N N N个初始串结构数据,其中每个串数据为一个个体
, N N N个个体构成一个群体,参数 N N N的选择需要根据问题的规模而确定。
杂交
杂交是GA中的主要遗传操作,由交换概率挑选的每两个父代通过将相异的部分信息进行交换,从而产生新的个体。
适应度值评估检测
适应度是用来度量种群中个体优劣的指标,适应度是特征组合的判据的值,该判据的选取是遗传算法的关键。GA在搜索进化的过程中一般不需要外部信息,仅用评估函数来评估个体或者解的优劣,并作为之后遗传的依据。在GA中,适应度函数需要进行比较排序并在此基础上计算选择概率。
适应度函数的设计需要满足以下条件:
- 单值、连续、非负、最大化
- 合理、一致性
- 计算量小
- 通用性强
选择
选择的目的是为了从交换后的群体中选出优良的个体,使得适应性强的个体为下一代贡献的概率变大。
变异
变异首先会在群体中随机选择一定数量的个体,对于选中的个体以一定的概率随机改变串结构数据中的某个基因值。
中止
中止的条件一般有3种:
- 给定一个最大的遗传代数,算法迭代到最大数时停止
- 给定问题一个下界计算方法,当进化中达到要求的偏差 ε \varepsilon ε时,算法中止
- 当发现算法进化到无法改进解的性能时停止算法
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+6x3⎩⎪⎪⎪⎨⎪⎪⎪⎧x1−x2+x3≤203x1+2x2+4x3≤423x1+2x2≤300≤x1,0≤x2,0≤x3
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
算法对比: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');
对比GA和PSO可以发现,GA极值寻优计算具有较好的鲁棒性,收敛较快,PSO存在早熟现象
Reference
MATLAB优化算法案例分析与应用 余胜威