首先,确定一下学习路线和学习资料(按照这个路线,入门非常容易,主要是人家文章写得好!):
思路:
1、编码与解码:分别使用十位二进制数表示x1,x2,那么种群中的每个个体就是20位二进制数。(编码方式参见上边提到的课件)
二进制数转化为十进制数算法:
表现在这道题目就是:Umin = -2.048,Umax = 2.048 ,λ = 10,bi是十位二进制中的每一个值(仅有0 、1);
所以 x 1 = U m i n + ( ∑ i = λ 1 b i ∗ 2 i − 1 ) U m a x − U m i n 2 λ − 1 x_{1}=Umin + (\sum_{i=\lambda }^{1}b_{i}\ast 2^{i-1})\frac{Umax-Umin}{2^{\lambda } - 1} x1=Umin+(i=λ∑1bi∗2i−1)2λ−1Umax−Umin
即:
x 1 = − 2.048 + ( ∑ i = 10 1 b i ∗ 2 i − 1 ) 4.096 2 10 − 1 x_{1}=-2.048 + (\sum_{i=10 }^{1}b_{i}\ast 2^{i-1})\frac{4.096}{2^{10 } - 1} x1=−2.048+(i=10∑1bi∗2i−1)210−14.096
x2同理。
2、适应度函数: f(x1, x2)是恒大于0的数,所以可以直接用作适应度函数。
3、比例选择、交换、变异算子:选择复制、交换,变异均使用上面matlab实验的解法。
matlab代码如下:
main.m
function main()
clear;
clc;
%种群大小
popsize = 90;
%二进制编码长度
chromelength = 20;
%交叉概率
pc = 0.7;
%变异概率
pm = 0.01;
%初始种群 %pop = population 种群
pop = initpop(popsize, chromelength);
%迭代100次
for i = 1:100
%计算适应度值?
objvalue = cal_objvalue(pop);
fitvalue = objvalue;
%选择复制
newpop = selection(pop, fitvalue);
%交换
newpop = crossover(newpop, pc);
%变异
newpop = mutation(newpop, pm);
%更新种群
pop = newpop;
%寻找最优解并打印在command窗口
[bestindividual, bestfit] = best(pop, fitvalue);
[x1b, x2b] = binary2decimal(bestindividual);
fprintf('the best x1 is -->>%5.2f\n', x1b);
fprintf('the best x2 is -->>%5.2f\n', x2b);
fprintf('the best y is -->>%5.2f\n', bestfit);
%更新后的种群
[x1, x2] = binary2decimal(newpop);
y = cal_objvalue(newpop);
%每迭代10次就输出一次图像,观察效果
if mod(i, 10) == 0
figure;
x3 = -2.048:0.01:2.048;
x4 = -2.048:0.01:2.048;
[x5, x6] = meshgrid(x3, x4);
y1 = (1 - x5).^2 + 100*(x6 - x5.^2).^2;
mesh(x5, x6, y1);
hold on;
plot3(x1, x2, y, '*');
title(['iteration is' num2str(i)]);
end
end
initpop.m(初始化种群函数)
%初始化种群
function pop = initpop(popsize, chromelength)
%随机产生90*20的0 1序列作为初始化种群
pop = round(rand(popsize, chromelength));
binary2decimal.m(二进制转换为十进制函数)
%二进制转化为十进制
function [pop3 pop4] = binary2decimal(pop)
[px, py] = size(pop);
%计算x1的数值矩阵
for i = 1:py - 10
pop1(:,i) = 2.^(py - 10 - i)*pop(:,i);
end
%计算x2的数值矩阵
for i = 11:py
pop2(:,i - 10) = 2.^(py - i)*pop(:,i);
end
%x1求和后的列向量
temp1 = sum(pop1, 2);
%x2求和后的列向量
temp2 = sum(pop2, 2);
%x1转换为十进制
pop3 = -2.048 + 4.096/1023*temp1;
%x2转化为十进制
pop4 = -2.048 + 4.096/1023*temp2;
cal_value.m(计算适应度函数)
%计算适应度函数(也就是香蕉函数值)
function objvalue = cal_objvalue(pop)
[x1, x2] = binary2decimal(pop);
objvalue = (1 - x1).^2 + 100*(x2 - x1.^2).^2;
selection.m(选择复制函数)
%选择和复制 轮盘赌法
function [newpop] = selection(pop, fitvalue)
[px, py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
%概率求和排序
p_fitvalue = cumsum(p_fitvalue);
%产生随机概率并排序
ms = sort(rand(px, 1));
fitin = 1;
newin = 1;
while newin <= px
if(ms(newin) < p_fitvalue(fitin))
newpop(newin,:) = pop(fitin,:);
newin = newin + 1;
else
fitin = fitin + 1;
end
end
crossover.m(交换函数)
%交换
function [newpop] = crossover(pop, pc)
[px, py] = size(pop);
newpop = ones(size(pop));
%理论是随机交换(交换哪个,和谁交换,交换哪一部分都是随机的),这里采用i和i+1的随机部分交换,尽可能达到随机
for i = 1:2:px - 1
if(rand < pc)
cpoint = round(rand*py);
newpop(i,:) = [pop(i,1:cpoint), pop(i+1, cpoint + 1:py)];
newpop(i+1, :) = [pop(i+1,1:cpoint), pop(i, cpoint+1:py)];
else
newpop(i, :) = pop(i,:);
newpop(i+1,:) = pop(i+1,:);
end
end
mutation.m(变异函数)
%变异
function [newpop] = mutation(pop, pm)
[px, py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
if(rand < pm)
mpoint = round(rand*py);
if mpoint <= 0
mpoint = 1;
end
newpop(i,:) = pop(i,:);
if newpop(i, mpoint) == 0
newpop(i, mpoint) =1;
else newpop(i, mpoint) == 1
newpop(i, mpoint) = 0;
end
else
newpop(i,:) = pop(i,:);
end
end
best.m(选择最优个体函数)
%选择最优个体
function [bestindividual bestfit] = best(pop, fitvalue)
[px, py] = size(pop);
bestfit = fitvalue(1);
bestindividual = pop(1,:);
for i = 2:px
if fitvalue(i) > bestfit
bestfit = fitvalue(i);
bestindividual = pop(i, :);
end
end
实验结果:
迭代100次之后的图像:
数据:
the best x1 is -->>-2.04
the best x2 is -->>-2.03
the best y is -->>3825.04
已经非常接近最大值的真实值(x1 = -2.048,x2 = -2.048)。
ps我是挑选的比较好的实验结果贴上来的,事实证明,这样计算也还是经常跑到另外一个极大值那边(x1 = 2.048 x2 = -2.048)。参数可以调节(种群数、交换概率、变异概率等),交换和变异方式也可以选择其他的方式,我还会继续学习其他的交换变异方式,完善这道题目。
使用lingo软件求解最大值:
程序:
model:
max = (1 - x1)^2 + 100*(x2 - x1^2)^2;
x1 >=-2.048;
x1 <= 2.048;
x2 >= -2.048;
x2 <= 2.048;
end
结果:
Global optimal solution found.
Objective value: 1760.317
Objective bound: 1760.317
Infeasibilities: 0.000000
Extended solver steps: 0
Total solver iterations: 33
Model Class: NLP
Total variables: 2
Nonlinear variables: 2
Integer variables: 0
Total constraints: 5
Nonlinear constraints: 1
Total nonzeros: 6
Nonlinear nonzeros: 2
Variable Value Reduced Cost
X1 2.048000 0.000000
X2 0.000000 838.8608
Row Slack or Surplus Dual Price
1 1760.317 1.000000
2 4.096000 0.000000
3 0.000000 3438.070
4 2.048000 0.000000
5 2.048000 0.000000
计算的最大值仅仅是1760.317,明显是局部最大值。
结论: 使用遗传算法,找到了函数的全局最优解。
f(x1, x2) = x12 + x22;
x1∈{1, 2, 3, 4, 5};x2∈{1, 2, 3, 4, 5}
和第一道题目类似,这道题目更简单。
思路:
那么每个自变量以3位二进制编码000-111∈[0, 7].那么每个个体就是六位二进制数。
function main()
clear;
clc;
%种群大小
popsize = 90;
%二进制编码长度
chromelength = 6;
%交叉概率
pc = 0.6;
%变异概率
pm = 0.001;
%初始种群 %pop = population 种群
pop = initpop(popsize, chromelength);
%迭代100次
for i = 1:100
%计算适应度值?
objvalue = cal_objvalue(pop);
fitvalue = objvalue;
%选择复制
newpop = selection(pop, fitvalue);
%交换
newpop = crossover(newpop, pc);
%变异
newpop = mutation(newpop, pm);
%更新种群
pop = newpop;
%寻找最优解并打印在command窗口
[bestindividual, bestfit] = best(pop, fitvalue);
[x1b, x2b] = binary2decimal(bestindividual);
fprintf('the best x1 is -->>%5.2f\n', x1b);
fprintf('the best x2 is -->>%5.2f\n', x2b);
fprintf('the best y is -->>%5.2f\n', bestfit);
%更新后的种群
[x1, x2] = binary2decimal(newpop);
y = cal_objvalue(newpop);
if mod(i ,10) == 0
figure;
x3 = 0:0.01:7;
x4 = 0:0.01:7;
[x5, x6] = meshgrid(x3, x4);
y1 = x5.^2 + x6.^2;
mesh(x5, x6, y1);
hold on;
plot3(x1, x2, y, '*');
title(['iteration is ' num2str(i)]);
end
end
initpop.m
%初始化种群
function pop = initpop(popsize, chromelength)
%随机产生90*20的0 1序列作为初始化种群
pop = round(rand(popsize, chromelength));
cal_value.m
%计算适应度函数
function objvalue = cal_objvalue(pop)
[x1, x2] = binary2decimal(pop);
objvalue = x1.^2 + x2.^2;
binary2decimal.m
%二进制转化为十进制
function [pop3 pop4] = binary2decimal(pop)
[px, py] = size(pop);
%计算x1的数值矩阵
for i= 1:py - 3
pop1(:, i) = 2.^(py - 3 - i)*pop(:,i);
end
%计算x2的数值矩阵
for i = 4:py
pop2(:, i - 3) = 2.^(py - i)*pop(:, i);
end
%x1的十进制数值
pop3 = sum(pop1, 2);
%x2的十进制数值
pop4 = sum(pop2, 2);
selection.m
%选择和复制 轮盘赌法
function [newpop] = selection(pop, fitvalue)
[px, py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
%概率求和排序
p_fitvalue = cumsum(p_fitvalue);
%产生随机概率并排序
ms = sort(rand(px, 1));
fitin = 1;
newin = 1;
while newin <= px
if(ms(newin) < p_fitvalue(fitin))
newpop(newin,:) = pop(fitin,:);
newin = newin + 1;
else
fitin = fitin + 1;
end
end
crossover.m
%交换
function [newpop] = crossover(pop, pc)
[px, py] = size(pop);
newpop = ones(size(pop));
%理论是随机交换(交换哪个,和谁交换,交换哪一部分都是随机的),这里采用i和i+1的随机部分交换,尽可能达到随机
for i = 1:2:px - 1
if(rand < pc)
cpoint = round(rand*py);
newpop(i,:) = [pop(i,1:cpoint), pop(i+1, cpoint + 1:py)];
newpop(i+1, :) = [pop(i+1,1:cpoint), pop(i, cpoint+1:py)];
else
newpop(i, :) = pop(i,:);
newpop(i+1,:) = pop(i+1,:);
end
end
mutation.m
%变异
function [newpop] = mutation(pop, pm)
[px, py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
if(rand < pm)
mpoint = round(rand*py);
if mpoint <= 0
mpoint = 1;
end
newpop(i,:) = pop(i,:);
if newpop(i, mpoint) == 0
newpop(i, mpoint) =1;
else newpop(i, mpoint) == 1
newpop(i, mpoint) = 0;
end
else
newpop(i,:) = pop(i,:);
end
end
best.m
%选择最优个体
function [bestindividual bestfit] = best(pop, fitvalue)
[px, py] = size(pop);
bestfit = fitvalue(1);
bestindividual = pop(1,:);
for i = 2:px
if fitvalue(i) > bestfit
bestfit = fitvalue(i);
bestindividual = pop(i, :);
end
end
the best x1 is -->> 7.00
the best x2 is -->> 7.00
the best y is -->>98.00
迭代40次,效果就已经很好了。
当然,这道题目就是为了练习遗传算法,实际上可以使用lingo计算这种最优解。
使用lingo软件求解函数最大值:
程序:
model:
max = x1^2 + x2^2;
x1 > 0;
x1 <= 7;
x2 >0;
x2 <= 7;
@gin(x1);
@gin(x2);
end
结果:
Global optimal solution found.
Objective value: 98.00000
Objective bound: 98.00000
Infeasibilities: 0.000000
Extended solver steps: 0
Total solver iterations: 13
Model Class: PINLP
Total variables: 2
Nonlinear variables: 2
Integer variables: 2
Total constraints: 5
Nonlinear constraints: 1
Total nonzeros: 6
Nonlinear nonzeros: 2
Variable Value Reduced Cost
X1 7.000000 0.000000
X2 7.000000 0.000000
Row Slack or Surplus Dual Price
1 98.00000 1.000000
2 7.000000 0.000000
3 0.000000 14.00000
4 7.000000 0.000000
5 0.000000 14.00000
结论:两种方法找到的都是全局最优解。
function main()
clear;
clc;
%种群大小
popsize = 100;
%二进制编码长度?
chromelength = 20;
%交叉概率
pc = 0.6;
%变异概率
pm = 0.001;
%初始种群 %pop = population 种群
pop = initpop(popsize, chromelength);
%迭代100次?
for i = 1:100
%计算适应度
objvalue = cal_objvalue(pop);
fitvalue = objvalue;
%选择复制
newpop = selection(pop, fitvalue);
%交换
newpop = crossover(newpop, pc);
%变异
newpop = mutation(newpop, pm);
%更新种群
pop = newpop;
%最佳点
[bestindividual, bestfit] = best(pop, fitvalue);
[x1b, x2b] = binary2decimal(bestindividual);
fb = exp(x1b).*(4*x1b.^2 + 2*x2b.^2 + 4*x1b.*x2b + 2*x2b + 1);
%更新后的种群
[x1, x2] = binary2decimal(newpop);
y = cal_objvalue(newpop);
f = exp(x1).*(4*x1.^2 + 2*x2.^2 + 4*x1.*x2 + 2*x2 + 1);
%每迭代一次输出一次图像?
if mod(i, 10) == 0
figure;
x3 = -10:0.1:10;
x4 = -10:0.1:10;
[x5, x6] = meshgrid(x3, x4);
y1 = exp(x5).*(4*x5.^2 + 2*x6.^2 + 4*x5.*x6 + 2*x6 + 1);
mesh(x5, x6, y1);
hold on;
plot3(x1, x2, f, '*');
title([' iteration is ' num2str(i)]);
end
end
fprintf('the best x1 is --->>%5.2f\n', x1b);
fprintf('the best x2 is --->>%5.2f\n', x2b);
fprintf('the best f is --->>%5.2f\n', fb);
initpop.m
%初始化种群
function pop = initpop(popsize, chromelength)
%随机产生90*20的0 1序列作为初始化种群
pop = round(rand(popsize, chromelength));
binary2decimal.m
%二进制转化为十进制
function [pop3 pop4] = binary2decimal(pop)
[px, py] = size(pop);
%计算x1的数值矩阵
for i = 1:py - 10
pop1(:,i) = 2.^(py - 10 - i)*pop(:,i);
end
%计算x2的数值矩阵
for i = 11:py
pop2(:,i - 10) = 2.^(py - i)*pop(:,i);
end
%x1求和后的列向量
temp1 = sum(pop1, 2);
%x2求和后的列向量
temp2 = sum(pop2, 2);
%x1转换位十进制
pop3 = -10 + 20/1023*temp1;
%x2转换位十进制
pop4 = -10 + 20/1023*temp2;
cal_objvalue.m
%适应度函数
function objvalue = cal_value(pop)
[px, py] = size(pop);
[x1, x2] = binary2decimal(pop);
g1 = 1.5 + x1.*x2 - x1 - x2;
g2 = - x1.*x2;
%f值
f = exp(x1).*(4*x1.^2 + 2*x2.^2 + 4*x1.*x2 + 2*x2 + 1);
for i = 1:px
%满足约束
if g1(i)<=0 && g2(i) <= 10
%适应度函数
if f(i) < 100
objvalue(i) = 100 - f(i);
else
objvalue(i) = 0;
end
else
objvalue(i) = 1;
end
end
selection.m
%选择和复制 轮盘赌法
function [newpop] = selection(pop, fitvalue)
[px, py] = size(pop);
totalfit = sum(fitvalue);
p_fitvalue = fitvalue/totalfit;
%概率求和排序
p_fitvalue = cumsum(p_fitvalue);
%产生随机概率并排序
ms = sort(rand(px, 1));
fitin = 1;
newin = 1;
while newin <= px
if(ms(newin) < p_fitvalue(fitin))
newpop(newin,:) = pop(fitin,:);
newin = newin + 1;
else
fitin = fitin + 1;
end
end
crossover.m
%交换
function [newpop] = crossover(pop, pc)
[px, py] = size(pop);
newpop = ones(size(pop));
%理论是随机交换(交换哪个,和谁交换,交换哪一部分都是随机的),这里采用i和i+1的随机部分交换,尽可能达到随机
for i = 1:2:px - 1
if(rand < pc)
cpoint = round(rand*py);
newpop(i,:) = [pop(i,1:cpoint), pop(i+1, cpoint + 1:py)];
newpop(i+1, :) = [pop(i+1,1:cpoint), pop(i, cpoint+1:py)];
else
newpop(i, :) = pop(i,:);
newpop(i+1,:) = pop(i+1,:);
end
end
mutation.m
%变异
function [newpop] = mutation(pop, pm)
[px, py] = size(pop);
newpop = ones(size(pop));
for i = 1:px
if(rand < pm)
mpoint = round(rand*py);
if mpoint <= 0
mpoint = 1;
end
newpop(i,:) = pop(i,:);
if newpop(i, mpoint) == 0
newpop(i, mpoint) =1;
else newpop(i, mpoint) == 1
newpop(i, mpoint) = 0;
end
else
newpop(i,:) = pop(i,:);
end
end
best.m
%选择最优个体
function [bestindividual bestfit] = best(pop, fitvalue)
[px, py] = size(pop);
bestfit = fitvalue(1);
bestindividual = pop(1,:);
for i = 2:px
if fitvalue(i) > bestfit
bestfit = fitvalue(i);
bestindividual = pop(i, :);
end
end
the best x1 is --->>-7.48
the best x2 is --->> 1.30
the best f is --->> 0.11
使用lingo求解函数最小值:
程序:
model:
!目标函数;
min = @exp(x1)*(4*x1^2 + 2*x2^2 + 4*x1*x2 + 2*x2 + 1);
!约束条件;
1.5 + x1*x2 - x1 - x2 <= 0;
- x1*x2 <= 10;
end
结果:
Global optimal solution found.
Objective value: 8.500000
Objective bound: 8.500000
Infeasibilities: 0.000000
Extended solver steps: 3
Total solver iterations: 73
Model Class: NLP
Total variables: 2
Nonlinear variables: 2
Integer variables: 0
Total constraints: 3
Nonlinear constraints: 3
Total nonzeros: 6
Nonlinear nonzeros: 6
Variable Value Reduced Cost
X1 0.000000 18.50000
X2 1.500000 0.000000
Row Slack or Surplus Dual Price
1 8.500000 -1.000000
2 0.000000 8.000000
3 10.00000 0.000000
结论: 遗传算法找到了全局最优解。
遗传算法详解博文
这里边写的很清楚,源代码实验结果都有。
我加了一部分注释,程序如下:
% 利用遗传算法,解决TSP问题模板
tic %tic toc 用来计算程序段运行的时间
clc,clear
sj = load('gadata.txt'); %加载敌方100 个目标的数据 sj = 25*8 输入数据是精度和纬度信息
x=sj(:,1:2:8);x=x(:); %x为经度 x = 100*1
y=sj(:,2:2:8);y=y(:); %y为纬度 y = 100*1
sj=[x y]; %sj = 100*2 sj(1)经度,sj(2)纬度
figure(1);
plot(x,y);
xlabel('longtitude');
ylabel('latitude');%画出初始图形
d1=[70,40];%初始点
sj0=[d1;sj;d1];%sj0 102*2
%距离矩阵d
sj=sj0*pi/180; %变为弧度制
d=zeros(102);%距离矩阵初始化 d 102*102
for i=1:101
for j=i+1:102
temp=cos(sj(i,1)-sj(j,1))*cos(sj(i,2))*cos(sj(j,2))+sin(sj(i,2))*sin(sj(j,2));
d(i,j)=6370*acos(temp);
end
end
d=d+d';L=102;w=50;dai=100;
%通过改良圈算法选取优良父代A
for k=1:w
c=randperm(100);
c1=[1,c+1,102];
flag=1;
while flag>0
flag=0;
for m=1:L-3
for n=m+2:L-1
if d(c1(m),c1(n))+d(c1(m+1),c1(n+1))