QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4789|回复: 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实现的遗传算法实例(一)
    " b1 R' `* S( _/ X  u. Y# V
    ! u( P8 T. n* J0 T0 u一、遗传算法介绍
    ; E2 a* s: l, d; U
    " f6 M! w  S2 n        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
    ' H2 v( [; g* g        f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10
    ( T8 h  G: k) o) _* g) N1 z; W: c# N7 r8 D  @
    1、将自变量x进行编码
    + }1 T+ ^* }# J5 k/ J6 [6 i- x
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    $ U3 u1 j& [& x6 L& }4 R" l0 R/ m1 y& U3 _& {0 j" u; o: f) |
    2、计算目标函数值
    - b& B/ H$ B  Q: |
    & ~3 e6 T) u# D$ d      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。' x) ]+ q9 J4 p. X5 P1 k  H
    ( V% |" z( Z% a! W
    3、适应度函数" c6 {3 E. ]  r& L# _

    7 d) X; U6 k1 U7 J' G$ u/ W      适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    ! m) u- |4 V1 T, \1 O, }# z
    . ^  q% H. ~4 v4 _2 P4、自然选择
    & A1 j4 e* I+ ~0 S+ W( h
    0 u. W6 h: S9 T; x0 q自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    9 B# J8 i9 o% v2 R
    + Q9 j. u5 H- }* i& u3 L假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。; H7 q9 E. A7 M0 j0 u- _- Y
    2 ~" z1 Y1 x9 Y) h2 D7 i2 X4 h% J0 P
    5、繁殖
    ; E: c4 m+ _7 `! n$ O
    5 F" n1 w1 G+ z6 I; W* t假设个体a、b的基因是) ^/ v4 g6 P6 q" e- y% o8 o7 v
    + A$ h8 M. i4 M% W( r) f- t
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]# i4 W1 w' E. o2 h! s
    : ?/ ?+ W" V+ w
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    4 n$ P, y$ i$ b; V  F" n; i% B: u: V+ z. g* q
    这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    5 \" \7 [" x/ L9 m* d& Z& s, D" g6 }* O  {8 Q$ [
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]6 ]- g" e" g' z& n) _
    2 ^' Z9 Z  }2 F$ O
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    & \* J- V9 C! B7 `3 C% j# V5 }
    & O( B$ y2 b7 {, g& t7 Z: m) u6 _交换后为:
    ; V) `9 R" s1 W% i; w. F1 A5 w- J( Q, L' P% J. a
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    * M1 U: T% Z8 a8 v3 d& R0 Q5 E" \
      B3 X4 k, Z: p7 i6 h: q: p* o& lb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    8 h6 ?1 b3 d" \) v; K* u( v; x: t- a4 e+ u: I5 R3 C+ T. |
    6、突变/ r# S3 K; r* l8 L: ?- q$ u( L

    3 R8 {9 b5 o6 t* U/ f4 `8 R8 R  [遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间2 Z% B* W, ?* U* o
    / T# _* S) D( B5 \3 N$ F
    二、代码1 S& C* ]+ H6 G, J. n
    def b2d(b): #将二进制转化为十进制 x∈[0,10]
    + S; H4 t9 f0 |, Y5 j- V        t = 0
    , V* A* ^% h3 x; P$ X) w        for j in range(len(b)):
    ' @) U4 @7 x$ {                t += b[j] * (math.pow(2, j))& q  _& O1 j6 }- }" ]
            t = t * 10 / 1023
    ) Q6 @" P2 I2 `+ R4 P2 r7 D        return t
    3 K6 ?. M% l$ `+ i
    7 E$ Y% j. H8 H7 u: X5 ]1 Q+ _popsize = 50 #种群的大小
    5 j9 R' Z: s6 V) x3 g3 }' _7 _#用遗传算法求函数最大值:
    / F2 l; ^% Y7 w" o1 I+ `#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]5 N3 q& K! Y9 _

    & z) ?5 q$ f3 j, N% Q/ nchromlength = 10 #基因片段的长度
    & N# z- \5 ]: Upc = 0.6 #两个个体交叉的概率) u) f% v6 M8 r' O) L
    pm = 0.001; #基因突变的概率( F' ?. i; Y3 `( {
    results = [[]]
    0 \( L4 L& M$ h4 ?, r2 A1 Nbestindividual = []
    ) D' D& J7 O* p) t& mbestfit = 0+ ~* I- ]7 r7 A5 P6 ?
    fitvalue = []& \" u/ |  `4 v* K' \8 R
    tempop = [[]]
    ' u8 b$ ?! e5 ?3 mpop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    ! B% E1 V' d. _" x2 a$ _" s- Q5 Wfor i in range(100): #繁殖100代
    ' _( x/ [! @4 q9 \8 O& `        objvalue = calobjvalue(pop) #计算目标函数值
    4 w8 }1 ^! T8 l! _( V        fitvalue = calfitvalue(objvalue); #计算个体的适应值
    ) |' B1 K0 Y8 J/ _; M        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    : h3 Y$ ?8 p, @" I" w  ?        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来) \2 L! K/ M2 R0 ~2 V& S. i
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体8 Q- C# c8 p# {  f; H, K' v- h9 G; Y3 m
            crossover(pop, pc) #交叉繁殖$ u, w$ ~) B) |4 J' z" k
            mutation(pop, pc) #基因突变& V) ^- J+ Q$ G( r2 @! h) w
            9 l2 M; g( I% K# }; _

    3 l! E0 `7 a6 L2 H" v8 m. f" Yresults.sort()       
    # t7 H  w  g5 b$ Nprint(results[-1]) #打印函数最大值和对应的
    3 n" w. I5 H; n6 C0 mdef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    ( o$ b5 @1 K' C$ Z$ X    fitvalue = []) D8 W% v& n0 d  k8 P
        temp = 0.0
    " x  a% }2 o6 `% K) g% J* u    Cmin = 0;
    $ F% l8 z: q' S+ Y+ T$ n: R    for i in range(len(objvalue)):+ l& ], A# U$ z: Z. ]
            if(objvalue + Cmin > 0):4 j7 I2 {2 g6 ~$ E. ~2 P) y# }
                temp = Cmin + objvalue0 j. f6 u% L& S7 p
            else:' A* M6 ~& k; G7 H
                temp = 0.09 S" _' N5 J7 [; z  t
            fitvalue.append(temp)
    : C( A' y7 M/ b    return fitvalue
    4 C4 ~) ^* G3 ~1 W: y; `" dimport math2 ?6 X1 J5 T" u8 k+ ~' d, b( s: F+ o

    " F0 r% R3 f0 t0 adef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)0 ]5 `1 p* \) x' X
        temp = [];
    4 H/ b+ z5 u. n% L) g% G# h9 ?) R6 O; k; o% z    for i in range(len(pop)):  F/ r1 {' s; D' t  _8 S
            t = 0;( c9 M) G8 m7 D; k8 C% r
            for j in range(10):: E+ l/ t' v9 ~2 O0 E5 {
                t += pop[j] * (math.pow(2, j)): B# |+ a- k- @; V0 r
            temp.append(t)
    - S- Y! r" V. S% z    return temp
    6 @( `3 Q: K3 q& v5 U+ e( _2 U& g6 [- [( e/ U; \0 X. p4 }
    def calobjvalue(pop): #计算目标函数值
    + D/ |- n8 _5 m  o0 _8 E* q    temp1 = [];
    . V. u6 A& m3 O( F8 f9 B' M    objvalue = [];
    7 y8 v4 T, U; w0 [    temp1 = decodechrom(pop)
    . v5 X0 E7 U, g4 x3 A8 ?8 S- Y    for i in range(len(temp1)):) [0 ~3 L' s. w, @/ ]) l# e' Y
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)+ _# W" }+ \& V- G
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))7 v8 Q+ d+ k  c% j, Z. z
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    ) a. Q* ]5 Z5 D/ _8 J7 Edef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体1 K% O" {  b( S5 u2 ^; n! s
            px = len(pop)
      @0 u) P: e' G; K$ c1 j        bestindividual = []
    & q; [" h" ?, A        bestfit = fitvalue[0]
    6 o* K: Z; \, m  w1 m        for i in range(1,px):# f9 ?# W. |7 l. X' c% F
                    if(fitvalue > bestfit):5 A  Z  e& C0 h- Y9 b5 ^+ R% c
                            bestfit = fitvalue
    9 \+ B* w& d; D4 r; S) @, |& e                        bestindividual = pop
    + G& t, m2 }6 G, c5 ]# u9 s0 I. Q        return [bestindividual, bestfit]% @( P7 H. h) h5 C, x! J  e# Y
    import random' d) D+ F% t* k5 l) P& m7 i$ _

    6 ^! \3 ]% m, W, z' v9 Xdef sum(fitvalue):
    : H0 g( j1 p( ~& g2 j2 X+ e    total = 0
    & v% K. R! [; K. \9 i    for i in range(len(fitvalue)):
    8 `1 d' ?- M- K% s        total += fitvalue
    ! {4 a+ T4 s, P- @$ Z9 s    return total
    ! ]5 J. Y; [1 t+ s: W/ I' @, r" ?* Q) \/ F5 d$ p
    def cumsum(fitvalue):
      I$ i9 o+ Q8 n- F" k- s* U5 g    for i in range(len(fitvalue)):
    + E+ V1 Y) L: ?( ?3 Z. R- [        t = 0;
    + A  C" w* ]+ ?7 A        j = 0;
    4 t8 h! c8 W8 D& L$ L7 t        while(j <= i):
    / A, z4 \! B4 j: T3 W  D1 O: z            t += fitvalue[j]9 I+ Z, Q" }. i7 U) e
                j = j + 10 `) [: V/ d/ |" n/ s. C4 K
            fitvalue = t;
    . M- Y5 F$ o  i1 c& \0 w: Y/ U; j2 C/ g9 ~. U) f
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)4 ?) m! j/ s) i. I  w
            newfitvalue = []
    9 x6 I. q+ _, e+ m        totalfit = sum(fitvalue). |" r, Q" Y2 m' p9 ?
            for i in range(len(fitvalue)):
    ( B( b, Z: p6 v- v- K                newfitvalue.append(fitvalue / totalfit)
    5 x: x# |4 J4 h! B5 B' U& |$ p; o        cumsum(newfitvalue)0 b" ^$ h: S* `, c0 Y9 @2 R
            ms = [];! E4 C! L& ?3 R* B# y
            poplen = len(pop)
    4 w, W: _+ \! }6 `& g" m9 ~! b        for i in range(poplen):
    2 y" K& j3 R' ]                ms.append(random.random()) #random float list ms
    1 `0 b9 \# v$ ~3 s$ P" S        ms.sort()" I# I2 I( z* ~% c. }* H, |9 }
            fitin = 03 p# k, N  A9 |/ H4 G7 H5 x1 l' C
            newin = 06 p. ?4 D6 F. q) G& w) c
            newpop = pop
    3 s* w& _) X, k7 E6 e        while newin < poplen:
    " P' n2 I- q$ ^, n9 A                if(ms[newin] < newfitvalue[fitin]):
      m* c( @2 c! I7 |' c                        newpop[newin] = pop[fitin]
    ! D8 {* }: w1 Y5 Q                        newin = newin + 1
    5 L3 t8 p6 B/ }+ Z# ]% |' n5 E                else:
    . z) h! p) u$ R                        fitin = fitin + 12 X- D1 j4 F5 z- r0 W% L! [( Z% W
            pop = newpop
    & r! Q7 I& ?$ A6 uimport random
    9 d1 n: R0 @  ]: o$ \  u- g
    4 i6 Q7 A/ m2 s) h0 Ldef crossover(pop, pc): #个体间交叉,实现基因交换
    8 c* V5 F1 s- }& _; O4 t: S9 ~    poplen = len(pop)
    8 l6 X% M- D$ s8 c4 u0 K% A    for i in range(poplen - 1):" h1 B+ Z# }& |# {% Z" N" W, W0 _
            if(random.random() < pc):. n) Z  O( r. h' c; u$ F0 [
                cpoint = random.randint(0,len(pop[0]))% X7 O% o( G# \1 N4 r# R
                temp1 = []
    ; H6 W& H7 P8 W% }% c            temp2 = []
    2 J. e. j) ^7 x: X' o( v  U8 L            temp1.extend(pop[0 : cpoint])* _! y' ~2 k0 e# P3 F
                temp1.extend(pop[i+1][cpoint : len(pop)])
    4 ^4 Z5 u6 J  O0 p% Q: M            temp2.extend(pop[i+1][0 : cpoint])
    4 _; I( Z0 b9 J! R  L5 t, B            temp2.extend(pop[cpoint : len(pop)])2 _2 O* D6 C3 }
                pop = temp1
    % F5 }4 f7 T6 E            pop[i+1] = temp2" Z1 A2 t* v/ R" n3 F# r% W9 O
    import random$ [$ {+ J+ }( X! b5 K7 l, w' ?
    " s6 O+ ?: C/ S  c
    def mutation(pop, pm): #基因突变) Q; L  d2 a- `  _* a9 s0 x8 n
        px = len(pop)
    ' B3 v3 P8 Z' k& K) t  k) Z    py = len(pop[0])( `" O2 I$ P7 T% ]: \
    : P' ^: N4 S# Y% s' F. P& P9 y7 [
        for i in range(px):
    + `2 e) Y: \: Q$ A! g        if(random.random() < pm):
    / p8 ?' P* J+ s- G+ E" d" w            mpoint = random.randint(0,py-1), B% i) X6 J3 i; c6 e$ n
                if(pop[mpoint] == 1):
    4 M1 ]9 n& J+ y1 H+ z1 T; U* N1 b                pop[mpoint] = 0
    4 J7 L( g6 r  F6 J0 z6 a            else:
    ; O$ c6 R: U2 B, g9 C/ a$ @, S                pop[mpoint] = 1
      ?' C5 }/ O4 ]- s6 T# [/ H3 g: I. q* q& Y$ f* Q  l2 v5 h7 x
    3 W9 J$ v" ]% `; B. w
    ————————————————
    5 x' P* E1 M4 X4 j版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& ~' D# R; {3 T/ z# h
    原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    , \- t, {- n8 L8 P2 t; j! e+ k) O2 l# t4 l

    ) \+ L( a" p2 A6 D9 S0 {$ T+ [- ?
    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, 2025-7-4 11:38 , Processed in 0.409647 second(s), 50 queries .

    回顶部