经典优化算法:遗传算法(Genetic Algorithm, GA)

server/2025/3/31 12:12:35/

网上有许多关于遗传算法原理的解读,这里博主也不必做过多的介绍,现在从已有的MATLAB代码为切入点简单介绍一下遗传算法

01.引言

遗传算法(Genetic Algorithm, GA)是进化计算领域的核心方法之一,起源于对生物进化过程的数学建模与仿生学研究。其核心思想基于达尔文的“自然选择”理论,通过选择(Selection)、交叉(Crossover)和变异(Mutation)操作对种群进行迭代优化,逐步逼近最优解。GA的优势在于:

1.全局搜索能力:通过种群多样性避免陷入局部最优。

2.无需梯度信息:适用于不可导、非凸、高维问题。

3.广泛适用性:可用于连续优化、组合优化(如TSP)、机器学习调参等。

其核心思想是:将解编码为“染色体”,通过适应度函数评估优劣,优胜劣汰生成下一代,最终收敛到最优解。

02.结合代码的算法的流程(文末附代码)

1.初始化

popsize = pop;          % 种群规模
lenchrom = dim;         % 变量维度(染色体长度)
pc = 0.7;               % 交叉概率
pm = 0.05;              % 变异概率
maxgen = Max_iter;      % 最大迭代次数

关键参数

  • popsize:种群大小,影响搜索空间覆盖度。

  • pc和pm:控制探索(交叉)与开发(变异)的平衡。

  • maxgen:迭代次数,决定计算资源与精度的权衡。

2. 初始化种群

for i=1:popsizeGApop(i,:) = Code(lenchrom, bound);  % 生成随机个体fitness(i) = fun(GApop(i,:));        % 计算适应度
end
  • Code函数:在变量范围bound内随机生成个体,确保初始种群多样性。

  • 适应度评估:调用目标函数fobj(即用户定义的优化问题),值越小表示个体越优(最小化问题)。

3.迭代进化

for i=1:maxgen% 选择、交叉、变异GApop = Select2(GApop, fitness, popsize);GApop = Cross(pc, lenchrom, GApop, popsize, bound);GApop = Mutation(pm, lenchrom, GApop, popsize, [i maxgen], bound);% 更新适应度及最优解for j=1:popsizefitness(j) = fun(GApop(j,:));if fitness(j) < fitnessgbest(j)gbest(j,:) = GApop(j,:);     % 更新个体历史最优endif fitness(j) < fitnesszbestzbest = GApop(j,:);          % 更新全局最优endendcurve(i) = fitnesszbest;             % 记录收敛曲线
end

3.1 选择(Select2)

轮盘赌选择(Roulette Wheel Selection):

  • 适应度取倒数(因代码针对最小化问题),适应度越优(值越小)的个体被选中的概率越高。

  • 根据概率分布随机选择个体,确保优秀个体有更多繁殖机会,但避免完全贪婪导致早熟。

fitness = 1./(fitness);                  % 最小化转最大化
sumf = fitness./sum(fitness);            % 归一化为概率
index = 轮盘赌选择sizepop次;              % 根据概率选取个体索引
individualsTemp = individuals(index,:);  % 新种群

3.2 交叉:算术交叉(Arithmetic Crossover)

  • 随机选择两个父代个体,在随机位置pos进行线性插值交叉。

  • 公式:child1 = pick*parent2 + (1-pick)*parent1

  • 确保子代在父代附近搜索,平衡全局与局部探索。

pos = ceil(rand * lenchrom);             % 随机选择交叉位置
v1 = parent1(pos); v2 = parent2(pos);
child1(pos) = pick*v2 + (1-pick)*v1;    % 线性插值生成子代

3.3 变异:非均匀变异(Non-uniform Mutation)

  • 随机选择一个位置pos,根据当前迭代次数调整变异幅度

  • 公式:delta = v2*(1-rand^((1-t/T)^k)),其中t为当前代数,T为总代数。

  • 早期变异幅度大(全局探索),后期幅度小(局部开发)。

