遗传算法实战:基于MATLAB

求解 f = − 5 s i n x 1 s i n x 2 s i n x 3 s i n x 4 s i n x 5 − s i n ( 5 x 1 5 x 2 5 x 3 5 x 4 5 x 5 ) + 8 ,其中 0 < = x 1 , x 2 , x 3 , x 4 , x 5 < = 0.9 π (最小值为 2 点多) \text{求解}f=-5sinx_1sinx_2sinx_3sinx_4sinx_5-sin(5x_15x_25x_35x_45x_5)+8,{其中}0<=x_1,x_2,x_3,x_4,x_5<=0.9\pi (\text{最小值为}2\text{点多}) 求解f=5sinx1sinx2sinx3sinx4sinx5sin(5x15x25x35x45x5)+8其中0<=x1,x2,x3,x4,x5<=0.9π最小值为2点多

主函数 Genetic.m
1 初始化参数
%% 遗传算法
% 求解f = -5*sinx1*sinx2*sinx3*sinx4*sinx5 - sin(5*x1*5*x2*5*x3*5*x4*5*x5) + 8
% 其中0<= x1,x2,x3,x4,x5 <= 0.9pi,最小值为2点多
clear; clc

maxgen = 100; % 最大迭代次数
sizepop = 50; % 种群规模
pcross = 0.6; % 交叉率(达到阈值才交叉)
pmutation = 0.01; % 变异率(达到阈值才变异)

lenchrom = [1, 1, 1, 1, 1]; % 基因的长度(视具体情况而定)
% 五个变量的范围(视具体情况而定)
bound = [0, 0.9*pi; 0, 0.9*pi; 0, 0.9*pi; 0, 0.9*pi; 0, 0.9*pi];

% 个体(采用结构体方式实现) fitness:适应度 chrom:基因
individuals = struct('fitness', zeros(1, sizepop), 'chrom', []);
% avgfitness = []; % 平均适应度
% bestfitness = []; % 最好适应度
% bestchrom = []; % 最好的基因
2 初始化种群
% 初始化种群
for i = 1 : sizepop
    % Code函数用于实现基因的随机形成
    individuals.chrom(i, :) = Code(lenchrom, bound, sizepop);
    x = individuals.chrom(i, :);
    % fun函数用于计算基因的函数值(本题中该值越小越好,而适应值越大越好)
    individuals.fitness(i) = fun(x);
end

% 最好的适应度及其下标、最好的基因、平均适应度
% 本题中函数值越小,适应能力就越强,故选择最小值
[bestfitness, bestindex] = min(individuals.fitness);
bestchrom = individuals.chrom(bestindex, :);
avgfitness = sum(individuals.fitness) / sizepop;
3 函数主体:实现搜索过程
trace = zeros(maxgen, 2); % 记录每一代最好的适应度和平均适应度
% 开始遗传
for i = 1 : maxgen
    % Select函数进行选择操作
    individuals = Select(individuals, sizepop);
    % Cross函数进行交叉操作
    individuals.chrom = Cross(pcross, lenchrom, individuals.chrom, sizepop);
    % Mutation函数进行变异操作
    individuals.chrom = Mutation(pmutation, lenchrom, individuals.chrom, sizepop, [i,maxgen], bound);
    % 计算下一代种群的适应度
    for j = 1 : sizepop
        x = individuals.chrom(j, :);
        individuals.fitness(j) = fun(x);
    end
    % 更新最好的适应度与基因、平均适应度
    [newbestfitness, newbestindex] = min(individuals.fitness);
    [worestfitness, worestindex] = max(individuals.fitness);
    % 代替上一次净化中最好的染色体(同时将最差的修改)
    if bestfitness > newbestfitness
       bestfitness = newbestfitness;
       bestchrom = individuals.chrom(newbestindex, :);
    end
    individuals.chrom(worestindex, :) = bestchrom;
    individuals.fitness(worestindex) = bestfitness;
    avgfitness = sum(individuals.fitness) / sizepop;
    % 记录每一代中进化最好的适应度和平均适应度
    trace(i, :) = [avgfitness, bestfitness];
end
% 进化结束
4 结果展示
%% 结果显示
[r, c] = size(trace);
figure
plot((1: r)', trace(:, 1), 'r-', (1: r)', trace(:, 2), 'b--');
title(['函数值曲线', '终止代数=', num2str(maxgen)], 'fontsize', 12);
xlabel('进化代数', 'fontsize', 12); ylabel('函数值', 'fontsize', 12);
legend('各代平均值', '各代最佳值');
xlim([1, r]); ylim([1.5, 8]);
grid on % 显示网格线
disp('函数值 变量')
disp([bestfitness, individuals.chrom(bestindex, :)])
适应度函数 fun.m
function y = fun(x)
% 用于计算函数值
y = -5 * sin(x(1)) * sin(x(2)) * sin(x(3)) * sin(x(4)) * sin(x(5))...
        - sin(5*x(1) * 5*x(2) * 5*x(3) * 5*x(4) * 5*x(5)) + 8; % 视具体情况而定
