[基因遗传算法]原理思想和python代码的结合理解之(一) :单变量

news2024/11/14 19:59:06

读《遗传算法的Python实现(通俗易懂)》佳文的思考与笔记整理.


我们拥有一个目标函数 y = 10 ⋅ s i n ( 5 x ) + 7 ⋅ c o s ( 4 x ) y=10 \cdot sin(5x)+7\cdot cos(4x) y=10sin(5x)+7cos(4x)

def aim(x):return 10*np.sin(5*x)+7*np.cos(4*x)

约束范围(这里是定义域): x ∈ [ 0 , 5 ] x \in [0,5] x[0,5]
我们使用基因遗传算法求解 y y y的最大值.


文章目录

    • 一. 基因(DNA)体现在二进制编码
    • 二、个体与种群
    • 三、物竞天择,适者生存
      • A. 计算个体的适应度
      • B. 赌命运,适应度越高生存的几率越大
      • C. 在没交叉没变异之前的情况,举例
    • 四、交叉和突变
      • A. 交叉函数
      • B. 变异函数
    • 五、种群繁衍(循环迭代),适应性越来越强
    • 六、主程序代码
    • 七、使用库scikit-opt解决
      • A. 使用GA解决上面问题
      • B.使用AG解决一个单极点问题

一. 基因(DNA)体现在二进制编码

首先知道十进制(整数)与二进制是一一对应的可转换的关系.我们的基因形式则为二进制数据.

  • bin(2**9) 表示 2 9 = 512 2^9=512 29=512的二进制表达形式为 '0b1000000000',取0b后面的数字,共有10位表示.
  • bin(5)=0b101.整数5可以用二进制101代替.
  • 我们的定义域是一个连续的区间,最优解可能不是整数而是小数.因此我们采用更长的基因(如10个DNA)可以表达更大的整数,然后缩小到 [ 0 , 5 ] [0,5] [0,5]范围内,补充[0,5]内的小数.
  • 因此数据的编码和解码公司可以参考.在这里插入图片描述
  • 在这里(10个DNA的情况下),设计的 decode(解码)函数为
def decode(pop):
   return   pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) *(X_max-X_min)/ float(2**DNA_SIZE-1) +X_min
# DNA_size=10

二、个体与种群

多个基因构成一个个体.
多个个体构成一个种群.
举例假设:种群的数量为4,每个个体🈶️5个基因.则创造随机的初始种群.

pop_size=4
DNA_SIZE=5
pop = np.random.randint(2, size=(pop_size, DNA_SIZE))

pop的输出为(举例,随意random下. )

array([[1, 1, 1, 1, 0],# 物种1的基因
       [0, 0, 0, 0, 0],
       [1, 1, 1, 0, 0],
       [1, 1, 0, 1, 0]])# 物种4的基因

三、物竞天择,适者生存

A. 计算个体的适应度

x x x个体(含多个DNA)–>decode解码为 x ′ x' x–>aim目标函数求的 y y y

# pred=[y1,y2,...,yn] 为pop的目标函数值
def fitnessget(pred):
    return pred + 1e-3 - np.min(pred)

对于目标函数值pred同时去掉最小值np.min(pred),则pred中最小值为0.添加上 1 e − 3 = 0.01 1e-3=0.01 1e3=0.01,防止列表中数据为0,报错.

  • 适应度的计算与目标结果相关
  • 求最大值时,其结果越高则适应度越高
  • 求最小值时,其结果越低则适应度越高

B. 赌命运,适应度越高生存的几率越大

但这并不意味着适应度高,一定会生存下来,因此会存在一定的赌运气生存下来的情况.即是物竞天择的原理.这里的赌运气采用赌轮盘的方法.

def select(pop, fitness):           
    # print(abs(fitness))
    # print(fitness.sum())
    idx = np.random.choice(np.arange(pop_size), size=pop_size, replace=True,p=fitness/fitness.sum())
    # print(idx)
    return pop[idx]

C. 在没交叉没变异之前的情况,举例

依旧以 种群为4,基因为5 为例.
在这里插入图片描述
在这里插入图片描述

  • 1号基因为1次,2号基因为2次,3号基因消失了,4号基因为1次.
  • 个体总量没有发生变化,但适应度高的个体被更多的保留了下来
  • 迭代下去,我们就会得到所谓的纯种个体组成的种群
  • 想要适应度最高的而不是纯种个体中最优的个体