delta = v2*(1 - rand^((1 - i/maxgen)^2));  % 变异幅度递减
chrom(i,pos) = v + delta;                  % 更新基因值

4. 约束处理

  • 边界检查(test函数):在交叉和变异后,检查个体是否在bound范围内,若越界则重新生成。

  • 自适应调整:通过bound动态约束搜索空间,确保解的可行性。

03.近年来相关论文发表

跨越半个世纪的技术生命力:遗传算法依旧活跃

04.本文代码效果图

05.部分代码

% Genetic Algorithm 遗传算法             %
function [Best_score,Best_pos,curve]=GA(pop,Max_iter,lb,ub,dim,fobj)
%% 参数初始化
popsize=pop;              %种群规模
lenchrom=dim;              %变量字串长度
fun = fobj;  %适应度函数
pc=0.7;                  %设置交叉概率
pm=0.05;                  %设置变异概率
if(max(size(ub)) == 1)ub = ub.*ones(dim,1);lb = lb.*ones(dim,1);  
end
maxgen=Max_iter;   % 进化次数  
%种群
bound=[lb,ub];  %变量范围
%% 产生初始粒子和速度
for i=1:popsize%随机产生一个种群GApop(i,:)=Code(lenchrom,bound);       %随机产生个体%计算适应度[fitness(i)]=fun(GApop(i,:));            %染色体的适应度
end
%找最好的染色体
[bestfitness bestindex]=min(fitness);
zbest=GApop(bestindex,:);   %全局最佳
gbest=GApop;                %个体最佳
fitnessgbest=fitness;       %个体最佳适应度值
fitnesszbest=bestfitness;   %全局最佳适应度值
%% 迭代寻优
for i=1:maxgen
%         disp(['第',num2str(i),'次迭代'])%种群更新 GA选择更新GApop=Select2(GApop,fitness,popsize);% 交叉操作 GAGApop=Cross(pc,lenchrom,GApop,popsize,bound);% 变异操作 GA变异GApop=Mutation(pm,lenchrom,GApop,popsize,[i maxgen],bound);pop=GApop;for j=1:popsize%适应度值[fitness(j)]=fun(pop(j,:));%个体最优更新if fitness(j) < fitnessgbest(j)gbest(j,:) = pop(j,:);fitnessgbest(j) = fitness(j);end%群体最优更新if fitness(j) < fitnesszbestzbest = pop(j,:);fitnesszbest = fitness(j);endendcurve(i)=fitnesszbest;     
end
Best_score = fitnesszbest;
Best_pos = zbest;
end
%% 选择函数
function ret=Select2(individuals,fitness,sizepop)
% 本函数对每一代种群中的染色体进行选择,以进行后面的交叉和变异
% individuals input  : 种群信息
% fitness input  : 适应度
% sizepop     input  : 种群规模
% opts        input  : 选择方法的选择
% ret         output : 经过选择后的种群
fitness= 1./(fitness);
sumfitness=sum(fitness);
sumf=fitness./sumfitness;
index=[];
for i=1:sizepop   %转sizepop次轮盘pick=rand;while pick==0pick=rand;endfor j=1:sizepoppick=pick-sumf(j);if pick<0index=[index j];break;  %寻找落入的区间,此次转轮盘选中了染色体i,注意:在转sizepop次轮盘的过程中,有可能会重复选择某些染色体endend
end
individualsTemp=individuals(index,:);
fitnessTemp=fitness(index);
if(size(individualsTemp,1) == 0)ret=individuals;
elseret=individualsTemp;
end
end
%% 交叉函数
function ret=Mutation(pmutation,lenchrom,chrom,sizepop,pop,bound)
% 本函数完成变异操作
% pcorss                input  : 变异概率
% lenchrom              input  : 染色体长度
% chrom                 input  : 染色体群
% sizepop               input  : 种群规模
% pop                   input  : 当前种群的进化代数和最大的进化代数信息
% ret                   output : 变异后的染色体
for i=1:sizepop  % 随机选择一个染色体进行变异pick=rand;while pick==0pick=rand;endindex=ceil(pick*sizepop);% 变异概率决定该轮循环是否进行变异pick=rand;if pick>pmutationcontinue;endflag=0;while flag==0% 变异位置pick=rand;while pick==0pick=rand;endpos=ceil(pick*sum(lenchrom));  %随机选择了染色体变异的位置,即选择了第pos个变量进行变异if pos<=0 pos = 1;endif pos>size(bound,1)pos = size(bound,1);endv=chrom(i,pos);v1=v-bound(pos,1);v2=bound(pos,2)-v;pick=rand; %变异开始if pick>0.5delta=v2*(1-pick^((1-pop(1)/pop(2))^2));chrom(i,pos)=v+delta;elsedelta=v1*(1-pick^((1-pop(1)/pop(2))^2));chrom(i,pos)=v-delta;end   %变异结束flag=test(lenchrom,bound,chrom(i,:));     %检验染色体的可行性end
end
ret=chrom;
end
%% 变异函数
function ret=Cross(pcross,lenchrom,chrom,sizepop,bound)
%本函数完成交叉操作
% pcorss                input  : 交叉概率
% lenchrom              input  : 染色体的长度
% chrom                 input  : 染色体群
% sizepop               input  : 种群规模
% ret                   output : 交叉后的染色体
for i=1:sizepop % 随机选择两个染色体进行交叉pick=rand(1,2);while prod(pick)==0pick=rand(1,2);endindex=ceil(pick.*sizepop);% 交叉概率决定是否进行交叉pick=rand;while pick==0pick=rand;endif pick>pcrosscontinue;endflag=0;while flag==0% 随机选择交叉位置pick=rand;while pick==0pick=rand;endpos=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; %交叉结束flag1=test(lenchrom,bound,chrom(index(1),:));  %检验染色体1的可行性flag2=test(lenchrom,bound,chrom(index(2),:));  %检验染色体2的可行性if   flag1*flag2==0flag=0;else flag=1;end    %如果两个染色体不是都可行,则重新交叉end
end
ret=chrom;
end
%% 判断是否在范围内
function flag=test(lenchrom,bound,code)
% lenchrom   input : 染色体长度
% bound      input : 变量的取值范围
% code       output: 染色体的编码值
flag=1;
[n,m]=size(code);
for i=1:nif code(i)<bound(i,1) || code(i)>bound(i,2)flag=0;end
end
end
%% 编码函数
function ret=Code(lenchrom,bound)
%本函数将变量编码成染色体,用于随机初始化一个种群
% lenchrom   input : 染色体长度
% bound      input : 变量的取值范围
% ret        output: 染色体的编码值
flag=0;
while flag==0pick=rand(1,lenchrom);ret=bound(:,1)'+(bound(:,2)-bound(:,1))'.*pick; %线性插值flag=test(lenchrom,bound,ret);             %检验染色体的可行性
end
end

