优化算法——遗传算法

优化算法——遗传算法与遗传算法的第一次接触遗传算法的基本概念基本定义遗传算法的基本流程遗传算法过程中的具体操作参数的编码二进制编码 Gray 编码实数编码有序编码初始群体的设定适应度函数的计算遗传操作设计选择 selection 交叉 crossover 变异 mutation 控制参数的设定求解优化问题的实例问题描述问题分析算法设计个体编码适应值函数选择策略杂交算子变异算子参数设置

与遗传算法的第一次接触

基本定义

  1. 个体(individual):在遗传学中表示的是基因编码,在优化问题中指的是每一个解。
  2. 适应值(fitness):评价个体好坏的标准,在优化问题中指的是优化函数。
  3. 群体(population): 由个体组成的集合
  4. 遗传操作:遗传操作的主要目的是用于在当前的群体中产生新的群体,主要的操作包括:选择(selection)、交叉(crossover)、变异(mutation)。

遗传算法的基本流程

遗传算法过程中的具体操作

参数的编码

遗传算法中的参数编码的方式主要有:1、二进制编码。2、Gray编码。3、实数编码。4、有序编码。

二进制编码

二进制编码是最原始的编码方式,遗传算法最初是在二进制编码的方式下进行运算的。二进制编码也是遗传算法中使用最为直接的运算编码方式。二进制编码是指利用 0 0 0 1 1 1对问题的解向量进行编码。例如,对于如下的优化问题:
m a x    f ( x 1 , x 2 ) = 21.5 + x 1 s i n ( 4 π x 1 ) + x 2 s i n ( 20 π x 2 ) max\; f\left ( x_1,x_2 \right )=21.5+x_1sin\left ( 4\pi x_1 \right )+x_2sin\left ( 20\pi x_2 \right ) maxf(x1,x2)=21.5+x1sin(4πx1)+x2sin(20πx2)
− 3.0 ≤ x 1 ≤ 12.1 ; 4.1 ≤ x 2 ≤ 5.8 -3.0\leq x_1\leq 12.1;4.1\leq x_2\leq 5.8 3.0x112.1;4.1x25.8
其三维图像如下图所示:
这里写图片描述
在对这样的优化问题进行二进制编码的过程中,是将问题的可能解编码为二进制位串,例如问题的可能解为实数对 ( x 1 , x 2 ) \left ( x_1,x_2 \right ) (x1,x2),首先必须将 x 1 x_1 x1 x 2 x_2 x2分别使用二进制位串表示,然后将他们的二进制位串组合在一起。对于每一个变量的二进制位串的长度取决于变量的定义域所要求的精度。












对于上述的优化问题,假设精度为小数点后 4 4 4位,则:
( 12.1 − ( − 3.0 ) ) × 10000 = \left ( 12.1-\left ( -3.0 \right ) \right )\times 10000= (12.1(3.0))×10000=151000
2 17 − 1 < ≤ 2 18 − 1 2^{17}-1<\leq 2^{18}-1 2171<1510002181
那么表示变量 x 1 x_1 x1的二进制位串的长度为 l 1 = 18 l_1=18 l1=18
同理,对于变量 x 2 x_2 x2
( 5.8 − 4.1 ) × 10000 = 17000 \left ( 5.8-4.1 \right )\times 10000= 17000 (5.84.1)×10000=17000
2 14 − 1 < 17000 ≤ 2 15 − 1 2^{14}-1<17000\leq 2^{15}-1 2141<170002151
表示变量 x 2 x_2 x2的二进制位串的长度为 l 2 − 15 l_2-15 l215
此时,个体可以表示为:
这里写图片描述
其中,前 18 18 18位表示的是 x 1 x_1 x1,后 15 15 15位表示的是 x 2 x_2 x2




















Gray编码

这种编码方式在求解优化问题时,本人基本上没做过任何研究。

实数编码