四、交叉和突变

A. 交叉函数

def change(parent, pop):
    if np.random.rand() < PC:    #交叉
        i_ = np.random.randint(0, pop_size, size=1)
        # print(parent)
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool)
        # print(np.where(cross_points==True))
        # print(cross_points)
        parent[cross_points] = pop[i_, cross_points]
        # print(parent)
    return parent 
  • 交叉概率: PC=0.6(假设)
  • 交叉点:个体10个基因(DNA),随机(在每个基因上)是否生成交叉点,结果为:cross_points
  • 在种群中,为parent 选择交叉的另一个pop[i_]
  • 将pop[i_]上的交叉的索引cross-points赋值给parent的cross_points的索引上

B. 变异函数

def variation(child,pm):                  #变异
    for point in range(DNA_SIZE):
        if np.random.rand() < PM:
            child[point] = 1 if child[point] == 0 else 0
    # print(child)
    return child
  • 变异概率:PM=0.1(假设)
  • 个体的每个基因,都有PM的变异概率
  • 变异:0–>1 或1–>0

五、种群繁衍(循环迭代),适应性越来越强

  1. 定义初始种群(查看二): pop = np.random.randint(2, size=(pop_size, DNA_SIZE))
  2. 繁衍生息(进行循环)

A: 适者生存,计算目标值和适应度

  1. 种群pop—解码–>X_value
  2. 获取目标值–> F_values
  3. 获得适应度–> fitness

B:记录目标值最好的物种及其DNA

  1. i=0(初次循环时), 记录最好的物种为Max其基因为max_DNA
  2. 更新最好的物种及其基因
  3. 每迭代10次, 输出当前的最好的物种以及基因,查看

C: 物竞天择

  1. 赌命运生存,(select函数)
  2. 种群复制副本pop_copy用于交叉配对的

D: 交叉产生新子,新子有概率变异
每个来自于pop的物种child

  1. pop_copy中的随机一个交叉(change函数)产生孩子child
  2. 孩子child可能会产生变异(variation函数)
  1. 迭代结束后,输出目标值最好的物种及其DNA

六、主程序代码

定义变量

# 定义全局变量
pop_size = 10  # 种群数量
PC=0.6 # 交叉概率
PM=0.01 #变异概率
X_max=5    #最大值 
X_min=0     #最小值,与x_max共同构成x的定义域范围
DNA_SIZE=10  #DNA长度与保留位数有关,2**10 当前保留3位小数点
N_GENERATIONS=1000

主程序

pop = np.random.randint(2, size=(pop_size, DNA_SIZE))


# print(pop)
for i in range(N_GENERATIONS):
    #解码
    # print(pop)
    X_value= decode(pop)
    
    #获取目标函数值
    F_values = aim(X_value)
    
    #获取适应值
    fitness = fitnessget(F_values)
    # print(fitness)
    if(i==0):
        Max=np.max(F_values)
        max_DNA = pop[np.argmax(F_values), :]
        
    if(Max<np.max(F_values)):
        Max=np.max(F_values)
        max_DNA=pop[np.argmax(F_values), :]
        
    if (i % 10 == 0):
        print("Most fitted value and X: \n",
              np.max(F_values), decode(pop[np.argmax(F_values), :]))
    #选择
    pop = select(pop,fitness)
    # print(pop)
    pop_copy = pop.copy()
    # print(pop_copy)
    for parent in pop:
        # print(parent)
        child = change(parent,pop_copy)
        child = variation(child,PM)
        # print(child)
        parent[:] = child
print("目标函数最大值为:",Max)
print("其DNA值为:",max_DNA)
print("其X值为:",decode(max_DNA))

结果展示
运行一:

i: 0 Most fitted value and X: 
 7.384343376804747 2.7126099706744866
i: 10 Most fitted value and X: 
 13.372066639693031 0.21994134897360704
i: 20 Most fitted value and X: 
 15.560237189300736 1.4809384164222874
i: 30 Most fitted value and X: 
 15.560237189300736 1.4809384164222874
i: 40 Most fitted value and X: 
 16.975412816482176 1.5591397849462365
i: 50 Most fitted value and X: 
 16.975412816482176 1.5591397849462365
----------
目标函数最大值为: 16.975412816482176
其DNA值为: [0 1 0 0 1 1 1 1 1 1]
其X值为: 1.5591397849462365

