问题描述
用 Matlab 编写遗传算法求解
max 𝑓(𝑥1, 𝑥2) = (21.5 + 𝑥1 ∙ sin(4𝜋𝑥1) + 𝑥2 ∙ sin(20𝜋𝑥2))
𝑠.𝑡. − 2.9 ≤ 𝑥1 ≤ 12.0,
4.2 ≤ 𝑥2 ≤ 5.7
遗传算法
具体算法原理参考计算智能
代码实现
- 可行解采用实数编码方式,自行设定初始参数,包括:种群个数,交叉概率,
变异概率,最大迭代次数
代码如下:
% 目标函数
fun = @(x) 21.5 + x(:, 1) .* sin(4 * pi * x(:,1)) + x(:,2) .* sin(20 * pi * x(:, 2));
pc = 0.8; % 交叉概率
pm = 0.1; % 变异概率
MaxIter =200; % 迭代次数
Popsize = 100; % 基因数
dim = 2; % 解的维度
% 两个约束条件
low = [-2.9, 4.2]; % 下限
up = [12.0, 5.7]; % 上限
% 初始化种群:在约束条件范围生成x1,x2集合
Pop = rand(Popsize, 2) .* (up - low) + low;
- 自行定义和实现选择算子、交叉算子和变异算子
选择算子代码如下:(最大值选择)
% 选择
change = 20;
for i = 1:change
Pop(p(i), :) = Pop(p(Popsize), :);
end
交叉算子代码如下:(均匀交叉)
% 交叉
for i=1:Popsize
if rand < pc
% 随机选择两个父代
x = randi(Popsize,2,1);
parent1 = Pop(x(1),:);
parent2 = Pop(x(2),:);
% 使用均匀交叉获得子代
mask = rand(1, 2) > 0.5;
child1 = parent1;
child1(mask) = parent2(mask);
child2 = parent2;
child2(mask) = parent1(mask);
Pop(x(1), :) = child1;
Pop(x(2), :) = child2;
end
变异算子代码如下:(随机变异)
% 变异
for i = 1:Popsize
if rand < pm && i ~= q || 1 % 不对最优路径进行变异
% 随机选择变异的位置
choose = randi(dim);
% 生成变异的随机数
Pop(i, choose) = low(choose) + (up(choose) - low(choose)) * rand();
end
end
- 输出最优解及函数的最大值,及其对应的迭代次数
代码如下:
% 找出全局最优解及其迭代次数
[MaxestAns_value, Iterindex] = max(MaxAns_alue);
disp('获得最优解的迭代次数为:');
disp(Iterindex);
disp('目标函数最优解为:');
disp(MaxAns(Iterindex, :));
disp('目标函数最大值为:');
disp(MaxestAns_value);
- 画出迭代曲线
代码如下:
% 迭代曲线图
figure;
plot(MaxAns_alue);
title('迭代曲线');
xlabel('迭代次数');
ylabel('最短路径长度');
完整代码
% 目标函数
fun = @(x) 21.5 + x(:, 1) .* sin(4 * pi * x(:,1)) + x(:,2) .* sin(20 * pi * x(:, 2));
pc = 0.8; % 交叉概率
pm = 0.1; % 变异概率
MaxIter =200; % 迭代次数
Popsize = 100; % 基因数
dim = 2; % 解的维度
% 两个约束条件
low = [-2.9, 4.2]; % 下限
up = [12.0, 5.7]; % 上限
% 初始化种群:在约束条件范围生成x1,x2集合
Pop = rand(Popsize, 2) .* (up - low) + low;
Iter = 1;
MaxAns = zeros(MaxIter, dim);
MaxAns_alue = zeros(MaxIter, 1);
while(Iter <= MaxIter)
% 计算适应度
fitness = fun(Pop);
[Maxvalue, q] = max(fitness);
MaxPop_parents = Pop(q, :);
MaxPop_parents_value = Maxvalue;
% 对适应度进行从小到大排序
[f, p] = sort(fitness);
% 选择最大值的解替换前 n 个解
change = 20;
for i = 1:change
Pop(p(i), :) = Pop(p(Popsize), :);
end
% 交叉
for i=1:Popsize
if rand < pc
% 随机选择两个父代
x = randi(Popsize,2,1);
parent1 = Pop(x(1),:);
parent2 = Pop(x(2),:);
% 使用均匀交叉获得子代
mask = rand(1, 2) > 0.5;
child1 = parent1;
child1(mask) = parent2(mask);
child2 = parent2;
child2(mask) = parent1(mask);
Pop(x(1), :) = child1;
Pop(x(2), :) = child2;
end
end
% 计算交叉后的函数值,并找出最大值的解
Value = fun(Pop);
[Maxvaule, q] = max(Value);
MaxPop_crossover = Pop(q, :);
MaxPop_crossover_value = Maxvaule;
% 变异
for i = 1:Popsize
if rand < pm && i ~= q || 1 % 不对最优路径进行变异
% 随机选择变异的位置
choose = randi(dim);
% 生成变异的随机数
Pop(i, choose) = low(choose) + (up(choose) - low(choose)) * rand();
end
end
% 计算变异后的函数值,并找出最大值的解
Value = fun(Pop);
[Maxvaule, q] = max(Value);
MaxPop_mutation = Pop(q, :);
MaxPop_mutation_value = Maxvaule;
% 每一代中找到的最优路径
MaxPop_opt = [MaxPop_parents; MaxPop_crossover; MaxPop_mutation];
a = [MaxPop_parents_value; MaxPop_crossover_value; MaxPop_mutation_value];
[Maxvalue ,m] = max(a);
MaxAns(Iter, :) = MaxPop_opt(m, :);
MaxAns_alue(Iter, 1) = Maxvalue;
Iter = Iter + 1;
end
% 找出全局最优解及其迭代次数
[MaxestAns_value, Iterindex] = max(MaxAns_alue);
disp('获得最优解的迭代次数为:');
disp(Iterindex);
disp('目标函数最优解为:');
disp(MaxAns(Iterindex, :));
disp('目标函数最大值为:');
disp(MaxestAns_value);
% 迭代曲线图
figure;
plot(MaxAns_alue);
title('迭代曲线');
xlabel('迭代次数');
ylabel('最短路径长度');
输出结果
迭代曲线图
最佳路径以及长度