生成初始化种群 Code.m
function ret = Code(lenchrom, bound, sizepop)
% 本函数用于随机初始化一个种群
% lenchrom input:染色体长度
% bound input:变量的取值范围
% sizepop input:种群的大小
% ret output:染色体的编码值
for i = 1 : sizepop
    % pick为随机生成的基因(0-1、1行5列)
    pick = rand(1, length(lenchrom));
    % ret为随机生成在边界内的基因(视具体情况而定)
    ret = bound(:, 1)' + (bound(:, 2) - bound(:, 1))' .* pick;
end
选择函数 Select.m
function ret = Select(individuals, sizepop)
% 本函数对每一代种群中的染色体进行选择,以进行后续的交叉与变异
% individuals input:种群结构体信息
% sizepop input:种群规模
% ret output:经过筛选后的种群
% 将函数值转换为求适应度的值
individuals.fitness = 1 ./ individuals.fitness;
sumfitness = sum(individuals.fitness);
% 每个个体选中的概率
sumf = individuals.fitness ./ sumfitness;

index = zeros(1, sizepop); % 记录选中的个体
% 会选中优秀的重复个体
for i =  1 : sizepop
    pick = rand; % 生成一个随机数
    while pick == 0
       pick = rand; 
    end
    for j = 1 : sizepop
       pick = pick - sumf(j);
       % 当pick小于零时,表示选中
       if pick < 0
           index(i) = j;
           break; % 选中结束
       end
    end
end
% 更新种群
individuals.chrom = individuals.chrom(index, :);
individuals.fitness = individuals.fitness(index);
ret = individuals;
交叉函数 Cross.m
function ret = Cross(pcross, lenchrom, chrom, sizepop)
% 本函数完成交叉操作
% pcross input:交叉概率
% lenchrom input:染色体的长度
% chrom input:染色体种群
% sizepop input:种群规模
% bound input:变量的取值范围
% ret output:交叉后的染色体
for i = 1 : sizepop
    % 随机选择两个染色体进行交叉
    pick = rand(1, 2); % 1行2列
    while prod(pick) == 0
        pick = rand(1, 2); 
    end
    index = ceil(pick .* sizepop); % 交叉的两项(ceil向上取整)
    pick = rand; % 随机生成一个值,用于判定是否进行交叉
    while pick == 0
       pick = rand; 
    end
    if pick > pcross % 大于交叉率不进行交叉
       continue; 
    end
    pick = rand; % 所选择的两个染色体在哪个位置进行交叉
    while pick == 0
        pick = rand; 
    end
    pos = ceil(pick .* sum(lenchrom));
    % 交叉开始(pick用于控制交叉变化)
    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;
    % 不用判断交叉生成的染色体是否有效,因为生成的染色体仍在恰当范围内
end
ret = chrom;
变异操作 Mutation.m
function ret = Mutation(pmutation, lenchrom, chrom, sizepop, pop, bound)
% 本函数完成变异操作
% pmutation input:变异概率
% lenchrom input:染色体长度
% chrom input:染色体种群
% siezpop input:种群规模
% pop input:当前种群的进化代数和最大的进化代数的向量
% bound input:变量的取值范围
% ret output:编译后的染色体
for i = 1 : sizepop
    % 随机选择一个染色体进行变异
    pick = rand;
    while pick == 0
       pick = rand; 
    end
    index = ceil(pick * sizepop); % 选择变异染色体
    pick = rand; % 判断是否变异
    if pick > pmutation
       continue; 
    end
    pick = rand; % 选中的染色体哪一个位置发生变异
    while pick == 0
        pick = rand; 
    end
    pos = ceil(pick * sum(lenchrom));
    v = chrom(index, pos);
    v1 = v - bound(pos, 1);
    v2 = bound(pos, 2) - v;
    pick = rand; % 用于控制变异的变化
    if pick <= 0.5
        delta = v1 * (1 - pick * ((1 - pop(1) / pop(2)) ^ 2));
        chrom(index, pos) = v - delta;
    else
        delta = v2 * (1 - pick * ((1 - pop(1) / pop(2)) ^ 2));
        chrom(index, pos) = v + delta;
    end
    % 不用判断变异生成的染色体是否有效,因为生成的染色体仍在恰当范围内
end
ret = chrom;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胆怯与勇敢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值