QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5974|回复: 0
打印 上一主题 下一主题

python实现的遗传算法实例(一)

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-5-9 14:48 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    python实现的遗传算法实例(一)8 @! J$ F3 b3 x& c

    2 `, \) I- N( l! i一、遗传算法介绍# ~, g, e2 S. K1 A' _9 }' Z6 W. B
    . ^) d% Q( C- |7 J" @9 t' H: u
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。1 v+ c! q: {+ z) D
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10- s! W1 E3 ~3 N/ t5 w- G3 E
    3 `, w0 }$ V) R& D6 [' ]
    1、将自变量x进行编码+ h0 U0 U  v) ?1 s. _( T  @7 _' v- N

    8 `2 n/ \; M( v8 A0 l      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    0 O( j! q$ Z( o+ S) x
    , X# \9 z% U* E2 S# z! T+ A! W2、计算目标函数值$ E9 |6 \  }9 s  c- g1 \
    0 u* v$ Q$ S' @# m( Q. I" W0 w
          根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    ; `1 o% Z, \* h6 t: s5 C- v1 v4 T/ R
    3、适应度函数
    * m) w1 R6 n) S. ?$ D; k+ w2 r  l7 s( I8 s9 s' {
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。% f2 w  f7 u. x( c4 H
    2 o" W# [8 w+ X- `8 b
    4、自然选择+ P; |$ o" c+ I( {8 T
    + D6 M8 @; _3 y% `$ {/ o$ e, _2 w
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:. h, @2 I8 I; l0 O5 ?

    ! n5 e8 s1 e7 {5 N6 C# Y$ f5 A假设种群中共5个个体,适应度函数计算出来的个体适应性列表是fitvalue = [1 ,3, 0, 2, 4] ,totalvalue = 10 , 如果将fitvalue画到圆盘上,值的大小表示在圆盘上的面积。在转动轮盘的过程中,单个模块的面积越大则被选中的概率越大。选择的方法是将fitvalue转化为[1 , 4 ,4 , 6 ,10], fitvalue / totalvalue = [0.1 , 0.4 , 0.4 , 0.6 , 1.0] . 然后产生5个0-1之间的随机数,将随机数从小到大排序,假如是[0.05 , 0.2 , 0.7 , 0.8 ,0.9],则将0号个体、1号个体、4号个体、4号个体、4号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
    ) G) \" X$ k' b. f4 N/ x5 o% F5 g- m: G( `1 e
    5、繁殖& J: x  F/ E3 ]; ~6 G0 w  ?) M- a

    ! r. w& b  ?8 S3 A3 V假设个体a、b的基因是) c/ H4 ]2 \8 y" c0 J9 e" K6 h

    # P' q% K  y" |a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]$ L5 W! S/ `# G2 D) S

    4 m! E' f4 _6 ^' \# T7 n9 l4 k) ^b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    : t$ w) p" o0 i9 t! K5 U# l$ R0 j
    - D& _. _+ v4 }6 `+ R( D, X这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    8 U3 p. P1 [2 g% b. t8 ]! \7 Y, ^  m0 v
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    * b' w; c) i- z6 m, P! U; p7 u$ i& s
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    8 W( P1 E) |' c+ d- e7 |$ G6 c8 t* |4 O' I
    交换后为:
    4 M0 p* ^( R/ ~5 y. v1 c1 n; t/ p& H3 y, r
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    $ b5 _% @( s: K: {* Q+ N( Z, C$ n( w% }1 |: \& \9 ^
    b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    7 G% a8 t; A+ F2 H$ b8 u* N5 m* \% x5 U# u" L  X
    6、突变
    6 S  ?( d8 T6 q) `7 u# ]' i, I0 c& T: V1 m8 e. P0 Y
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
    1 @8 c  {/ n) x+ [6 h# U* P. I( H- X* G2 b
    二、代码
    5 w' i4 {  n! m! b3 r( Jdef b2d(b): #将二进制转化为十进制 x∈[0,10]
    8 j9 f, B2 r, k! ]$ N* v        t = 0
    + n( J$ t- R; l& |3 P- w" O        for j in range(len(b)):
    * Q7 S7 y$ F2 q. `" d* g                t += b[j] * (math.pow(2, j))
      [* h! s5 l! d, R1 {. t* k6 I        t = t * 10 / 1023
    $ ~; R  u4 F9 ?8 o+ w8 X- ~: ~        return t
    : s, D, }! ]' H
    8 G, `6 g3 C  P2 n$ P1 F4 Cpopsize = 50 #种群的大小
    7 J* r. j  C$ K& l: b0 r4 w$ x#用遗传算法求函数最大值:
    - ^9 a: F3 n) g$ P#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    1 s' i! f0 J* _2 ]& N2 Y1 F  G( D
    chromlength = 10 #基因片段的长度; O$ z; F( h# Q" Q  v0 Y& @) o- f
    pc = 0.6 #两个个体交叉的概率
    1 m& z* @+ v( D' n7 U) o" V" Dpm = 0.001; #基因突变的概率" ^9 ~0 ~5 C( z" N( v. l
    results = [[]]
      o2 {( H! h& ?* H0 d7 Qbestindividual = []
    % e4 P1 K$ _1 V2 ?# I+ ^: [bestfit = 0
    3 K' e- U: ~. v- V+ \fitvalue = []( G$ D% \8 r2 h. _. k
    tempop = [[]]$ ]8 M5 F# A% S, J
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    * I, O2 I) o* I1 r0 Gfor i in range(100): #繁殖100代$ A: c3 K; V1 \* e2 w9 K
            objvalue = calobjvalue(pop) #计算目标函数值
    & @0 x! _" @& J        fitvalue = calfitvalue(objvalue); #计算个体的适应值
    . }, e7 Q4 w  T! a) j2 O- w0 y        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    7 M- T* |" d# N8 Y; b  B        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来' {& i4 r* W# g8 ]. Z7 R% ~* h
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体2 S4 q* n6 w: B; Z. D' q& j8 T
            crossover(pop, pc) #交叉繁殖
    1 V1 e( s$ O3 `& U/ p3 a" C1 u6 K, T        mutation(pop, pc) #基因突变' o. u6 |6 e# H3 C, A
           
    5 |5 u. y8 [; T% h
    5 P; P4 S1 K' W4 u1 fresults.sort()        % m% a9 Z0 t/ X
    print(results[-1]) #打印函数最大值和对应的
    0 J, X% B( [. F; s+ y5 @; {# Udef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。" {! F- |4 G6 m& h, u! B% e- K8 u
        fitvalue = []  b9 H( V! @+ u$ e
        temp = 0.0
    % J! @6 S" P$ ^( n. x    Cmin = 0;
    ; E1 u1 _) P0 M) S  Y$ W& |7 Y    for i in range(len(objvalue)):4 C% F6 ]$ P/ D
            if(objvalue + Cmin > 0):
    6 P! Y8 U- V. ^& w9 C1 Y7 R            temp = Cmin + objvalue4 W, J- t2 ?! V5 ?6 I* _) r+ L
            else:
    # w" C: q( s3 |7 c            temp = 0.00 m$ ?, s& \7 u( N  H9 \" w+ j
            fitvalue.append(temp)# V! Y  @1 ^6 H& T$ |& |7 U  h% ~5 A1 C
        return fitvalue
    ) z; W$ ]4 ^' r/ E& z; [" Dimport math3 [  M( s/ o- i0 @! t

    6 F3 \5 M) {! Y- |5 ]def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)1 ]9 b" V* ]9 \: j7 S: Y
        temp = [];
    . O$ T: r" H1 H2 ]. h    for i in range(len(pop)):7 J7 g" @0 {* u% h7 ]1 G# `7 j
            t = 0;
    3 f& f- o5 j, k7 _2 z$ L        for j in range(10):7 c4 u  u8 |6 s+ T$ V2 z9 e
                t += pop[j] * (math.pow(2, j)), O+ w+ O$ s* }: A% ~7 _
            temp.append(t)
    - E' x4 u/ y0 R    return temp
    & i% @5 P" I) ?' x% u2 P+ y% s7 G0 L1 f! x$ q
    def calobjvalue(pop): #计算目标函数值
    " I4 |$ Y/ f$ c    temp1 = [];. d8 g( C6 N# b
        objvalue = [];7 n3 v" K) y/ h2 n; h" T3 e
        temp1 = decodechrom(pop)2 g6 t" A  q) T* h# v
        for i in range(len(temp1)):/ P# m: W6 ^/ u, T: @% D
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)) p4 h0 y1 E( x0 Y! a9 T" i6 @
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))' f6 I4 \$ J5 `  U" @
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    " J3 h  U+ F! ^; \+ `def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体# }4 U4 S/ D; h( r8 q' ]! C
            px = len(pop)6 {+ p( P$ j0 a: \$ x# r
            bestindividual = []
    7 ~$ ]+ {( m# p( [7 A( }+ @+ d        bestfit = fitvalue[0]
    & b7 ~2 i1 ?5 s        for i in range(1,px):; M; F! _* o$ C2 q. \
                    if(fitvalue > bestfit):+ M. e6 }/ C. ^5 |
                            bestfit = fitvalue: o7 A" }; A. b
                            bestindividual = pop2 p4 D$ o/ P8 H1 q! w
            return [bestindividual, bestfit]
    ' k$ E1 T( \5 p# M2 R6 u. Yimport random
    9 B) n& l1 y9 L2 ?  Q* {" j+ r& b7 Z8 [
    def sum(fitvalue):
    , }9 c8 s  b! R& ~. V& M* R    total = 07 U' Q; K! k, u# n: L
        for i in range(len(fitvalue)):" q* M/ Q. b8 u+ B. O7 j: [
            total += fitvalue- F2 K  G, |& |2 T
        return total
    $ M/ g5 b2 P  U+ t& A; ]. i
      s9 h" k* o* r7 n1 fdef cumsum(fitvalue):* a8 G- g- K9 P/ Z: D
        for i in range(len(fitvalue)):
    * A& U9 G. u: l, L+ c1 K2 T        t = 0;. z% C; K1 {. |% z
            j = 0;
    2 H. e  A- ^) {. f2 F2 f; \5 N        while(j <= i):
    , f/ Z8 P; o) V+ n5 l) O' [            t += fitvalue[j]3 D5 k9 T* L  g. U3 U: h
                j = j + 1
    # R' ]( L5 u& l3 [        fitvalue = t;; y' F- `) L+ O  \) j5 v! r
    4 l/ J' ?7 y" z8 u: C
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)
    . e# p# g- J+ u' M        newfitvalue = []4 m- s! p% h0 C
            totalfit = sum(fitvalue)/ a4 C  A3 {* L4 z2 c  Y' V
            for i in range(len(fitvalue)):
    ( J% A. m( \% _4 g% z" Z( g                newfitvalue.append(fitvalue / totalfit)% C3 C* Y* W. [" W
            cumsum(newfitvalue)
    2 y! _: M/ Q/ F) ?$ k( p        ms = [];
    ' ~% G/ Q" w8 ^& {        poplen = len(pop)$ f# q0 y1 o. {( N0 A! c
            for i in range(poplen):* B2 `/ \1 a  \; c! b. j2 n. A
                    ms.append(random.random()) #random float list ms+ v+ C! ]- v2 V$ K
            ms.sort()
    - Z, L( R) g/ q/ R% X: I* {4 f& K& F        fitin = 0$ P' q. W% e) }4 P: e5 y- r' T
            newin = 0
    6 f/ V, M+ u3 n2 {! ?: X2 o        newpop = pop# r. A; J7 _. S' w( K' S+ h
            while newin < poplen:) v! M4 D" X/ Z; }& r
                    if(ms[newin] < newfitvalue[fitin]):
    / S9 M. _( O  b                        newpop[newin] = pop[fitin]7 B$ A4 I7 ]8 q4 Y% _" u
                            newin = newin + 1# a/ P$ v2 I( k" i) Y5 C1 {
                    else:
    ; {  q( x6 Y% \8 d: O& u                        fitin = fitin + 15 C8 c( K, e' X0 }) I
            pop = newpop; \1 }: O7 C8 I& h8 k& o
    import random
    * ~( _: q3 O: t
    1 W0 W- J& P6 [" w# |' tdef crossover(pop, pc): #个体间交叉,实现基因交换
    5 `  u8 j. Q* [6 o! f2 A8 q    poplen = len(pop)
    ( o8 c4 b7 s: h    for i in range(poplen - 1):5 Z5 ?3 }8 x4 F5 }0 n) ?* Q! T3 a
            if(random.random() < pc):
    9 H6 g/ ]/ d8 Z6 P6 i            cpoint = random.randint(0,len(pop[0]))  q/ }8 }4 V% n/ ^3 Z
                temp1 = []
    ( |4 `, h* n0 z            temp2 = []& u. c7 V7 v4 l* p0 o* M$ T* ~
                temp1.extend(pop[0 : cpoint])
    ' C: A5 \; ^+ B; P$ T            temp1.extend(pop[i+1][cpoint : len(pop)])
    - G) H8 f4 a* G            temp2.extend(pop[i+1][0 : cpoint])
    7 H$ s0 `' ^: c! b0 x            temp2.extend(pop[cpoint : len(pop)])5 q7 {/ Z8 ~$ p! N* \  M, ^& M
                pop = temp1
    0 ^' I; {1 @2 X9 r; A8 |& d& N( F            pop[i+1] = temp25 L9 a- o( t# Y/ d- A9 p" a2 j& }
    import random% u8 h; l; C) M! {- P. n: S$ |

      ^0 \! R! q) Idef mutation(pop, pm): #基因突变7 ?# `# o' t7 ?$ Y6 N7 r
        px = len(pop)
    8 X9 D  g. b, u+ Q3 F: J    py = len(pop[0])
    ; _" e" U/ t/ K: ?
    # J, @9 p# A+ }) u! s: j    for i in range(px):
    . P# l! T$ o* @! ~- A* L% T        if(random.random() < pm):
    7 C. b. p% E5 H            mpoint = random.randint(0,py-1)
    2 C) z* n0 ^  w" {            if(pop[mpoint] == 1):- |. r) g/ c9 X3 {' e) p
                    pop[mpoint] = 0
    6 x+ X# k$ Q9 q5 N            else:
    " G/ _# U3 ?# h* l                pop[mpoint] = 1
    0 p7 H! U1 b5 [" Y3 F# X1 R
    ; V7 C7 s4 R1 g+ ?! l) x5 {8 m& Q* |; c- A
    ————————————————6 i6 j; X4 ^) _& k5 r- F: [
    版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    2 G" a3 b& @$ j/ e# J0 y2 V原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    7 z2 c( k+ Y8 m' \' r# r
    - h  j/ _- o" X/ W! e- p- ]( g" X1 T% ~" l/ p1 b% g' C
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-18 14:03 , Processed in 1.287366 second(s), 50 queries .

    回顶部