✅作者简介:信号处理方向在校博士研究生,目前专研于MATLAB算法及科学绘图等,熟知各种信号分解算法、神经网络时序、回归和分类预测算法、数据拟合算法以及滤波算法。提供一个可以相互学习相互进步的平台

🚩技术信仰:知行合一,让每一行代码都成为解决问题的利器

🔍后台私信备注个人需求(比如GA-BP)定制以下TOC算法优化模型(看到秒回):

1.回归/时序/分类预测类:BP、RF、XGBoost、RBF、LSSVM、SVM、ELM、DELM、ESN、RELM等等均可,优化算法优化BP为例,可达到以下效果:

(1)优化BP神经网络的数据时序预测

(2)优化BP神经网络的数据回归(多输入多输出)预测

(3)优化BP神经网络的数据回归预测

2.分解类:EEMD、VMD、REMD、CEEMDAN、ICEEMDAN、SVMD等分解模型均可,优化算法优化VMD/ICEEMDAN为例,可达到以下效果:

(1)基于改进天鹰优化算法(IAO)优化的VMD参数

(2)基于改进天鹰优化算法(IAO)优化ICEEMDAN参数

3.去噪算法算法类:VMD/CEEMDAN/ICEEMDAN/SVMD+小波阈值/SVD去噪,可在去噪算法前加智能优化算法优化参数以VMD-WT/SVD为例,可达到以下效果:

