QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5828|回复: 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实现的遗传算法实例(一)+ z3 n& t, l6 T3 P" W

    ' b' Y: r8 d1 _. D2 W1 [一、遗传算法介绍* ^$ Q+ p+ w) w, [# F4 l

    - x# w& ?. a0 ^  I  i2 w: e        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。5 V2 p& r3 Q1 S, \! ?( M+ Z; w
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 100 _2 m3 K. E" I# o+ p) p" E: {- t
    % x' J7 w! P( Q9 l3 o* M2 d! Q
    1、将自变量x进行编码
    9 ?% N* E/ p; t% o" o; E$ s) u: |$ j' Q& c8 O) U! c
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]: o! Z3 d, k0 w! }

    7 Q3 e: Y* N* [5 ]7 H# [, R' u2、计算目标函数值) _$ t0 f. @' I# x! W2 x- g! g

      Q. c) \& b/ T5 b+ A      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。; }* e( m0 j0 `4 M  B
    8 e& L2 Z* i! @( d& E
    3、适应度函数
    5 F9 `) @- ~& m& N% R* A; H$ Q$ ?: K' @2 z- p' b# ~
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
      m& a$ k% |+ Q7 H& R. u& ~$ z7 |
    8 v, b. o9 W( _6 O/ c. Z! h" k' r4、自然选择
    ; R. L$ L: E/ W4 a3 h  N
    " T" ?5 C& r' c8 K9 Z0 q! {自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:  d! F$ o& W" A9 |/ _! f
      |/ \. S" Y" k
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。8 R- i! h; {0 |* t; d2 E" z

    6 {) \! Q$ p' R* B. H: b5、繁殖
    5 ]. y: U# D2 Z1 m
    5 [" Q# }  `6 f4 L: L. n, s+ M假设个体a、b的基因是& V8 w3 e( Z; X; J5 a
    0 w: c  e: I* V% F% _$ L
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    / J5 k$ {+ K  O9 O/ _$ m+ b
    ' ]4 k( P# B# F0 U; S& m5 A' Jb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]9 t$ x! d! q+ E+ E7 |* t

    ' [$ \, z9 H9 Q8 A: ^这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:0 y$ j1 p. e' S" g0 f1 c6 D
    + t1 B/ R; ]  X9 g
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    3 E. Q) I% M. p$ q
      V+ n- e7 x+ r( @/ Eb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    8 J( I2 x( Y. ]) p  b
    ! G- ?6 N& A+ l) _交换后为:, S; q: h3 P8 r3 E0 [6 b0 s
    ( Q; z; C# h* g4 v
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    2 B2 c/ R! T' ^. R3 s$ c+ T& ^0 t  g* \7 D' n7 J' y
    b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    ( ^3 d/ J; P# _1 V" G7 \! k9 a# w9 A! W8 c# e% w5 ?2 d" o
    6、突变
    ! u- ]- x, R! r' \
    ) c: X( X( [: A$ @- K6 v0 h遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间. Z: H- B9 K0 k3 @2 g" r

    - |* h6 ~) o3 j二、代码
    # W7 h& H2 A5 I8 O( I8 Udef b2d(b): #将二进制转化为十进制 x∈[0,10]$ k$ q* @4 v+ M
            t = 0
    4 X" u: y- G4 Q. `' @9 L* M. C        for j in range(len(b)):
    3 O8 Z+ I/ Q7 g                t += b[j] * (math.pow(2, j))0 W9 j" n; p% m
            t = t * 10 / 1023
    ) K& \6 M* r! ?4 s9 s2 B        return t3 l3 t) `" `% G# p( u
    : }8 ]# M0 }/ E: R; r
    popsize = 50 #种群的大小
    0 U, K$ C' L4 Q* {#用遗传算法求函数最大值:
    - W! B( Z4 x5 r  e- t' |: T2 _#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]2 u. R8 m5 z9 \1 L* b4 F

    ; f$ ]3 s  y/ Dchromlength = 10 #基因片段的长度$ o0 z# T5 f7 e3 T2 P; M- Q8 X
    pc = 0.6 #两个个体交叉的概率
    4 A* |3 ^. r' ]& }! `! G$ Mpm = 0.001; #基因突变的概率( A+ @+ k* |. v5 h
    results = [[]]
    . `# }* k' i' @- C$ Rbestindividual = []
    8 [- h. M# u5 v3 U& Cbestfit = 0
    4 U+ Z) @0 Q3 O! p  I! X/ ^( b7 ?fitvalue = []* P9 F& e" k6 F1 W0 o
    tempop = [[]]1 U/ e/ z* h8 j- h
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    # c! s) a* E! S9 k- p( _% C" mfor i in range(100): #繁殖100代( C! F5 F1 k# s: z0 w6 z2 \6 n5 ^6 X
            objvalue = calobjvalue(pop) #计算目标函数值, q4 C5 @1 o% Y
            fitvalue = calfitvalue(objvalue); #计算个体的适应值% z/ J6 y" T; G# l
            [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值( I* ^) a/ P  k1 H! R7 a  J
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    6 u+ I6 K6 z0 G# H3 C  x' v  [        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体1 j& M) f' n' A! _: }: G
            crossover(pop, pc) #交叉繁殖+ x6 `! J8 j* w
            mutation(pop, pc) #基因突变) V" d& |, A  P3 I; l. A
           
    + G. N" r; i! K* E3 O% f2 |% t5 b1 E5 w
    results.sort()       
    $ h% g" A6 M: x# C1 B+ x0 V9 m$ Sprint(results[-1]) #打印函数最大值和对应的
      _: k2 |/ a* b  A4 ?/ Qdef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。, {% n; Z$ k; m0 Q6 X: a
        fitvalue = []9 J# B0 i, S0 X7 X* g
        temp = 0.0# j1 S3 b" E" n- l; l: P
        Cmin = 0;: w$ s6 U7 [2 f6 t! I8 C
        for i in range(len(objvalue)):
    : c% b; F. Q- ~0 Y9 Q: }6 l        if(objvalue + Cmin > 0):; P( P; }2 V: S) M* i2 d
                temp = Cmin + objvalue' J/ z1 q7 l- R& t) T; T
            else:
    ! D9 G6 h* G! l. Z5 O+ }" `            temp = 0.0
    - c/ c: C( d* f4 {7 }; G$ Z        fitvalue.append(temp)
    $ h. C, M" _" p) z, M    return fitvalue5 N6 b+ S) l3 E( F* T" u
    import math
    & X# ^3 Q% b; H5 e6 i' M. W& Y4 Q8 [. J' x# w' b# v5 ?  O
    def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
    9 _+ L2 _+ g+ \- z4 ?! {    temp = [];8 U, I; H$ ~- E& O
        for i in range(len(pop)):
    - [. ~, q1 W7 x5 W$ Q( y% Z        t = 0;# w% n6 b7 A8 c
            for j in range(10):( V! z3 h0 H% H" S( n0 i- K! E
                t += pop[j] * (math.pow(2, j))/ L6 V# Y7 {+ \) ^$ }
            temp.append(t)3 x7 U2 H+ a& I) R* m
        return temp
    0 C* a- f$ i: n  e
    " ?. f& D: G* D& e7 Rdef calobjvalue(pop): #计算目标函数值
    ) t# q7 ?  f- T# g  L    temp1 = [];
    1 o/ K2 _9 [6 v; A2 E4 U0 n    objvalue = [];6 a2 R- d3 e$ I! l: S4 T4 X
        temp1 = decodechrom(pop)9 c4 Q$ i! C. k2 @* q
        for i in range(len(temp1)):
    - @' r6 M$ E/ }2 i        x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)/ G- W2 _  t7 M4 f& m
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    4 l- }7 s9 z; x4 L! _0 j    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    & U' O+ q! V2 jdef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体+ e& B& q. S# @* b: j' N6 w& M. J
            px = len(pop), A: k6 O4 m/ O/ u4 u
            bestindividual = []2 ^8 @" i! \: |% Z2 l
            bestfit = fitvalue[0]; D: `4 g+ F# w% z7 C
            for i in range(1,px):" k' t6 F' Y1 A9 j" S3 h5 z$ m
                    if(fitvalue > bestfit):
    2 [* j* c/ [' X6 p5 G# r                        bestfit = fitvalue
    * U5 M: v+ v3 a                        bestindividual = pop' c0 D7 l) P- V5 b5 G& ?
            return [bestindividual, bestfit]
    ' e6 X) Q4 z  g  q! S5 iimport random5 h) @6 H: A+ ^
    / w2 |. {2 ?, m6 V: G
    def sum(fitvalue):% c4 ?/ A6 i. k* K
        total = 04 H7 k$ G2 T. h$ X7 B" ]& O
        for i in range(len(fitvalue)):+ T" d! y* }# t( j+ y2 r& I
            total += fitvalue
    9 a0 ~) R7 ^* P7 C; `    return total
    9 m0 q: g. K7 u. e
    * p  R$ s+ z( ?2 Gdef cumsum(fitvalue):7 }7 T% i! @! b! Y2 [! x$ T
        for i in range(len(fitvalue)):
    ! p5 x$ y2 E7 [# Y0 R; S8 R3 D: |        t = 0;5 [' i1 @$ b  b, x0 j
            j = 0;
    9 l' w) _2 ^' u* ]7 p. d        while(j <= i):
    # @5 {. c* R- y2 t            t += fitvalue[j]# [/ d5 e2 H: w5 i! |8 M
                j = j + 1( J: O) B$ j/ D- U
            fitvalue = t;& _+ `, a9 X7 ]# `0 @* M
      H- |# ?7 ]+ G8 y
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)
    * d; Z, R* g6 k) h, |, M        newfitvalue = []0 n8 j9 S) C4 W6 B! Q* P; q
            totalfit = sum(fitvalue)
    " t1 j% j9 v0 V8 O        for i in range(len(fitvalue)):! ~4 E; e  `% v7 e& o6 h' [- m
                    newfitvalue.append(fitvalue / totalfit)  z4 I+ @7 f2 }, |+ N
            cumsum(newfitvalue). J* n: \4 \) g" N+ W. H
            ms = [];6 O: ^( y' f2 g( a" q1 N
            poplen = len(pop)8 A4 |- q7 S  n& L4 R! r" j9 o
            for i in range(poplen):
    8 j  q$ x! s9 S: N& @                ms.append(random.random()) #random float list ms/ W9 b' W5 F1 I: d# X
            ms.sort(); R4 k8 m) C/ d: f( z& }5 f
            fitin = 0+ y5 W6 f" |& N3 i7 T: P
            newin = 0
    ( V2 J! `1 }; q0 v        newpop = pop+ B" S$ y5 e9 D; W1 _
            while newin < poplen:
    : x2 k1 v& p( f/ R                if(ms[newin] < newfitvalue[fitin]):' x- g1 l% T/ M" |6 o: P
                            newpop[newin] = pop[fitin]+ k, u2 K% f  Y, ~3 W1 L: I
                            newin = newin + 1/ e+ a' u, ~4 i7 I
                    else:; [& c' |1 a3 t
                            fitin = fitin + 1
    - r# i( M3 b/ x8 g9 h        pop = newpop
    ( G, [4 d3 o4 S0 D: Uimport random, c/ r, E% a5 X6 |* L! \* D
    / x, @7 @8 H7 d% c# J0 N
    def crossover(pop, pc): #个体间交叉,实现基因交换% U0 G" A; b6 E
        poplen = len(pop)
    5 D, S) G8 k; G+ B- L" l5 ^; U    for i in range(poplen - 1):
    4 C$ n* {) z. `& N: k        if(random.random() < pc):  `: c  F- U  ?2 d$ ^
                cpoint = random.randint(0,len(pop[0]))7 z7 z1 V1 O9 Z" S
                temp1 = []/ N( P* L1 g0 I6 S% [7 _
                temp2 = []
    + A7 l. k8 |9 c* r6 K            temp1.extend(pop[0 : cpoint]). ^5 l* i4 @3 |: H
                temp1.extend(pop[i+1][cpoint : len(pop)])* }; W6 Q3 r7 k! t5 b* _
                temp2.extend(pop[i+1][0 : cpoint])
    ( Q2 H  o5 {- B$ o# p( Z            temp2.extend(pop[cpoint : len(pop)])
    ( J3 F% x, `% k1 f            pop = temp14 T0 ^+ @, E) T$ D! b) A
                pop[i+1] = temp2
    7 m  K! H3 d& zimport random
    ) J5 T! m: ]8 `$ L$ r. N: L% ^6 D. b( A
    def mutation(pop, pm): #基因突变3 D- P& C+ [6 U, b% c
        px = len(pop)
    : F* J6 N5 O: Q; m0 V    py = len(pop[0])
    : s! |) H+ S+ U9 N1 {* P/ F: t2 i
        for i in range(px):
    9 |! h  L. h/ R6 V, L        if(random.random() < pm):3 {3 O1 S1 U7 ^6 n+ N
                mpoint = random.randint(0,py-1)6 \4 ?$ X1 X) _  w2 S
                if(pop[mpoint] == 1):
    $ r# V; j: p/ o1 i. \, g                pop[mpoint] = 0! a) t  w0 _" A  m! ~% J6 I
                else:
    + c  m: [& O$ Z+ f; @+ r5 E                pop[mpoint] = 19 P3 e/ J8 ^' f4 O* N2 d. f
    * L* u  N! [( g( ^* N

    * m# M. Q( E9 R/ @————————————————
    8 T" q9 F. |; C+ B8 {7 T版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 F" c) T6 S0 H' Y! Z1 H原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    ) X# N3 n" y$ c8 \  h3 j- @* u8 ~! {
    $ X* u2 K8 `5 j& i/ u4 _/ a4 G: i
    ) g' ^; K1 p! R( z! o6 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-4-18 12:04 , Processed in 0.439526 second(s), 51 queries .

    回顶部