QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5976|回复: 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实现的遗传算法实例(一)3 l. j" a8 D+ F8 @

    * t' ?0 ^& e4 y2 j. u) o一、遗传算法介绍
    . t. Y. }/ r! c3 p# D- A% d5 |6 q2 j5 v0 f, ^& Y7 Z; N
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。6 p- p) i0 _2 h5 l; r) u9 \
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10* d5 m, y& j0 F) L# @
    3 w$ H/ Q+ A7 r& Q
    1、将自变量x进行编码
    3 F4 e. N3 b( }7 S% V# l% q6 \/ [1 w% [- A
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]3 M5 z9 }  W  b& H0 K9 n( Y) b
    5 X7 X" g8 y8 }7 y. K. T- |% _
    2、计算目标函数值1 ]. ]8 a5 s9 z$ {- F
    2 P/ z8 t5 S+ s9 t9 f7 f
          根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    " K8 h% Q/ k; G8 ~2 A4 ?4 N& F
    / s! M1 n, X2 _& z1 v3 T3、适应度函数
    ) a! l" o/ m% w# x! @5 C! ]. [* ]: w0 O( T: G
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。/ s3 d1 p% [* a% Q6 b

    % U6 Q9 J9 v* z! ^3 Z* m  v0 @4、自然选择7 M* `2 t4 N2 o9 U$ q$ Y

    % i$ c/ |! A& D4 c8 t' r7 Y* e/ x自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    ( |* r  g: x3 n; g% i( y+ P/ a! Y" J# u
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。7 E$ |3 V, Y& _: {0 p

    : K, C2 l9 C7 W; z7 b5、繁殖' s: `& P% g: k% {

    8 R8 `* ?9 I% E6 r& e. t5 c4 C假设个体a、b的基因是
    3 ^# {3 [1 J5 i9 v& n
    - s8 X. [4 b3 s" {7 A" |4 Pa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    ) P8 F2 x' u; {* ^* N
    / }9 Q  H: V, r8 D6 kb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    0 `, g0 y6 T) c, y3 S5 J' @) z
    6 D- }: Q) ]7 z这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    , n& M  x- z/ ?: l" `& r
      w8 ~0 w. R( |a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]7 L8 {- s: g, Z& B

    # k8 f7 M8 Z/ U: Z1 Nb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]$ Y7 d+ c7 I9 W+ s7 ~
    4 O  s5 a( @- ?
    交换后为:
    ; {% h( W8 ~# R" Y* s  L* a- }6 W" j  ~) x
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    ' F* [! |# z  h: K" J+ E
    ! w; B* X' A4 m6 yb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    3 P/ q8 W' w0 H* u* s' u' Y: w4 _, c, x  D% ~) }* d% L; b
    6、突变
    4 E! K% q- ~3 s1 U; z& @# h# Y: R, r/ w5 X- t  F# l
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
    ' m/ u5 d, s( f, K; ^3 F7 @0 o$ I. c$ G# j
    二、代码
    1 S- C* Z, q: c: k- A4 M( \% edef b2d(b): #将二进制转化为十进制 x∈[0,10]; T( s% ]( I9 g! j9 c, c
            t = 0
    - z5 [+ [. ^# m1 v2 C        for j in range(len(b)):% k1 g- J0 j' Z8 n
                    t += b[j] * (math.pow(2, j))8 `" n4 ~- u' n9 x" y3 p3 y" r" S4 a
            t = t * 10 / 1023
    6 R& h6 x( y+ r" S, b* z        return t
    - G. ^8 m2 Q  c0 l* o2 Z. f- I2 ?& p, o; C% @" c) r
    popsize = 50 #种群的大小9 P6 a1 R" V0 X
    #用遗传算法求函数最大值:, k3 o1 ~& b8 I4 B) E6 \
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]3 u! m7 U: U7 x6 @, b+ L* M
    0 \: U  Q, r: {4 D0 T
    chromlength = 10 #基因片段的长度) d7 e7 N2 x% J% a$ a
    pc = 0.6 #两个个体交叉的概率) M8 _; f6 ~2 Q8 G
    pm = 0.001; #基因突变的概率& _/ _7 y5 ]9 q3 ^: A! D
    results = [[]]; i0 e6 h% O  ?( z3 i. l9 X: K0 t
    bestindividual = []
    : f! r4 G: m* M0 y9 Gbestfit = 0
      F& Z4 H6 V/ ?; {/ Q- rfitvalue = []
    $ Y6 f8 l7 y3 Ftempop = [[]]
    . n+ }! r/ @. J4 Z" {pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]- V+ i8 @0 m( {) t
    for i in range(100): #繁殖100代& M* Y/ f& P! Y
            objvalue = calobjvalue(pop) #计算目标函数值4 i1 t: O( l! ]- k
            fitvalue = calfitvalue(objvalue); #计算个体的适应值
    # r( o3 o  G, I. P        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值1 l5 h. M! e' C# F' X
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    5 w9 B7 |. P/ t$ ^        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体9 X  v9 f0 _) ^9 _6 f
            crossover(pop, pc) #交叉繁殖' e1 f  `$ l9 v) g8 ^8 t) z
            mutation(pop, pc) #基因突变6 \" n- W5 y1 C2 l' d
            ; B% U* Q5 b+ r
    ) i# F. Z5 |2 D4 q' e& `
    results.sort()        & H3 T. \" y. ~
    print(results[-1]) #打印函数最大值和对应的8 `6 B9 Q0 z. t" a
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。+ F- L5 D, c' o6 ]0 ]# r/ b
        fitvalue = []: f4 K( J1 w4 P4 D# g
        temp = 0.0
    % }& U% h7 \8 k- t    Cmin = 0;: s- F* z) R7 R" L1 ]9 @7 P# ^, \
        for i in range(len(objvalue)):: V- X/ I! E$ Z: D9 q* N6 i% g
            if(objvalue + Cmin > 0):
    + D9 @5 \+ ?  P$ x) D% @            temp = Cmin + objvalue5 d# d% y* |$ `! l; o5 s; ^
            else:5 u' D) r- ~' M- L, r- S
                temp = 0.0
    1 c3 Q8 z; ]5 V& P- q8 N        fitvalue.append(temp)
    9 F! |/ M: S: _6 y7 P" S2 ?7 K  g6 g2 M    return fitvalue
    ( a& y. G7 D# K1 s6 [9 Y! B+ Nimport math. c/ c% w& I& ]: k3 r- z
    + d& N% [7 ?* _7 U; F8 `( J1 ^
    def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)/ S5 i% ^! ]2 n$ t. ?: v
        temp = [];5 W/ r1 B9 |/ V
        for i in range(len(pop)):
    ; i  n# \3 S7 G3 ~" J! i, U        t = 0;
    $ ]$ {6 l7 q% Q9 H9 C  n        for j in range(10):
    * D! W1 H( b+ e5 h% K            t += pop[j] * (math.pow(2, j))5 `- S  w6 f0 h4 o3 E
            temp.append(t): q: i7 y, q0 q
        return temp
    ; D, Z* T. m& i6 q9 t4 ~" L% Q* B9 t# m8 u
    def calobjvalue(pop): #计算目标函数值. h3 A- Y! V2 Y
        temp1 = [];
    * `3 @/ G# i. b: q2 E    objvalue = [];/ f5 u6 x1 b5 {3 A2 z! K
        temp1 = decodechrom(pop)
    ; E, ]) v3 i) G3 t0 j3 a    for i in range(len(temp1)):  z3 X) T3 o! A9 Y' |! s
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
    , U6 L( C9 e1 M, C        objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    - @3 r; W' C7 q4 U2 n+ G    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    6 ]0 F4 p7 e) O3 Z- h+ \8 S" d. Udef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体2 Z: E" \' X2 z
            px = len(pop)+ Z/ X. [% E+ p4 D: w
            bestindividual = []' @5 |6 w+ R/ X2 G! x9 P# j
            bestfit = fitvalue[0]0 ~6 F) D' f6 E+ @, w" X: b
            for i in range(1,px):
    3 u1 A  n1 x; f8 S                if(fitvalue > bestfit):2 `6 b0 k0 ]" Q. `3 b2 p& ~0 @2 n
                            bestfit = fitvalue8 d) F5 N0 q* i0 k0 H
                            bestindividual = pop
    , H2 {$ G+ e2 |        return [bestindividual, bestfit]/ Y' \0 c2 X9 K9 K2 W
    import random; ?+ d$ Y  Z( a; q+ ]4 J, M

    ' j! l  Y! U. ~: T+ Rdef sum(fitvalue):
    0 ?3 h, b5 w1 F7 _5 j; n6 b    total = 0
    1 R% g* f( D# d1 H# W    for i in range(len(fitvalue)):
    6 ^' g- B; r& R% f, G, G* @        total += fitvalue
    " A. `- r2 L) x( k+ O6 c1 {    return total
    . v7 E0 _9 `6 g9 [2 f% t7 V8 |( k& i, q! L5 a' F# D7 [7 M
    def cumsum(fitvalue):
    $ B, [+ S. C( S) z! T  }    for i in range(len(fitvalue)):% Q8 W, m8 P) p6 m7 R2 a
            t = 0;7 v) O' P. Y" f* |/ D0 k
            j = 0;
    : w4 p2 D& k, J/ Y4 V        while(j <= i):
    , i/ d3 D0 b  ~+ q, U8 o* y% T            t += fitvalue[j]
    . G! ~! G( j. }& Y* j            j = j + 1
    % g* y0 I: H4 L: g4 t( p6 a, ~3 @        fitvalue = t;
    / K7 E  l) L# U
    ( I7 K/ D8 ^' b  \def selection(pop, fitvalue): #自然选择(轮盘赌算法)
      N& u# f4 l9 L8 p) o6 {        newfitvalue = []
    6 n0 J" R  a. X$ e1 |4 N. y* E. Y        totalfit = sum(fitvalue)& f  t) k, s  R
            for i in range(len(fitvalue)):# q/ Y0 a' `& ^8 h
                    newfitvalue.append(fitvalue / totalfit)- f' f3 {: H& s2 p- Q' w* C8 a
            cumsum(newfitvalue)
    + A9 F9 F) o/ j" {& c4 Y        ms = [];
    6 S7 J/ ^. V9 q8 z1 H" h) o& N4 N        poplen = len(pop)$ A4 c. ~8 S' S0 g* ^# i7 R
            for i in range(poplen):
    + T7 B1 J7 A8 R3 G6 P" B7 d" L1 j                ms.append(random.random()) #random float list ms
    8 R: U( J9 v8 n) @+ _2 V8 R        ms.sort()
    ( q7 y  H% X" x* a) O' s$ b: j        fitin = 0
    8 X1 }' W' i: c        newin = 0
    ' E; a6 g/ K1 {: _" {- a        newpop = pop: E2 f, q- U  Y9 I
            while newin < poplen:
    ! P# T6 l4 s9 a, B                if(ms[newin] < newfitvalue[fitin]):/ R6 h) {9 O% V0 R! y" M) g
                            newpop[newin] = pop[fitin]: `9 {- V2 A' n4 a1 i# a" D4 J& ?
                            newin = newin + 1
    3 g( y* N) V) I$ {8 s7 ?# O                else:8 H/ U; a$ K" Y3 g: ~6 W6 ~
                            fitin = fitin + 1& N8 Z  {& I( ^& U
            pop = newpop
    1 z( B# V2 s2 O- g/ @6 wimport random' d: P% R' C0 {9 k" l
    ; n- J/ p0 R% m3 v7 _" ^
    def crossover(pop, pc): #个体间交叉,实现基因交换! ^6 x4 q) ]3 D* T8 p" ?! \0 L  V
        poplen = len(pop)
    % i0 b1 g& z; A. w0 a0 P2 ]- L    for i in range(poplen - 1):
    7 w& E! K9 Y8 |: }1 [7 a) Q7 i        if(random.random() < pc):5 P. P' w9 f% n" Y: N. }; F! q
                cpoint = random.randint(0,len(pop[0]))% B* n4 P6 ?% B' d3 t& R/ A
                temp1 = []
    ) @& c1 a- N% H* g7 ^. F& y            temp2 = []1 Q8 r) x+ q" D- m8 ~) L% e) r6 [
                temp1.extend(pop[0 : cpoint]). ?9 i2 B' m# v" X2 Y  h
                temp1.extend(pop[i+1][cpoint : len(pop)])
    % h) w9 f7 d( V            temp2.extend(pop[i+1][0 : cpoint])4 P' O8 `3 l6 }! O  F1 t. v5 {4 S2 R, K( O
                temp2.extend(pop[cpoint : len(pop)])) \- A* K* t: \; p0 }
                pop = temp1/ L4 v9 H$ _5 g# g5 [$ `
                pop[i+1] = temp2
    9 u# _5 q+ T/ C5 {2 Bimport random& x7 {) H: ?0 }8 p4 m# j
    ' i% ]+ }5 n) S, X- A- r4 [
    def mutation(pop, pm): #基因突变( o9 B$ G) {5 e  j& ?1 L1 P
        px = len(pop)
    % ?' h* r! M1 |8 I+ V/ c    py = len(pop[0])
    - R+ P# l. ~5 X5 H" |
    / f! f) M9 ?' [7 e( h! D7 o    for i in range(px):! v3 K4 K5 D, I  ?1 p
            if(random.random() < pm):
    9 _5 m/ x, O, P" U* P) h            mpoint = random.randint(0,py-1)8 d: @& D/ _" U+ i* V
                if(pop[mpoint] == 1):) a  K) n1 v9 A# W
                    pop[mpoint] = 09 ~5 j1 Y( i% q+ d+ ^8 H0 D8 _
                else:* K! e. u# ^) o2 a
                    pop[mpoint] = 1) F0 k) j4 B( s; Y* R3 G

    ( O$ {6 J! X1 c# a. c4 ~* x$ J6 A2 D; b
    ————————————————
    9 `8 V; O2 z) f7 z版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 A" J8 t, f" Y8 c. p$ N" w
    原文链接:https://blog.csdn.net/u010902721/article/details/23531359. L, c6 H# W4 ]( m
    % I8 s$ D2 A4 w

    5 d6 ?& B+ d3 o
    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-19 13:49 , Processed in 0.589140 second(s), 52 queries .

    回顶部