优化算法 | 遗传算法(附Python代码)
今天为各位讲解遗传算法(GA),相信各位对GA都已非常熟悉,之前我们也出过很多关于GA的教程:
- 遗传算法(GA)求解带时间窗的车辆路径(VRPTW)问题MATLAB代码
- 遗传算法(GA)求解容量受限的车辆路径(CVRP)问题MATLAB代码
- 遗传算法求解0-1背包问题(附matlab源代码)
- 遗传算法(GA)求解旅行商问题(TSP)附MATLAB代码
- 优化算法 | 遗传算法的变形
- 机器学习 | 基于遗传算法的BP神经网络优化算法(附MATLAB代码)
- 多种群遗传算法的函数优化算法(附MATLAB代码)
- 基于量子遗传算法的函数寻优算法
- 遗传算法求解车间调度问题(附MATLAB代码)
之前的教程基本上都是用GA求解离散优化问题,鲜有涉及连续优化问题,因此今天我们主要讲解使用GA求解连续优化问题。
我们首先给出求解问题,目标是求解下述函数最小值:
▎GA算法求解步骤
01 | 种群初始化
因为求解问题的变量数目为5,所以染色体长度为5。假设种群数目为npop,则随机生成npop个长度为5的个体,并且每个个体在每个维度上的取值应该在-100~100之间。种群初始化的代码如下:
# Initialize Population
pop = empty_individual.repeat(npop)
for i in range(npop):pop[i].position = np.random.uniform(varmin, varmax, nvar)pop[i].cost = costfunc(pop[i].position)if pop[i].cost < bestsol.cost:bestsol = pop[i].deepcopy()
假设npop=5,则初始化种群结果如下,其中position是个体位置,cost是个体目标函数值:
[struct({'position': array([-31.01033353,94.77288865,-91.01647726,1.32204408,-49.62896178]), 'cost': 20692.321989577737}),
struct({'position': array([-69.29141662,63.88025843,69.29075941,34.80789342,81.93170175]), 'cost': 21607.590370704376}),
struct({'position': array([-64.22127924,0.08618959,-56.55556517,-10.68613122,-61.14429882]), 'cost': 11175.730766415392}),
struct({'position': array([ 80.3919982,-56.0863127,-27.38791656,-39.56431118,-31.46714348]), 'cost': 12914.161657029803}),
struct({'position': array([ 27.41598459,24.68736174,-31.05651977,-48.98385997,-43.34750546]), 'cost': 6604.034227715052})]
02 | 适应度值计算
这份代码中的适应度值就是目标函数值,具体代码如下:
# Sphere Test Function
def sphere(x):return sum(x**2)
03 | 选择操作
选择操作就是从当前种群中选择出若干个个体,这份代码使用的是轮盘赌选择策略,也就是适应度值大的个体有更大的概率被选中,具体代码如下:
def roulette_wheel_selection(p):c = np.cumsum(p)r = sum(p)*np.random.rand()ind = np.argwhere(r <= c)return ind[0][0]
假设输入参数p=[1,2,3,4,5],接下来依次看每一行代码代表什么含义。
cumsum函数是累加函数,则c=[1,3,6,10,15]。
sum函数是求和函数,sum(p)=15,np.random.rand()函数返回一个[0,1)之间的随机数,不包括1,则r的取值范围为[0,15)之间的一个数,不包括15,假设此时r=5。
np.argwhere(a)函数返回非0元素的索引,其中a是要索引数组的条件,并且该函数输出的是一列元素。因此np.argwhere(r <= c)返回的是r <= c的索引,输出结果为
def roulette_wheel_selection(p):c = np.cumsum(p)r = sum(p)*np.random.rand()ind = np.argwhere(r <= c)return ind[0][0]
最终返回ind[0][0]=2,说明r=5落在3~6之间,即落在p=3所属的区间,轮盘赌示意图如下图所示。
04 | 交叉操作
交叉操作就是对选择出的两个个体进行处理,使这两个个体能够互相继承彼此良好的基因片段,具体代码如下:
def crossover(p1, p2, gamma=0.1):c1 = p1.deepcopy()c2 = p1.deepcopy()alpha = np.random.uniform(-gamma, 1+gamma, *c1.position.shape)c1.position = alpha*p1.position + (1-alpha)*p2.positionc2.position = alpha*p2.position + (1-alpha)*p1.positionreturn c1, c2
np.random.uniform(low,high,size)函数返回size相同维度且取值范围在[low,high)之间的随机数,如
np.random.uniform(low = 0, high = 1, size = 4)
返回4个[0,1)之间的随机数,具体返回结果如下
[0.25773193 0.90374664 0.51513421 0.60574244]
下面这两行代码实际上表示产生两个新个体的计算公式。
c1.position = alpha*p1.position + (1-alpha)*p2.position
c2.position = alpha*p2.position + (1-alpha)*p1.position
05 | 变异操作
变异操作是对某一个个体进行处理,更新该个体的位置,具体代码如下,其中mu是变异概率:
def mutate(x, mu, sigma):y = x.deepcopy()flag = np.random.rand(*x.position.shape) <= muind = np.argwhere(flag)y.position[ind] += sigma*np.random.randn(*ind.shape)return y
flag = np.random.rand(*x.position.shape) <= mu这行代码的含义是判断随机生成的与个体长度相等的数字中是否小于等于变异概率mu,返回结果示例为[False True False False False]
ind = np.argwhere(flag)表示找出flag为True的索引,即找出待变异的基因位,返回结果为ind=[[1]]。
y.position[ind] += sigma*np.random.randn(*ind.shape)表示更新待变异的基因位。
▎GA算法流程图
▎GA算法实例验证
实例验证函数如下,目标是求解下述函数最小值:
ga.py代码如下:
import numpy as np
from ypstruct import structuredef run(problem, params):# Problem Informationcostfunc = problem.costfuncnvar = problem.nvarvarmin = problem.varminvarmax = problem.varmax# Parametersmaxit = params.maxitnpop = params.npopbeta = params.betapc = params.pcnc = int(np.round(pc*npop/2)*2)gamma = params.gammamu = params.musigma = params.sigma# Empty Individual Templateempty_individual = structure()empty_individual.position = Noneempty_individual.cost = None# Best Solution Ever Foundbestsol = empty_individual.deepcopy()bestsol.cost = np.inf# Initialize Populationpop = empty_individual.repeat(npop)for i in range(npop):pop[i].position = np.random.uniform(varmin, varmax, nvar)pop[i].cost = costfunc(pop[i].position)if pop[i].cost < bestsol.cost:bestsol = pop[i].deepcopy()# Best Cost of Iterationsbestcost = np.empty(maxit)# Main Loopfor it in range(maxit):costs = np.array([x.cost for x in pop])avg_cost = np.mean(costs)if avg_cost != 0:costs = costs/avg_costprobs = np.exp(-beta*costs)popc = []for _ in range(nc//2):# Select Parents#q = np.random.permutation(npop)#p1 = pop[q[0]]#p2 = pop[q[1]]# Perform Roulette Wheel Selectionp1 = pop[roulette_wheel_selection(probs)]p2 = pop[roulette_wheel_selection(probs)]# Perform Crossoverc1, c2 = crossover(p1, p2, gamma)# Perform Mutationc1 = mutate(c1, mu, sigma)c2 = mutate(c2, mu, sigma)# Apply Boundsapply_bound(c1, varmin, varmax)apply_bound(c2, varmin, varmax)# Evaluate First Offspringc1.cost = costfunc(c1.position)if c1.cost < bestsol.cost:bestsol = c1.deepcopy()# Evaluate Second Offspringc2.cost = costfunc(c2.position)if c2.cost < bestsol.cost:bestsol = c2.deepcopy()# Add Offsprings to popcpopc.append(c1)popc.append(c2)# Merge, Sort and Selectpop += popcpop = sorted(pop, key=lambda x: x.cost) #按照目标函数值从小到大排序pop = pop[0:npop]# Store Best Costbestcost[it] = bestsol.cost# Show Iteration Informationprint("Iteration {}: Best Cost = {}".format(it, bestcost[it]))# Outputout = structure()out.pop = popout.bestsol = bestsolout.bestcost = bestcostreturn outdef crossover(p1, p2, gamma=0.1):c1 = p1.deepcopy()c2 = p1.deepcopy()alpha = np.random.uniform(-gamma, 1+gamma, *c1.position.shape)c1.position = alpha*p1.position + (1-alpha)*p2.positionc2.position = alpha*p2.position + (1-alpha)*p1.positionreturn c1, c2def mutate(x, mu, sigma):y = x.deepcopy()flag = np.random.rand(*x.position.shape) <= muind = np.argwhere(flag)y.position[ind] += sigma*np.random.randn(*ind.shape)return ydef apply_bound(x, varmin, varmax):x.position = np.maximum(x.position, varmin)x.position = np.minimum(x.position, varmax)def roulette_wheel_selection(p):c = np.cumsum(p)r = sum(p)*np.random.rand()ind = np.argwhere(r <= c)return ind[0][0]
function [f] = Sphere(x)
f= sum(x.^2);
end
app.py代码如下:
import numpy as np
import matplotlib.pyplot as plt
from ypstruct import structure
import ga# Sphere Test Function
def sphere(x):return sum(x**2)# Problem Definition
problem = structure()
problem.costfunc = sphere
problem.nvar = 5
problem.varmin = [-100, -100, -100, -100, -100]
problem.varmax = [ 100, 100, 100, 100, 100]# GA Parameters
params = structure()
params.maxit = 500
params.npop = 5
params.beta = 1
params.pc = 1
params.gamma = 0.1
params.mu = 0.01
params.sigma = 0.1# Run GA
out = ga.run(problem, params)# Results
plt.plot(out.bestcost)
print(out.bestsol)
# plt.semilogy(out.bestcost)
plt.xlim(0, params.maxit)
plt.xlabel('Iterations')
plt.ylabel('Best Cost')
plt.title('Genetic Algorithm (GA)')
plt.grid(True)
plt.show()
求解结果如下:
最优解:struct({'position': array([-1.32382941e-04, -2.07103364e-05, -1.31247597e-03, 1.21645087e-04,2.23626596e-08]), 'cost': 1.7553448711624725e-06})
▎参考
[1]Mostapha Kalami Heris, Practical Genetic Algorithms in Python and MATLAB – Video Tutorial (URL:
https://yarpiz.com/632/ypga191215-practical-genetic-algorithms-in-python-and-matlab), Yarpiz, 2020.
咱们下期再见
▎近期你可能错过了的好文章:
新书上架 | 《MATLAB智能优化算法:从写代码到算法思想》
优化算法 | 灰狼优化算法(文末有福利)
优化算法 | 鲸鱼优化算法
遗传算法(GA)求解带时间窗的车辆路径(VRPTW)问题MATLAB代码
粒子群优化算法(PSO)求解带时间窗的车辆路径问题(VRPTW)MATLAB代码
优化算法 | 遗传算法(附Python代码)相关推荐
- python重点知识归纳_一文了解机器学习知识点及其算法(附python代码)
一文了解机器学习知识点及其算法(附python代码) 来源:数据城堡 时间:2016-09-09 14:05:50 作者: 机器学习发展到现在,已经形成较为完善的知识体系,同时大量的数据科学家的研究成 ...
- 优化算法 | 人工蜂群算法(附Python代码)
hello,大家好.各位可点击左下方阅读原文,访问公众号官方店铺.谨防上当受骗,感谢各位支持! 今天为各位更新人工蜂群算法(Artificial Bee Colony,ABC)的Python代码,之前 ...
- MATLAB实战系列(十一)-多种群遗传算法的函数优化算法(附MATLAB代码)
前言: 本篇博文参考,智能优化算法书籍<MATLAB智能算法30个案例分析(第2版)>,今天要与大家分享的智能算法是多种群遗传算法. 本地MATLAB环境部署 因为后面要介绍的多种群遗传算 ...
- 讲清迪杰斯特拉(DIJKSTRA)算法,附python代码
最近有个同事问我迪杰斯特拉算法,以前都是直接用,三个循环体直接一套就出来,具体逻辑懒得去理解,这次被问到,就花了点时间理了理算法的底层逻辑. --------- 迪杰斯特拉算法是搜索出所有点到起点的最 ...
- python协同过滤可以预测吗_基于用户的协同过滤推荐算法原理-附python代码实现...
在推荐系统众多方法中,基于用户的协同过滤推荐算法是最早诞生的,原理也较为简单.该算法1992年提出并用于邮件过滤系统,两年后1994年被 GroupLens 用于新闻过滤.一直到2000年,该算法都是 ...
- 【实战案例】分享6种常用的信用卡欺诈检测算法(附 Python 代码)
大家好,本文旨在使用 XGBoost.随机森林.KNN.逻辑回归.SVM 和决策树解决信用卡潜在欺诈的分类问题,内容较长,建议收藏.点赞. 文章目录 技术提升 案例简介 导入相关模块 导入数据 探索性 ...
- 一文详解8种异常检测算法(附Python代码)
文章目录 一.异常检测简介 1.1 异常检测适用的场景 1.2 异常检测存在的挑战 二.异常检测方法 2.1 基于聚类的方法 2.2 基于统计的方法 2.3 基于深度的方法 2.4 基于分类模型 2. ...
- 10种机器学习算法(附Python代码)
sklearn python API LinearRegression from sklearn.linear_model import LinearRegression # 线性回归 # modul ...
- 阿基米德优化算法AOA附Matlab代码
✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信.
- 基于TextRank算法的文本摘要(附Python代码)
基于TextRank算法的文本摘要(附Python代码): https://www.jiqizhixin.com/articles/2018-12-28-18
最新文章
- monkey测试===ios-monkey测试工具
- 两个栈来实现一个队列的C++代码
- Android 系统(205)---MTK平台分区回读
- 广东计算机学会 信息学省初赛,全国青少年信息学奥林匹克竞赛联赛-广东计算机学会...
- PAT 乙级 1034. 有理数四则运算(20) Java版
- MySQL8.0二进制免编译部署过程详解(二)
- yolo如何降低loss_YOLO训练中的问题与怀疑
- Pytorch有什么节省内存(显存)的小技巧?
- Quick_Cocos2d_x V3.3 Protobuf Android
- 从苏宁电器到卡巴斯基第34篇:番外篇——晒一晒病毒分析师的桌面(上)
- 谷歌联网断网都可以玩的恐龙小游戏(内容有不死加速挂)
- android dex2oat 编译,dex2oat代码阅读笔记
- cwRsync文件同步
- 51物联卡:物联卡支持5G吗?怎么购买5G物联卡
- SpotMicro 12自由度四足机器人制作(两套方案)
- vue-router 详解
- 数学建模--正态分布均值的假设检验
- linux下重要目录的作用
- cocos creator麻将教程系列(八)—— 达达麻将语音聊天源码分析
- Lua和C/C++交互的注意点_艾孜尔江撰
热门文章
- cl.nd77.pw index.php,Loop in template
- 腾讯QQ协议分析文档
- 手把手教你sql触发器的使用
- 国内最大的两个网盘(rayfile和纳米盘)神秘资源下载搜索技巧
- 简单好用的桌面隐藏工具:Desktop Curtain for Mac
- 阿里云服务器搭建私人云盘
- opengl魔方文档_基于OpenGL的3D旋转魔方的实现.doc
- 苹果uwb_苹果发布会前瞻:iPhone12还得再等等 UWB或成最大惊喜
- 图像傅里叶变换的MATLAB实现
- C++ 五大链表排序(冒泡、插入、选择、归并、快排)