在二进制编码的过程中存在这样的一个问题,即在计算适应值的时候需要将二进制编码转换成十进制的编码进行运算,这样,很显然会想到能否直接使用十进制编码直接进行运算,如上例中的 ( x 1 , x 2 ) \left ( x_1,x_2 \right ) (x1,x2)这样的编码方式。

有序编码

有序编码主要使用在TSP问题中,在本文中主要涉及二进制编码和实数编码

初始群体的设定

在解决了个体的编码问题后,需要解决的问题是如何利用个体表示群体。在上述中,我们知道,群体是个体的集合。假设初始群体的大小为 N = 20 N=20 N=20。对于二进制编码方式与实数编码方式产生 20 20 20个初始解。如:
v 1 = ( 000 ) v_1=\left ( 000 \right ) v1=(010001001011010000111110010100010)
对应的实数编码的方式则为:
v 1 = ( 1.052426 , 5. ) v_1=\left ( 1.052426,5. \right ) v1=(1.052426,5.755330)
对于二进制编码则是随机初始化 20 20 20组这样的初始解,每组初始解随机初始化 33 33 33位的 0 − 1 0-1 01编码。而对于实数编码方式,则是在区间上随机初始化 20 20 20组初始解。








适应度函数的计算

适应度函数的目的是评价个体的好坏,如上面的优化问题中,即为最终的优化目标函数。对于二进制编码,则需要先将二进制编码转换成实数编码,再进行适应值函数的计算,对于实数编码方式,则直接进行适应值函数的计算。

遗传操作设计

遗传操作主要包括:选择(selection)、交叉(crossover)、变异(mutation),遗传操作的主要目的是从当前的群体中产生新的群体,这样便能使得产生新的更优的个体。

选择(selection)

交叉(crossover)

变异(mutation)

控制参数的设定

控制参数主要包括种群的规模 N N N,演化代数 T T T,杂交概率 p c p_c pc,变异概率 p m p_m pm等等。


在实现遗传算法时,一个常用的方法是将到当前代为止演化的最好个体单独存放起来,在遗传算法结束后,将演化过程中发现的最好个体作为问题的最优解或近似最优解。


求解优化问题的实例

问题描述

m i n    f ( x 1 , x 2 , ⋯   , x n ) = − 20 ⋅ e x p ( − 0.2 1 n ∑ i = 1 n x i 2 ) − e x p ( 1 n ∑ i = 1 n c o s ( 2 π ⋅ x i ) ) + 20 + e min\; f\left ( x_1,x_2,\cdots ,x_n \right )=-20\cdot exp\left ( -0.2\sqrt{\frac{1}{n}\sum_{i=1}^{n}x^2_i} \right )-exp\left ( \frac{1}{n}\sum_{i=1}^{n}cos\left ( 2\pi \cdot x_i \right ) \right )+20+e minf(x1,x2,,xn)=20exp(0.2n1i=1nxi2
)
exp(n1i=1ncos(2πxi))+20+e

其中, − 30 ≤ x i ≤ 30 , i = 1 , 2 , ⋯   , n ; e = 2.71828 -30\leq x_i\leq 30,i=1,2,\cdots ,n;e=2.71828 30xi30,i=1,2,,n;e=2.71828

问题分析

这是一道不带约束条件的函数优化的问题,既可以采用二进制编码方式,也可以采用十进制的编码方式,在本题的解决过程中,采用十进制的编码方式。首先通过Matlab得到的函数图像大致如下,从图像中可以观察到当 n = 2 n=2 n=2时,我们可以在 ( 0 , 0 ) (0,0) (0,0)附近取得函数的最小值。
这里写图片描述

算法设计

基于以上的分析,当 n = 2 n=2 n=2时,以下分别从个体的编码、适应值函数、选择策略、杂交算子、变异算子、参数设置、初始化以及终止条件这八个方面对程序的设计作简要的描述:

个体编码