运行二:

i: 0 Most fitted value and X: 
 11.538584764492317 1.7497556207233627
i: 10 Most fitted value and X: 
 13.37062486072224 2.9227761485826003
i: 20 Most fitted value and X: 
 13.374183016652838 2.9178885630498534
i: 30 Most fitted value and X: 
 13.374183016652838 2.9178885630498534
i: 40 Most fitted value and X: 
 13.374183016652838 2.9178885630498534
i: 50 Most fitted value and X: 
 13.374183016652838 2.9178885630498534
 ---------
 i: 240 Most fitted value and X: 
 13.374183016652838 2.9178885630498534
i: 250 Most fitted value and X: 
 15.364515002303772 1.6666666666666667
i: 260 Most fitted value and X: 
 16.943525799534186 1.5884652981427174
i: 270 Most fitted value and X: 
 16.999359344557767 1.5689149560117301
 --------
 i: 470 Most fitted value and X: 
 16.999359344557767 1.5689149560117301
i: 480 Most fitted value and X: 
 16.943525799534186 1.5884652981427174
i: 490 Most fitted value and X: 
 16.970440089469758 1.5835777126099706
i: 500 Most fitted value and X: 
 16.970440089469758 1.5835777126099706
i: 510 Most fitted value and X: 
 16.991707506136905 1.5640273704789833
i: 520 Most fitted value and X: 
 16.999359344557767 1.5689149560117301
 -------
 i: 590 Most fitted value and X: 
 16.999359344557767 1.5689149560117301
i: 600 Most fitted value and X: 
 16.998364271158337 1.573802541544477
 ----------
 i: 990 Most fitted value and X: 
 16.998364271158337 1.573802541544477
目标函数最大值为: 16.999359344557767
其DNA值为: [0 1 0 1 0 0 0 0 0 1]
其X值为: 1.5689149560117301

总结:

  • 第一次运行到50次就接近了最优值,而第二次运行了600次接近了最优质.
  • 两次最优解x都近似在1.6附近.最优值y近似在16.99上.可见该方法具有一定的稳定性和准确性.

应用思考:

  1. 这里只有一个变量 x x x,轻松表示其基因.如果存在多个变量 x 1 , x 2 , ⋯   , x n x_1,x_2,\cdots,x_n x1,x2,,xn, 那么其基因如何表示呢?
  2. 这里约束(定义域)非常简单.只有大小的范围限制. 当解决最优规划问题的时候.会存在凸性约束.那么其约束如何表示呢?
  3. 适应度的设计问题.这里可以看出适应度与目标值时直线关系(鞋履 k = 1 k=1 k=1).那么可否根据实际问题,重新设计 适应度的表达式呢?(比如,对数关系)
  4. 每一次,都需要自行编写代码嘛?(这个接下来可以解答)

七、使用库scikit-opt解决

from sko.GA import GA
import pandas as pd
import matplotlib.pyplot as plt

函数讲解

GA(func, n_dim, size_pop=50, max_iter=200, prob_mut=0.001, lb=-1, ub=1, constraint_eq=(), 
constraint_ueq=(), precision=1e-07, early_stop=None)
 |  
 |  genetic algorithm
 |  
 |  Parameters
 |  ----------------
 |  func : function
 |      The func you want to do optimal 优化的目标函数
 |  n_dim : int
 |      number of variables of func目标函数的变量
 |  lb : array_like
 |      The lower bound of every variables of func每个变量的下限
 |  ub : array_like
 |      The upper bound of every variables of func每个变量的上限
 |  constraint_eq : tuple,
 |      equal constraint 等式约束
 |  constraint_ueq : tuple,
 |      unequal constraint不等式约束
 |  precision : array_like
 |      The precision of every variables of func 函数每个变量的精度
 |  size_pop : int
 |      Size of population种群数量
 |  max_iter : int
 |      Max of iter迭代次数
 |  prob_mut : float between 0 and 1
 |      Probability of mutation 突变概率

A. 使用GA解决上面问题

def aim(p):
    x= p[0]
    return -(10*np.sin(5*x)+7*np.cos(4*x))

注意到:

  • 这里的x=p[0],也就是第一个变量的目标函数.如果不加这一行.运行会有广播机制的报错问题.
  • 此外原目标函数为求最大值,而GA的默认时求最小值.因此,则需要加一个负号-
