QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5992|回复: 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实现的遗传算法实例(一)
    1 j4 n' Q  t1 o/ B9 O8 N! z' f
    ; A9 l  W, ?$ K/ Z一、遗传算法介绍
    * f5 c4 R$ z- i# F2 C+ n( f. U, e: x, G4 Q
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。7 Z5 C, {0 A" B% D4 q
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 102 K, }& ^$ @! |2 d. ?

    0 s& \) ^* ~: m% d* V6 \7 J1、将自变量x进行编码
    0 k7 {+ |0 V% Z9 k- p  a5 Z! L9 N1 S6 X! f
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]$ }/ Y3 ]/ S8 T! x9 L, ]
      Y$ z7 b6 }% Z! d) M: h! A% ~, z
    2、计算目标函数值
    $ L; V' e4 B* ]" U& x: ^. K" M% J
    . M. E/ X( v& }+ ^% J      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    ) Z# D8 F( h3 t! a) V
    , S! i2 L: M- _; ]$ v3、适应度函数
    ) y* i) X. a/ m* d
    ; U' `1 U4 Q! b; Z% n1 k      适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    , a) i4 N, m" V6 \6 N9 j$ A. Y
    8 q  N$ x0 N, t) u+ Z) j2 z4、自然选择7 X3 j; C. {# Y4 t0 _' I& k" c

    5 a0 t. T2 c: \0 r( Z自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    4 `( a5 a, r4 D" [( f& k8 `/ H/ G, }' T3 ?5 n/ Z' E
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
    ' R2 o7 ]- ~- B! Y2 T) d! j  O6 M# O  |2 l; D8 M
    5、繁殖$ I- Z6 E5 O, Y2 T
    & H" F; R+ p' e+ W1 }- H' O
    假设个体a、b的基因是
    - s4 L( w0 d" I- u: d- i7 c" J. P$ c+ M3 l4 k# S
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]" R! n$ P, g0 ^+ A1 _/ z0 }

    ' d, Z& I1 a* k( p6 I) Kb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    3 a& l( D: u3 W: {. G
    # C* w2 ?* l+ c; j' O这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    : r1 `8 o( o3 E1 }- }3 F3 ^2 G9 {% Y4 U/ J9 ?6 D% i5 a8 t
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    ! i. x" h3 V7 L; d3 B; R, Q/ [! _; a: ]; q/ `5 B
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]  z" i0 R% J; t- L
    + N5 k1 W" d' u' k7 Q
    交换后为:
    6 b! B! t; ~. u1 ~. ~* e" U# n4 Q& H+ c, ?+ X/ X
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]# [6 V/ ?+ R1 T8 B2 U
    7 @- p; k( P3 |' ^
    b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]! c! M8 i/ f& X

    - I$ x6 o* W5 `4 M: e1 h! ^- I6、突变
    8 b! n2 N) b+ w0 i% C, x  o" `5 Y% F* |
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
    7 q* Q: F+ {7 o6 f9 J5 P* M' s2 k! D& m9 c: F8 e4 M. S
    二、代码" Q3 [' l2 `" }. V$ A; ^+ L- i
    def b2d(b): #将二进制转化为十进制 x∈[0,10]+ [2 ]1 l- }1 ?& v4 @# \
            t = 04 _" u$ a) V$ h# u& b* |
            for j in range(len(b)):/ O/ Z- l) ?+ I9 D% P; k8 e
                    t += b[j] * (math.pow(2, j))
    9 u# ?! P- u! g        t = t * 10 / 1023
    ( ~$ `8 ^9 B. B8 j; ?+ c# s; |        return t" _. m7 i) e# m9 I4 e

    : \. _/ \+ p8 H  u5 y( C/ Rpopsize = 50 #种群的大小- J5 E2 X% W5 i) p% p
    #用遗传算法求函数最大值:9 P9 F* e$ [* Q! h- J
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    2 z2 O/ A' P* R4 u% d" I8 o+ b
    - X- f6 ]0 D6 mchromlength = 10 #基因片段的长度
    1 ?/ ^3 V  w7 W+ p. zpc = 0.6 #两个个体交叉的概率
    " I1 n& S' i# r( l7 |3 E0 L1 q, apm = 0.001; #基因突变的概率
    3 p8 _, u! z+ Aresults = [[]]+ m% b. d* ^0 H" S, Q; j& r
    bestindividual = []* q- d% \! w0 X
    bestfit = 0" l7 t# _7 H  q2 [+ Y6 y
    fitvalue = []
    ; f% _  V4 p0 O4 b3 I' Jtempop = [[]]; p7 G( |& R( y
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    # V) B- Q) \9 p( vfor i in range(100): #繁殖100代/ M, [2 P, w0 [' W# E" `
            objvalue = calobjvalue(pop) #计算目标函数值
    # r& {9 E8 f4 h+ ?3 u        fitvalue = calfitvalue(objvalue); #计算个体的适应值
    ' n! Y, Y! J3 b# s        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值9 q3 }- E) u5 ?$ w+ I8 A) ?
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来5 Y- P3 a+ ~, F! b
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体/ U5 W! v3 ^- f/ s2 M0 N) W
            crossover(pop, pc) #交叉繁殖& Z: y: w1 v1 t) s
            mutation(pop, pc) #基因突变
    $ d  d1 m9 J  j, ]6 ?+ n$ v        * l0 Y, _0 W; J% y3 K2 w  o
    - J7 j/ x4 t+ L, \# H1 Y3 Z
    results.sort()       
    ' [! j* A# g9 F4 W6 ?+ B" C. yprint(results[-1]) #打印函数最大值和对应的) {  ?% w& X0 v/ q" Y( p3 \" E
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    4 @* }( u$ {" a5 x+ f+ k% T9 \  g    fitvalue = []
    & w, [" A: H1 @) S3 X  i# }6 @    temp = 0.0
    # a! @% v$ t8 [+ e0 I0 ~/ H    Cmin = 0;
    * r, @6 A& P8 i. U! P) F3 U! V. w    for i in range(len(objvalue)):
    % j+ T. x; ]+ I5 i        if(objvalue + Cmin > 0):
    ; J" f: a2 G) d            temp = Cmin + objvalue9 x7 c$ \( g3 \  y4 c' f
            else:
    ! W; ~/ ]- L$ e  t1 Z            temp = 0.0+ U  I! U3 o( x/ R8 b' P
            fitvalue.append(temp)
    ( ?* z# @: V! l; y- K: O: ?7 [    return fitvalue
      R% |1 B7 u2 b; n) Fimport math7 G: A& ?, r: {5 A# T

    % \2 M" p* L& L/ r7 `def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
    ; Z. m% K& C1 w# f* C+ I    temp = [];
    1 m. \& [/ @' w$ R- T    for i in range(len(pop)):& }) B8 w1 P* K# F( T
            t = 0;  s6 x" V  s! l# g
            for j in range(10):3 U2 c3 Q# u) P' C2 k
                t += pop[j] * (math.pow(2, j))/ X+ q5 |/ {1 f
            temp.append(t)
    8 U: f) D. V5 q% L* t" K    return temp5 w; _( _+ h3 y" t' s

    * O. [5 I5 K8 ]0 \3 U1 Y! }- Qdef calobjvalue(pop): #计算目标函数值
    9 X. k- V- d: H+ l& h8 H) k6 K9 z    temp1 = [];  |5 e  H! a/ _7 q* A# o3 N; f
        objvalue = [];" g2 H" m1 t3 X, C. H* v
        temp1 = decodechrom(pop)
    " x* J* ]; h% o* d    for i in range(len(temp1)):5 ?9 }  O, g* `7 R1 B0 m
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)0 W. \- E- a* Q
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    $ a+ H/ Z, I8 c; a/ ?4 L: |    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    " j  ~- \7 A  o( D7 }6 G$ Mdef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
    7 L) o, Z$ F8 v( [% Q0 M        px = len(pop)
    5 ~5 i8 n. o. u- l, [; V1 h        bestindividual = []
      b- g3 S+ _: y8 l% `: i  S        bestfit = fitvalue[0]; k, c+ K* g0 W
            for i in range(1,px):! S/ E' S; T9 E
                    if(fitvalue > bestfit):% M- |) N5 }; {
                            bestfit = fitvalue( O' U$ a4 _# t; V) U. V/ R" m( _
                            bestindividual = pop+ [: q! U! m3 ~" k9 {5 I6 u9 n
            return [bestindividual, bestfit]2 q3 m9 X% T9 ^( [& I! T* w
    import random
    + s6 {( f, m! x0 F' p* M
    $ w% z5 J0 Y- a4 ^& ]def sum(fitvalue):
    8 {3 C& ]; e  I, q  |3 J    total = 0! |, T8 L# _0 j
        for i in range(len(fitvalue)):+ e* q: }) I% |. ]# v( L
            total += fitvalue7 V2 }0 v7 |: H' j: ^/ K
        return total5 [# @. c5 a% h& Y$ e; {; @

    . m; R" g" D7 h/ f' r) I$ o7 z- _def cumsum(fitvalue):: [) j6 w  z7 T! T& d
        for i in range(len(fitvalue)):' g* ?! e7 f: H- c* \
            t = 0;  ]2 ^) `3 A0 J
            j = 0;+ a4 Q# v+ q# W' q' c( T' s
            while(j <= i):
    % R  O: m1 r6 o* Q8 q            t += fitvalue[j]; q9 e$ L- I9 S
                j = j + 1
    ! x% U# g* \6 f# X! k        fitvalue = t;# J( i" M" `/ O/ o( l
    3 R- ?+ B9 T% E# [, \
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)' `( {1 g9 [- T/ V  v* ]) l
            newfitvalue = []
    - [6 c) K4 m3 |        totalfit = sum(fitvalue)
    ! v& g5 T; q" d& I6 C3 b        for i in range(len(fitvalue)):
    $ B! ]; C8 L, z: I                newfitvalue.append(fitvalue / totalfit)
    8 K- m( [4 O! }5 L2 t1 u, e  }9 i        cumsum(newfitvalue)1 @  z5 e- w! n  D! O
            ms = [];3 o2 h! w$ i1 {% w
            poplen = len(pop)% @- v4 ^# }5 N9 l9 h) Z
            for i in range(poplen):
    ' _0 O3 G/ x- G- ~                ms.append(random.random()) #random float list ms3 ?* i( J$ P$ a! Q* g" S
            ms.sort()
    4 G( s1 h3 a$ N6 I+ f6 h# G8 x        fitin = 0
    . S% D  \1 e) ]7 u! @4 |- z        newin = 09 C: S7 D  Q5 |% U5 p2 S) O5 c
            newpop = pop
    ; {* m0 k5 U9 k: m$ u3 I        while newin < poplen:
    6 n9 u( g* P: I                if(ms[newin] < newfitvalue[fitin]):6 @4 k) [: b) j- Y1 a. z
                            newpop[newin] = pop[fitin], [/ {/ T: ^- m" U, Z" j
                            newin = newin + 1
    " f4 r7 G8 I, e' K+ O( s5 `# d                else:
    * V7 J9 m) L- W* o1 _                        fitin = fitin + 1% e. X% `9 \0 [
            pop = newpop4 ?9 ^& G- D; m2 n( G4 @
    import random
    , ], Y6 m% ]3 Q; e8 Q7 ^6 o) S/ q$ c* M0 C, G2 M# B2 Q
    def crossover(pop, pc): #个体间交叉,实现基因交换# P2 }7 e2 ?! |% N; c- ~1 M& N
        poplen = len(pop)$ A+ ~: c5 v. ~! F# s
        for i in range(poplen - 1):
    2 J, N7 J. k- ^5 N7 ]2 e        if(random.random() < pc):
    : N  N/ `: |, z9 H  }1 W( C$ u& `            cpoint = random.randint(0,len(pop[0]))& d: y  C7 C7 i
                temp1 = []. W/ m  i5 O& R* {
                temp2 = []
    ; `; g& ?4 r9 r7 d            temp1.extend(pop[0 : cpoint])
    , e- O/ Q% E6 }. A            temp1.extend(pop[i+1][cpoint : len(pop)])
    6 ?2 g& E' X. A2 `" H5 O( a& g            temp2.extend(pop[i+1][0 : cpoint])+ c, ]# Q- o7 v
                temp2.extend(pop[cpoint : len(pop)])
    ; j( V& a# t. q: q+ w0 s; V; x            pop = temp1
    3 U0 _' L, ^7 I+ K% |7 ^0 c( n: h            pop[i+1] = temp2
    # E% ?& E( @5 e6 Y0 Uimport random  U- ?  C& b5 F; G
    6 N! P- a8 A( S/ P* U
    def mutation(pop, pm): #基因突变
    + I4 B- Q' q1 [- D/ S    px = len(pop)5 ^5 ?8 h: ^2 f( [  `, D
        py = len(pop[0])( s7 ^$ q- p3 f' L

    # B+ H; X: ]" v    for i in range(px):
    ) v: X- ~' n* V. n6 y8 ]' \& a        if(random.random() < pm):; K+ M& r0 ^$ K; q- z: c, P
                mpoint = random.randint(0,py-1)! q6 V$ t+ W1 h& @/ A/ Q
                if(pop[mpoint] == 1):6 b- u1 m  R9 u
                    pop[mpoint] = 0+ j% V& E; m4 {5 A6 W
                else:
    # I2 u% C/ v, W9 Y+ j0 O7 {1 h( p                pop[mpoint] = 1: v& K3 K4 J' w: u5 F6 k

    " y+ Z, J) k( O  a9 |& H% ]& d
    - x9 _% ?- G2 G% c/ Q————————————————
    $ Z( A/ ?, _. i6 B+ @8 I$ X# J( |版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 X( c6 N& O0 {3 ~! ]1 k
    原文链接:https://blog.csdn.net/u010902721/article/details/235313590 j& ^4 D5 b$ ?  X2 v4 L
    7 n# D) o' O' p& b  H. L, E

    1 Q; @( @/ u* p4 `5 d
    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-9-2 05:51 , Processed in 0.451589 second(s), 51 queries .

    回顶部