采用实数向量编码,每一个个体是一实数对 ( x 1 , x 2 ) \left ( x_1,x_2 \right ) (x1,x2)

适应值函数

该优化问题是一个极小化问题,可对目标函数作简单变换,同时考虑到在选择策略时选择的是轮盘赌的选择策略,轮盘赌的选择策略有一个要求就是个体的适应值要为正数,因此,可以作如下的变换: F = 30 − f ( x 1 , x 2 ) F=30-f\left ( x_1,x_2 \right ) F=30f(x1,x2),这里的 30 30 30是取的一个上界。这样,既保证了变换后的适应值函数式中为正,而且我们可以将极小化问题转换成一个极大值问题考虑。

选择策略

采用轮盘赌的选择策略,因为在计算适应值时已经作了处理,即适应值始终为正,这样就可以使用轮盘赌的选择策略。轮盘赌的选择策略是一种基于适应值比例的选择策略,适应值越大被选择到下一代的概率也会越大。

杂交算子

采用整体算术杂交,即给定两个父体,产生一个随机数,经杂交后得到两个后代个体, v 1 = ( x 1 , x 2 ) v_1=\left ( x_1,x_2 \right ) v1=(x1,x2) v 2 = ( y 1 , y 2 ) v_2=\left ( y_1,y_2 \right ) v2=(y1,y2),产生一个随机数 α ∈ [ 0 , 1 ] \alpha \in \left [ 0,1 \right ] α[0,1],经杂交后得到两个后代个体: v 1 ′ = ( α x 1 + ( 1 − α ) y 1 , α x 2 + ( 1 − α ) y 2 ) {v}’_1=\left ( \alpha x_1+\left ( 1-\alpha \right )y_1,\alpha x_2+\left ( 1-\alpha \right )y_2 \right ) v1=(αx1+(1α)y1,αx2+(1α)y2) v 2 ′ = ( α y 1 + ( 1 − α ) x 1 , α y 2 + ( 1 − α ) x 2 ) {v}’_2=\left ( \alpha y_1+\left ( 1-\alpha \right )x_1,\alpha y_2+\left ( 1-\alpha \right )x_2 \right ) v2=(αy1+(1α)x1,αy2+(1α)x2)

变异算子

