优化算法
启发式算法——遗传算法Genetic Algorithm GA
算法概述
从代表问题可能潜在的解集的一个种群(population)开始,一个种群则经过基因(gene)编码的一定数目的个体(individual)。第一步需要实现从表现型到基因型的映射即编码工作。初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小,选择个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉和变异,产生出代表新的解集的种群。
后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
遗传算法有三个基本操作:选择(Selection)、交叉(Crossover)和变异(Mutation)。
• (1)选择(复制)
选择的目的是为了从当前群体中选出优良的个体,使它们有机会作为父代为下一代繁衍子孙。根据各个个体的适应度值,按照一定的规则或方法从第t代群体P(t)中选择出一些优良的个体遗传到下一代群体P(t+1)中。
选择的依据是适应性强的个体为下一代贡献一个或多个后代的概率大。
• (2)交叉
通过交叉操作可以得到新一代个体,新个体组合了父辈个体的特性。将群体P(t)内的各个个体随机搭配成对,对每一个个体,以交叉概率交换它们之间的部分染色体。
• (3)变异
对群体P(t)中的每一个个体,以变异概率改变某一个或多个基因座上的基因值为其他的等位基因。
同生物界中一样,变异发生的概率很低,变异为新个体的产生提供了机会。
遗传算法的基本步骤
1)个体编码
遗传算法的运算对象是表示个体的符号串,所以必须把变量x1\x3编码为一种符号串。
例如用无符号二进制整数表示。x1、x2为0-7之间的整数,所以分别用3位无符号二进制整数来表示。将它们连接在一起组成6位无符号二进制整数形成了个体的基因型,表示一个可行解。
例如基因型X=101110所对应的表现型是x=[5,6]
个体的表现型和基因型X可通过编码和解码程序相互转换。
2)初始群体的产生
遗传算法是对群体进行的进化操作,需要给其准备一些表示初始搜索点的初始群体数据。随机产生N个初始串结构数据,每个串结构数据称为一个个体,N个个体构成了一个群体。GA以这N个串结构数据作为初始点开始进化。
例如:群体规模大小为4,群体由4个个体组成,每个个体可通过随机方法产生。
011101、101011、011100、111001
3)个体适应度计算
遗传算法中以个体适应度大小来评定各个个体的优劣程度,从而决定其遗传机会的大小。不同的问题,适应性函数的定义方式也不同。
4)选择/复制运算
把当前群体中适应度较高的个体按照某种规则或模型遗传到下一代群体中。一般要求适应度高的个体将有更多的机会遗传到下一代。
使用比例选择算子。
遗传算法通过选择过程体现这一思想,进行选择的原则是适应性强的个体为下一代贡献一个或多个后代的概率大。选择体现了达尔文的适者生存原则。
5)交叉运算
交叉操作是遗传算法中产生新个体的主要操作过程(最主要的遗传操作)。以某一概率相互交换某两个个体之间的部分染色体。
使用单点交叉算子。
通过交叉操作可以得到新一代个体,新个体组合了其父辈个体的特性。交叉体现了信息交换的思想。
具体操作过程:
- 先对群体进行随机配对
- 其次随机设置交叉点位置
- 最后在相互交换配对染色体之间的部分基因
个体编号 | 选择结果 | 配对情况 | 交叉点位置 | 交叉结果 |
---|---|---|---|---|
1 | 01|1101 | 1-2 | 1-2:2 | 011001 |
2 | 11|1001 | 1-2 | 1-2:2 | 111101 |
3 | 1010|11 | 3-4 | 3-4:4 | 101001 |
4 | 1110|01 | 3-4 | 3-4:4 | 111011 |
6)变异运算
变异运算是对个体的某一个活某一些基因座上的基因值按某一较小的概率进行改变,也是产生新个体的一种操作方法。
使用基本位变异算子。
首先在群体中随机选择一个个体,对于选中的个体以一定的概率随机地改变串结构数据中某个串的值。同生物界一样, GA中变异发生的概率很低,通常取值很小。
具体操作过程:
- 首先确定各个个体的基因变异位置,数字表示变异点设置在该基因座处
- 然后按照某一概率将变异点的原有基因值取反
个体编号 | 交叉结果 | 变异点 | 变异结果 | 子代群体p(1) |
---|---|---|---|---|
1 | 011001 | 4 | 011101 | 011101 |
2 | 111101 | 5 | 111111 | 111111 |
3 | 101001 | 2 | 111001 | 111001 |
4 | 111011 | 6 | 111010 | 111010 |
基本遗传算法的描述
基本遗传算法的运行参数
- 群体大小M:一般取为20-100
- 交叉概率pc:一般取为0.4-0.99
- 变异概率pm:一般取为0.0001-0.1
- 终止进化代数T:一般取为100-200
形式化定义
GA=(M,F,s,c,m,pc,pm)
M-群体大小
F-个体适应度评价函数
s-选择操作算子
c-交叉操作算子
m-变异操作算子
pc-交叉概率
pm-变异概率
基本遗传算法的实现
编码与解码
- 编码
假设某一参数的取值范围是[umin,umax],用长度为l的二进制编码符号串表示该参数,共能产生2^l种不同编码,公式为
精度δ=
00000000…00000000=0<——umin
00000000…00000001=1<——umin+ δ
…
11111111…11111111=2^l-1<——umax - 解码
假设某一个个体的编码是x:
则对应解码公式是
个体适应度
要求所有个体适应度必须为正数或零
当优化目标是求函数最大值,并且目标函数总是取正值时,可以直接设定个体适应度F(X)等于相应的目标函数值f(X)
当优化目标是求函数最小值,增加一个负号转化为求目标函数最大值
min F(X)= max(-f(X))
将目标函数变换为个体适应度F(X)方法——
方法一:对于求目标函数最大值的优化问题
F(X)=f(X)+Cmin if f(X)+Cmin >= 0
F(X)=0 if f(X)+Cmin < 0
Cmin一个适当地相对比较小的数
- 预先指定的一个较小的数
- 进化到当前为止最小目标函数值
- 当前代或最近几代群体中最小目标函数值
方法二:对于求目标函数最小值的优化问题
F(X)=Cmax-f(X) if f(X)< Cmax
F(X)=0 if f(X)> Cmax
Cmax一个适当地相对比较大的数
- 预先指定的一个较大的数
- 进化到当前为止最大目标函数值
- 当前代或最近几代群体中最大目标函数值
比例选择算子
执行比例选择的手段——轮盘选择
轮盘法的基本精神,个体被选中的概率取决于个体的相对适应度【适应度大的个体,刻度长,对应的被选中可能性大】
pi=fi/∑fi
pi-个体被选中的概率
fi-个体的适应度
∑fi-群体的累加适应度
单点交叉算子
- 对个体进行两两随机配对
若群体大小为M,则共有(M/2)对相互配对的个体组 - 每一对相互配对的个体,随机设置某一基因座之后的位置交叉点
若染色体的长度为l,则共有(l-1)个可能的交叉点位置 - 对每一对相互配对的个体,依设定的交叉概率pc在其交叉点处相互交换两个个体的部分染色体,从而产生出两个新的个体。
交叉概率
pc=Mc/M
M-群体中个体的数目
M-群体中被交换个体的数目
基本位变异算子
- 对个体每一个基因座,依变异概率pm指定其为变异点
- 对每一个指定的变异点,对其基因组取反运算或用其他等位基因值来代替,从而产生出一个新的个体
变异概率
pm=B/M*l
B-每代中变异的基因数目
M-每代中群体拥有个体的数目
l-个体重基因传的长度
收敛性的影响
- 种群规模对收敛性的影响
- 选择操作对收敛性的影响
- 交叉概率对收敛性的影响
- 变异概率对收敛性的影响
遗传算法工具箱
• MATLAB内嵌遗传算法工具箱: gadst
• Sheffield大学遗传算法工具箱: gatbx
• 北卡罗来纳大学遗传算法工具箱: gaot
matlab函数
•optimtool
•initializega
pop = initializega(populationSize,variableBounds,evalFN,evalOps,options)
参数 | 意义 |
---|---|
pop | 随机生成的初始种群 |
populationSize | 种群大小 |
variableBounds | 变量边界的矩阵 |
evalFN | 适应度函数名称 |
evalOps | 适应度函数的参数 |
options | 精度及编码形式,1为浮点编码,0为二进制编码 |
• ga
[x,endPop,bPop,traceInfo] =ga(bounds,evalFN,evalOps,startPop,opts,termFN,termOps,selectFN,
selectOps,xOverFNs,xOverOps,mutFNs,mutOps)
参数 | 意义 |
---|---|
bounds | 变量上下界的矩阵 |
evalFN | 适应度函数名称 |
evalOps | 适应度函数的参数 |
startPop | 初始种群 |
opts | 精度、编码形式及显示方式,1为浮点编码,0为二进制编码,默认为[1e-6 1 0] |
termFN | 终止函数的名称 |
termOps | 终止函数的参数 |
selectFN | 选择函数的名称 |
selectOps | 选择函数的参数 |
xOverFNs | 交叉函数的名称 |
xOverOps | 交叉函数的参数 |
mutFNs | 变异函数的名称 |
mutOps | 变异函数的参数 |
x | 优化计算得到的最优个体 |
endPop | 优化终止时的最终种群 |
bPop | 最优种群的进化轨迹 |
traceInfo | 每代的最优适应度函数值和平均适应度函数值矩阵 |
案例分析
一元函数优化
%% 适应度函数此处即是目标函数(因为是求最大值)
function [sol, fitnessVal] = fitness(sol, options)
x = sol(1);
fitnessVal = x + 10*sin(5*x)+7*cos(4*x);
end
%% I. 清空环境变量
clear all
clc
%% II. 绘制函数曲线
x = 0:0.01:9;
y = x + 10*sin(5*x)+7*cos(4*x);
figure
plot(x, y)
xlabel('自变量')
ylabel('因变量')
title('y = x + 10*sin(5*x) + 7*cos(4*x)')
%% III. 初始化种群
initPop = initializega(50,[0 9],'fitness');
%% IV. 遗传算法优化
[x endPop bpop trace] = ga([0 9],'fitness',[],initPop,[1e-6 1 1],'maxGenTerm',25,... 'normGeomSelect',0.08,'arithXover',2,'nonUnifMutation',[2 25 3]);
%% V. 输出最优解并绘制最优点
x
hold on
plot (endPop(:,1),endPop(:,2),'ro')
%% VI. 绘制迭代进化曲线
figure(2)
plot(trace(:,1),trace(:,3),'b:')
hold on
plot(trace(:,1),trace(:,2),'r-')
xlabel('Generation'); ylabel('Fittness');
legend('Mean Fitness', 'Best Fitness')
BP神经网络初始权值和阈值优化
%% 适应度函数
function[sol,val]=gabpEval(sol,options)
global S
for i=1:S
x(i)=sol(i);
end;
[W1,B1,W2,B2,val]=gadecod(x);
%%解码函数
function[W1,B1,W2,B2,val]=gadecod(x)
global p
global t
global R
global S2
global S1
% 前R*S1个编码为W1
for i=1:S1
for k=1:R
W1(i,k)=x(R*(i-1)+k);
end
end
% 接着的S1*S2个编码(即第R*S1个后的编码)为W2
for i=1:S2
for k=1:S1
W2(i,k)=x(S1*(i-1)+k+R*S1);
end
end
% 接着的S1个编码(即第R*SI+SI*S2个后的编码)为B1
for i=1:S1
B1(i,1)=x((R*S1+S1*S2)+i);
end
%接着的S2个编码(即第R*SI+SI*S2+S1个后的编码)为B2
for i=1:S2
B2(i,1)=x((R*S1+S1*S2+S1)+i);
end
% 计算S1与S2层的输出
A1=tansig(W1*p,B1);
A2=purelin(W2*A1,B2);
% 计算误差平方和
SE=sumsqr(t-A2);
% 遗传算法的适应值
val=1/SE;
%% I. 清除环境变量
clear all
clc
%% II. 声明全局变量
global p % 训练集输入数据
global t % 训练集输出数据
global R % 输入神经元个数
global S2 % 输出神经元个数
global S1 % 隐层神经元个数
global S % 编码长度
S1 = 10;
%% III. 导入数据
%%
% 1. 训练数据
p = [0.01 0.01 0.00 0.90 0.05 0.00;
0.00 0.00 0.00 0.40 0.50 0.00;
0.80 0.00 0.10 0.00 0.00 0.00;
0.00 0.20 0.10 0.00 0.00 0.10]';
t = [1.00 0.00 0.00 0.00;
0.00 1.00 0.00 0.00;
0.00 0.00 1.00 0.00;
0.00 0.00 0.00 1.00]';
%%
% 2. 测试数据
P_test = [0.05 0 0.9 0.12 0.02 0.02;
0 0 0.9 0.05 0.05 0.05;
0.01 0.02 0.45 0.22 0.04 0.06;
0 0 0.4 0.5 0.1 0;
0 0.1 0 0 0 0]';
%% IV. BP神经网络
%%
% 1. 网络创建
net = newff(minmax(p),[S1,4],{'tansig','purelin'},'trainlm');
%%
% 2. 设置训练参数
net.trainParam.show = 10;
net.trainParam.epochs = 2000;
net.trainParam.goal = 1.0e-3;
net.trainParam.lr = 0.1;
%%
% 3. 网络训练
[net,tr] = train(net,p,t);
%%
% 4. 仿真测试
s_bp = sim(net,P_test) % BP神经网络的仿真结果
%% V. GA-BP神经网络
R = size(p,1);
S2 = size(t,1);
S = R*S1 + S1*S2 + S1 + S2;
aa = ones(S,1)*[-1,1];
%% VI. 遗传算法优化
%%
% 1. 初始化种群
popu = 50; % 种群规模
initPpp = initializega(popu,aa,'gabpEval',[],[1e-6 1]); % 初始化种群
%%
% 2. 迭代优化
gen = 100; % 遗传代数
% 调用GAOT工具箱,其中目标函数定义为gabpEval
[x,endPop,bPop,trace] = ga(aa,'gabpEval',[],initPpp,[1e-6 1 1],'maxGenTerm',gen,...
'normGeomSelect',[0.09],['arithXover'],[2],'nonUnifMutation',[2 gen 3]);
%%
% 3. 绘均方误差变化曲线
figure(1)
plot(trace(:,1),1./trace(:,3),'r-');
hold on
plot(trace(:,1),1./trace(:,2),'b-');
xlabel('Generation');
ylabel('Sum-Squared Error');
%%
% 4. 绘制适应度函数变化
figure(2)
plot(trace(:,1),trace(:,3),'r-');
hold on
plot(trace(:,1),trace(:,2),'b-');
xlabel('Generation');
ylabel('Fittness');
%% VII. 解码最优解并赋值
%%
% 1. 解码最优解
[W1,B1,W2,B2,val] = gadecod(x);
%%
% 2. 赋值给神经网络
net.IW{1,1} = W1;
net.LW{2,1} = W2;
net.b{1} = B1;
net.b{2} = B2;
%% VIII. 利用新的权值和阈值进行训练
net = train(net,p,t);
%% IX. 仿真测试
s_ga = sim(net,P_test) %遗传优化后的仿真结果
遗传算法的应用
- 函数优化
- 组合优化
- 生产调度问题
- 自动控制
- 机器人学
- 图像处理
- 人工生命
- 遗传编程
- 机器学习