(1)基于VMD-SpEn(样本熵)联合小波阈值去噪

(2)基于SVMD-SVD的信号去噪算法

(3)基于ZOA优化VMD-IAWT岩石声发射信号降噪算法


http://www.ppmy.cn/server/179849.html

相关文章

树莓派(4B)使用教程-小白之路(NO.1)

目录 我们将会使用树莓派实现&#xff1a; 大体介绍&#xff08;三部分&#xff09; 1.简单介绍 1.1 什么是树莓派 1.2 和单片机有什么区别 区别一 区别二 1.3 和电脑有什么区别 1.4 用树莓派实现opencv视觉检测的原理是什么 Tip&#xff1a;需要超快速了解请直接看有背…

记20个忘10个之十:黑色不幽默

记20个忘10个之十&#xff1a;黑色不幽默 注&#xff1a;所谓记20个忘10个&#xff0c;本质是指规模化记忆&#xff0c;是遵循人的记忆规律&#xff08;反言之&#xff0c;即遗忘的事实或规律&#xff09;的一种记忆方法&#xff0c;该方法倡导短时高频、大量记忆单词&#xff…

爬虫面试题

总结一下最近面试遇到的笔试题 1、解释Python中的init方法的作用。 在Python中&#xff0c;__init__方法是一种特殊的构造方法&#xff0c;主要用于在创建类的实例时初始化对象。至少接受至少一个参数&#xff1a;self,它是对当前实例的引用&#xff0c;可以通过添加其他参数…

ngx_http_index_set_index

定义在 src\http\modules\ngx_http_index_module.c static char * ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {ngx_http_index_loc_conf_t *ilcf conf;ngx_str_t *value;ngx_uint_t i, n;ngx_http_inde…

【C++进阶】函数:深度解析 C++ 函数的 12 大进化特性

目录 一、函数基础 1.1 函数定义与声明 1.2 函数调用 1.3 引用参数 二、函数重载&#xff1a;同名函数的「多态魔法」&#xff08;C 特有&#xff09; 2.1 基础实现 2.2 重载决议流程图 2.3 与 C 语言的本质区别 2.4 实战陷阱 三、默认参数&#xff1a;接口的「弹性设…

北理工计算机考研复试上机2024年真题

1、输入一组单词(区分大小写),统计首字母相同的单词的个数&#xff0c;相 同的单词不累加&#xff0c;输出格式:“字母&#xff0c;个数” input: I am a boy,you are a boy. output: I,1 a,3 b,1 y,1 代码&#xff1a; #include <bits/stdc.h> using namespace…

C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷五)

目录 1. sizeof 和 strlen的区别 1.1 sizeof 1.2 strlen 2. 数组和指针习题解析 2.1 一维数组 2.2 字符数组 代码1&#xff1a; 代码2&#xff1a; 代码3: 代码4&#xff1a; 代码5&#xff1a; 代码6&#xff1a; 2.3 二维数组 3. 指针运算笔试题解析 3.1 3.…

RabbitMQ 学习整理1 - 基础使用

项目代码&#xff1a;RabbitMQDemo: 学习RabbitMQ的一些整理 基本概念 RabbitMQ是一种基于AMQP协议的消息队列实现框架RabbitMQ可以用于在系统与系统之间或者微服务节点之间&#xff0c;进行消息缓存&#xff0c;消息广播&#xff0c;消息分配以及限流消峰处理RabbitMQ-Serve…