ga = GA(func=aim, n_dim=1, size_pop=10, max_iter=1000, 
lb=0, ub=5, precision=1e-7) 
best_x, best_y = ga.run()

# `GA`是一个class类,因此要先实例化(第一行),然后用`run`函数执行.

x = np.arange(0,5,0.01)
y = (10*np.sin(5*x)+7*np.cos(4*x))
fig,ax=plt.subplots()
ax.plot(x,y)
ax.scatter(best_x,-best_y,marker='*',c="red",s=200)# 红色星号表示求的最优解
plt.show()

结果
运行一:
在这里插入图片描述
运行二:
在这里插入图片描述
运行三:
在这里插入图片描述
总结: 从蓝色曲线中可以看到,具有多个极值点.因此,结果有三种以上了.但是其目标函数值都是比较优秀的.切红色星星都是位于极值点处.可以说算法比较准确了.

B.使用AG解决一个单极点问题

def schaffer(p):
    '''
    This function has plenty of local minimum, with strong shocks
    global minimum at (0,0) with value 0
    该函数具有大量的局部最小值,具有强烈的冲击
    全局最小值为(0,0),值为0
    '''
    x= p[0]
    
    return 5*np.sin(np.log(x))
   
from sko.GA import GA
ga = GA(func=schaffer, n_dim=1, size_pop=100, max_iter=800, 
lb=0, ub=10, precision=1e-7)
best_x, best_y = ga.run()
print('best_x:', best_x, '\n', 'best_y:', best_y)
x = np.arange(0,10,0.01)
y = 5*np.sin(np.log(x))
fig,ax=plt.subplots()
ax.plot(x,y)
ax.scatter(best_x,best_y,marker='*',c="red",s=200)# 红色星号表示求的最优解
plt.show()

结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何选择分度带(中央子午线)

如何选择分度带(中央子午线) 发布时间&#xff1a;2018-01-17 版权&#xff1a; 同步视频教程&#xff1a;如何选择中央子午线或者分度带 播放 什么是中央子午线&#xff1f; 什么是分度带? 【百度百科】 第一步&#xff1a;查看你所下载(或者要套合的范围)的图像的经纬…

盘点| 爆款小游戏的开发引擎

微信推出小游戏已有4年&#xff0c;期间不断涌现爆款。作为可以不用下载安装直接在线玩的小程序游戏&#xff0c;小游戏渐渐成为不少人的心头好。今天就来盘点一下那些爆款小游戏用到的游戏开发引擎&#xff1a; 一、Cocos 必须得把Cocos放在第一个讲&#xff0c;毕竟近期的羊了…

计量经济学

计量经济学 复习题 题型&#xff1a;选择2*10&#xff1b;填空2*10&#xff1b;名词解释4*5&#xff1b;综合题10*4 一 选择填空考点 1. 截面数据&#xff0c;时间序列&#xff0c;面板数据定义。P12/1.3.3 截面数据&#xff1a;同一时间&#xff08;时期或时点&#xff09;某个…

艾美捷胆固醇肉豆蔻酸酯说明书和相关研究

艾美捷胆固醇肉豆蔻酸酯以结晶固体形式提供。储备溶液可以通过将胆甾醇肉豆蔻酸酯溶解在所选溶剂中来制备。肉豆蔻酸胆甾醇可溶于有机溶剂氯丨仿&#xff0c;应使用惰性气体吹扫&#xff0c;浓度约为10mg/ml。 艾美捷胆固醇肉豆蔻酸酯基本参数&#xff1a; CAS#&#xff1a;19…

vue中使用图像编辑器tui-image-editor(一)

vue中使用图像编辑器tui-image-editor(一) 场景&#xff1a;需要对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等。 效果-图1 1、基本介绍 官网&#xff1a;https://ui.toast.com/tui-image-editor 官方GitHub地址&#xff1a;https://github.com/nhn/tui.image-edito…

数据库设计

概述 数据库设计是一项十分复杂的操作&#xff0c;首先需要理清数据之间的关系&#xff0c;绘制ER图&#xff0c;接着根据ER图设计Relation Schema&#xff0c;最后添加字段属性和索引生成数据表。一个好的ER图是一个数据库的基础。 数据库设计的好坏中最重要的一项指标就是重…

完整版在xcode打测试专用ipa包流程​