采用非均匀变异,即对于要变异的个体 x = ( x 1 , x 2 ) x=\left ( x_1,x_2 \right ) x=(x1,x2),随机产生整数 k ∈ { 1 , 2 } k\in \left \{ 1,2 \right \} k{
1,2}
,例如 k = 1 k=1 k=1,然后产生后代 x ′ = ( x 1 ′ , x 2 ) {x}’=\left ( {x}’_1,x_2 \right ) x=(x1,x2),其中
x 1 ′ = { x 1 + Δ ( t , u 1 − x 1 )  if  R a n d o m ( 2 ) = 0 x 1 − Δ ( t , x 1 − l 1 )  if  R a n d o m ( 2 ) = 1 {x}’_1=\begin{cases} x_1+\Delta \left ( t,u_1-x_1 \right ) & \text{ if } Random(2)= 0\\ x_1-\Delta \left ( t,x_1-l_1 \right ) & \text{ if } Random(2)= 1 \end{cases} x1={
x1+Δ(t,u1x1)x1Δ(t,x1l1) if Random(2)=0 if Random(2)=1


参数设置

  • 种群规模 N = 100 N=100 N=100
  • 个体长度 S i z e = 2 Size=2 Size=2
  • 演化代数 T = 3000 T=3000 T=3000
  • 杂交概率 p c = 0.7 p_c=0.7 pc=0.7
  • 变异概率 p m = 0.1 p_m=0.1 pm=0.1
  • 函数上界 U p p = 30.0 Upp = 30.0 Upp=30.0

初始化

在区间内随机初始化种群的个体,并置个体的适应值,适应值之和以及相对适应值比例为 0 0 0

终止条件

采用代数作为终止条件,当算法运行到指定的最大代数时,程序停止。

实验代码

#include 
      
        #include 
       
         #include 
        
          #include 
         
           #include 
          
            using namespace std; const int COLONY_SIZE=100; //个体数目 const int Size=2;//个体的长度 const int Generation=3000;//代数 const double OVER=0.7;//杂交的概率 const double MUTATE=0.1;//变异的概率 const double UPPER=30.0;//函数的上界 struct Indival { double code[Size]; double fitness; double cfitness; double rfitness; }Group[COLONY_SIZE]; Indival newGroup[COLONY_SIZE]; Indival bestChrom;//记录最好的个体 int GenNum=0; double random(double, double); void initiate(); void calvalue(); void select(); void crossOver(); void xOver(int,int); void mutate(); double delta(int,double,double,double); void sort(); /*主函数*/ int main() { ofstream output; srand((unsigned)time(NULL)); initiate(); calvalue(); output.open("data.txt"); while(GenNum<=Generation) { GenNum++; select(); crossOver(); mutate(); calvalue(); sort(); if (bestChrom.fitness 
           
             =Group[j-1].cfitness&&p 
             
            
           
          
         
        
      

最终结果

这里写图片描述

我在这里简单介绍了遗传算法,遗传算法是一个研究较多的算法,还有利用遗传算法求解组合优化问题,带约束的优化问题,还有一些遗传算法的理论知识,如模式定理,积木块假设,在这里就不一一列举了,希望我的博文对你的学习有帮助,也欢迎转载,谢谢,有不到位的地方还请指出。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216086.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午12:35
下一篇 2026年3月18日 下午12:35


相关推荐

  • pci设备驱动

    pci设备驱动原文地址 https www cnblogs com xiaoya901109 archive 2012 12 14 2818057 html 一 初始化设备模块 nbsp nbsp 当 Linux 内核启动并完成对所有 PCI 设备进行扫描 登录和分配资源等初始化操作的同时 会建立起系统中所有 PCI 设备的拓扑结构 此后当 PCI 驱动程序需要对设备进行初始化时 一般都会调用如下的代码 staticint init

    2026年3月26日
    1
  • linux赋权限777

    linux赋权限777sudochmod R0777 www 路径

    2026年3月26日
    1
  • java面试题及答案2020 大汇总

    java面试题及答案2020 大汇总java面试题及答案2020java面试题大汇总百度第一篇java面试题及答案2020先点赞后收藏,以后更新及时看文末后续更新答案,持续更新一面2018/9/11来自于牛客网1、手写ArrayList2、手写进制转换算法,求出一个数的二进制数1的个数3、JAVA基础,equals和==4、多线程方式、threadlocal,各种锁,synchronized和lock5、设计模式、spring类加载方式、实例保存在哪、aopioc、反射机制6、类加载器,双亲委派模

    2022年8月25日
    8
  • Pycharm如何修改字体大小、风格及界面风格

    Pycharm如何修改字体大小、风格及界面风格教你如何在 Pycharm 中 修改界面风格 字体大小 字体大小 代码高亮等

    2026年3月27日
    2
  • python random函数

    python random函数调用 random 前要 importrandom 模块 测试 1 random random 生成一个随机的浮点数 在 0 1 之间 2 random sample 从指定的序列或列表中 随机的截取指定长度的片段 测试 1 序列 测试 2 列表 3 random randint 随机生成一个 int 类型的数 可以指

    2026年3月19日
    2
  • Mac下Ant安装「建议收藏」

    Mac下Ant安装「建议收藏」首先进入Ant官网(http://ant.apache.org/bindownload.cgi)下载Ant:(本人的默认下载在/User/xx/Download)正常安装过程:1:sudosh(会提示你输入当前用户的密码)2:cp/User/xx/Download/apache-ant.1.9.4-bin.zip/usr/local(拷贝ant压缩包到/user/local目录下)3:c

    2022年7月25日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号