前言&#xff1a;有时候&#xff0c;想要把自己的程序运行在别人的iphone手机上&#xff0c;但又不能通过本地真机调试的方法安装&#xff0c;这个时候我们就要打一个测试专用的ipa包给远方的测试小伙伴们测试。​ 步骤&#xff1a;​ 首先希望你的发布证书已经安装好了。​ 1.…

分布式文件存储系统FastDFS[2]-上传和下载文件工具类

一、文件上传流程 1 时序图 2 流程说明 客户端访问Tracker Tracker 返回Storage的ip和端口 客户端直接访问Storage&#xff0c;把文件内容和元数据发送过去。 Storage返回文件存储id。包含了组名和文件名 1 添加依赖 <dependencies><dependency><groupId&g…

基于jsp+mysql+ssm峰值预警停车场管理系统-计算机毕业设计

项目介绍 随着城市建设与经济的不断发展,城市车辆的数量也不断增涨,为解决停车问题修建停车场。基于经营、安全、管理等多角度的考虑&#xff0c;希望在目前传统的大型车库管理系统中有机地结合车牌识别技术&#xff0c;以求得日后在停车库运营时更安全、管理上更细致、经营中…

13个小众有趣的网站,只有程序员才看得懂

欢迎来到程序员的世界&#xff0c;分享一些关于程序员的小众网站&#xff0c;不仅干货满满的实用类网站&#xff0c;也有一些有趣的娱乐网站&#xff0c;有些网站只有程序员才看得懂。1、程序员音乐 地址&#xff1a;https://musicforprogramming.net/ 一个仿代码样式的背景音乐…

使用JAR签名进行代码签名

JavaArchive(JAR)包格式可用于打包Java应用程序和库。 签名的JAR文件可以选择包含来自TSA时间戳响应&#xff0c;使用RFC#3161格式。 添加JAR签名者添加JAR签名者的链接&#xff0c;SignServer中的JAR签名器称为JArchiveSigner。 要配置JArchiveSigner&#xff0c;请按照以下…

[附源码]计算机毕业设计农产品销售网站Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

用R语言模拟M / M / 1随机服务排队系统

本文中我在R中构造一个简单的M / M / 1队列的离散事件模拟 。最近我们被客户要求撰写关于随机服务的研究报告&#xff0c;包括一些图形和统计输出。 模拟变量 像往常一样&#xff0c;我们从模拟及其检测所需的变量 开始。 t.end <- 10^5 # 模拟的持续时间 t.clock <- 0…

【OpenCV-Python】教程:4-3 Shi-Tomasi 角点检测

OpenCV Python Shi-Tomasi 角点检测器 【目标】 Shi-Tomasi 角点检测器cv2.goodFeaturesToTrack 【理论】 上一个章节中学习了Harris角点&#xff0c;J. Shi and C. Tomasi 做了一些修改&#xff0c;Good Features to Track显示了比Harris角点更好的效果。 Harris 角点检测…

私人定制AI绘画——快速finetune stable diffusion教程

最近AI绘图非常火&#xff0c;只需要输入文本就能得到令人惊艳的图。 举个例子&#xff0c;输入 “very complex hyper-maximalist overdetailed cinematic tribal darkfantasy closeup portrait of a malignant beautiful young dragon queen goddess megan fox with long bl…

springcloud之Eureka

idea项目创建 1.创建一个project&#xff0c;然后把src目录删掉 2.修改pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

java+springboot的社区维修平台

JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 系统结构图&#xff0c;如图4-3所示。 图4-3 系统结构图管 效果图 目 录 第一…

小迪-day15(Oracle,MongoDB、access、msSQL、postgresql注入)

1、sqlmap使用 基本操作笔记&#xff1a;-u #注入点 -f #指纹判别数据库类型 -b #获取数据库版本信息 -p #指定可测试的参数(?page1&id2 -p "page,id") -D "" #指定数据库名 -T "" #指定表名 -C "" #指定字段 -s &q…

[附源码]Python计算机毕业设计Django校刊投稿系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

项目经理如何做好跨部门沟通?

在项目管理中&#xff0c;计划不明确&#xff0c;职责定义不清晰&#xff0c;会造成沟通不畅&#xff0c;互相推诿的情况&#xff0c; 也会遇到跨部门沟通&#xff0c;就是相互相对独立的部门之间的沟通协调。这也让项目经理苦不堪言。 1、明确目标&#xff0c;计划制定 制…