QQ登录

只需要一步,快速开始

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

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

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

5250

主题

81

听众

16万

积分

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

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

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

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-5-9 14:48 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    python实现的遗传算法实例(一); H* H! B) D& y5 x5 j
    ; V, \$ v7 p7 ~" ^" f7 _& i
    一、遗传算法介绍
    2 \2 V8 ^2 b+ z, k& D; U4 L+ L
    ) A( [) i* t3 b5 F8 z( Z$ e        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。, R6 b) D# v% e' I4 b
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10
    & {5 ~) H, i  W, r0 v, u) C) m. U+ }0 Q* v
    1、将自变量x进行编码6 B  h/ [2 ^) [7 N! w2 k1 B) u% M

    ) a4 L& P0 f! h+ H; I" G5 s& k" B      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]7 ^2 G6 J  X3 u4 {* v7 I9 p
    9 T, Q' z' f2 t6 t  g1 w' r, W3 C
    2、计算目标函数值3 m4 g1 m% w2 m/ t  a" |' K

    + r- E' k2 z9 I8 g& C      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。. `: P- }& |) s- H. V$ l5 W
    ) k: p6 w# G2 Z- Y1 i" ^
    3、适应度函数! i" H+ T" p% i6 v9 a! ^
    0 Z  R, U" b6 w& s
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    + E& j0 ~0 }! K# w/ u; X
    : q4 g2 D# O( j* N9 |8 n7 G1 M4、自然选择
    - f: k7 V; w% ^3 y5 v8 g
    . E, C$ |* f) M% X自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    + w2 q& I. h. W7 _$ o/ u  @9 S5 P! t
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
    3 x1 `9 T/ i4 a5 M# H" B
    : ^- u( G$ z, o# n9 A5、繁殖! B7 ?/ H+ y; Q3 S6 `" I) D

    3 f  w( ?& N2 q) H假设个体a、b的基因是5 d9 O2 [2 Q# _$ H# a
    # h* c8 K" q6 K5 i8 N6 N7 ~# `
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    : V* U7 y! d4 T2 s% R6 i" \" v5 q4 [/ \% o
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    8 d( \  G6 \7 c  `4 E1 r( g
      p  g6 }  H+ G4 J0 \+ R这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:; G/ Z5 a4 N' a# p
    * c* B: u8 K: u3 [" \
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    0 W0 M5 e7 m5 b+ h
    : I% l9 M+ v2 i9 D0 E) [b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]! f" [& _' }- s$ s

    0 }  R1 ]+ w, g8 L交换后为:5 y! ?) p" u$ _) Q  c- H0 {

    - B7 m0 a. B" q* B+ J7 \a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]* E; U! q, L, A1 N$ R# k1 u6 A, ^

    # f9 R; s5 O0 d& y; p  \b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    $ U4 k- ^9 g0 }% `3 M
    ' s% N; G6 Y% a6 n6、突变2 l/ [4 U) x7 v, f( s
    ) C/ U' f) m5 N/ v* H; l& k3 o
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间4 E  s- T! I- ~6 D
    0 \+ Z& o8 x% R, z5 X8 V8 k
    二、代码, p8 W3 F" `- r2 ]2 o0 K$ ?+ E
    def b2d(b): #将二进制转化为十进制 x∈[0,10]
    % t2 h9 |" @, _( q$ C* V+ z        t = 0
    2 S5 {  m. v1 F3 V; }, R        for j in range(len(b)):
    4 D4 p7 V2 q, r) F                t += b[j] * (math.pow(2, j))
    . e/ D: t! f7 e9 ^& h        t = t * 10 / 1023& ]6 t8 l7 U: M, M4 S1 z* _% q
            return t& o. D  ?$ T' A0 a' a. ^1 \: r" R
    ( f: @8 z, E1 q
    popsize = 50 #种群的大小
    - `4 E+ e% G1 {! O7 |0 Y7 ^5 d! r. P#用遗传算法求函数最大值:
    # h, h9 m6 r) y6 E9 K2 n5 P#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    8 H% ^+ K" ^& b/ z" {2 n" N3 P8 o/ I. H
    chromlength = 10 #基因片段的长度
    ! T( ~' {6 O3 N$ [5 Ypc = 0.6 #两个个体交叉的概率! y2 W1 q1 R, E( U( w% ^% n6 X8 `: ~
    pm = 0.001; #基因突变的概率
    ' j- T/ U! r: f5 p, Dresults = [[]]
    % o' _6 P/ Z+ r- Xbestindividual = []
    ' n; R9 ]' R! @bestfit = 0
    3 E' x+ H- ]$ l5 d3 S$ P& @+ i; Cfitvalue = []/ K/ l7 E& M* v$ c' i/ \: c
    tempop = [[]]1 W( v2 U4 o3 G1 y0 o4 t
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    3 A) ~8 e) S1 `8 ]. m, g* |for i in range(100): #繁殖100代- ]1 N3 k; d" P; ^; _+ H+ K
            objvalue = calobjvalue(pop) #计算目标函数值
    3 V: g) t" v$ Y2 ?8 _, @9 X        fitvalue = calfitvalue(objvalue); #计算个体的适应值
    4 ]7 K% C; U' ~        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    # W( J' n" W5 a        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    , B3 T  S% u- ~5 E* x        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    + A  j# j$ b/ T5 z        crossover(pop, pc) #交叉繁殖
    , V6 U0 N0 x% h8 y% x* t( C) K        mutation(pop, pc) #基因突变
    : G) c* C: C* @4 e        9 Q# f9 _1 P* B: B' W8 w

    $ q! O- V0 C8 Q- {5 Rresults.sort()       
    " N' y3 U$ u) T1 r2 E- M: i7 X! Rprint(results[-1]) #打印函数最大值和对应的
    # d% q4 l; k2 ^7 k, bdef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    3 I/ b+ i5 ~" o; J% u    fitvalue = []8 e) [3 W6 V3 \, Y7 O1 x! X9 R6 S
        temp = 0.0
    ; Z6 g/ R/ K6 Y2 n% h2 ?    Cmin = 0;! H2 s& {, h6 T' V
        for i in range(len(objvalue)):* i( t- p' X# ~7 L
            if(objvalue + Cmin > 0):
    - G2 E/ K0 G+ c3 a+ G3 m  P            temp = Cmin + objvalue
    4 |' a! O. `8 ^; w        else:7 e, j6 s, W% c
                temp = 0.04 V2 A2 s  @- y4 n* k/ J0 `+ c$ H
            fitvalue.append(temp)0 g( C; G2 s- U- D
        return fitvalue- j7 N" [' p" ~# z1 Q- B+ R
    import math
    1 h  H# e% A& \" K7 W- J5 f
    3 X. j3 k/ Q" G  ~1 y. @) }% Vdef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)4 r4 I; X8 M9 D9 B4 _; x. z
        temp = [];$ I) K7 t9 Z* i
        for i in range(len(pop)):+ z* ?) ~5 A" v% z# e
            t = 0;
    ! q/ a- V! ^9 y6 K+ Y) ^        for j in range(10):: ~3 H; {2 O; e
                t += pop[j] * (math.pow(2, j))! h; k3 V9 y0 r; }% ]0 e
            temp.append(t)/ P# b1 t. p/ d& b9 f" y& O! B
        return temp4 ^2 M5 k  @: h: t! [

    3 t6 C; J! t" b' ~2 z; o# |def calobjvalue(pop): #计算目标函数值
    ; o* Z; U; h( D/ U    temp1 = [];; X6 R" R+ z4 S  R4 L) g6 D
        objvalue = [];
    ! E4 J5 r, W5 x+ }+ r  n- \    temp1 = decodechrom(pop)7 @5 C3 K- R. }- `  B3 q
        for i in range(len(temp1)):
    5 Q& l! t4 |& x4 M9 H1 J        x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)7 t+ P5 q" M- s" K
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    2 Q' s& ~9 L; k* B$ Z0 x- g' _" o) ?; W    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    ; q/ ^- X4 x3 a; B1 N9 X' q. I! q6 ldef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体3 J0 I- ?) Z! B' {5 @. |
            px = len(pop)
    6 \* R5 C5 C! U+ F4 H/ _/ U" }& y$ S        bestindividual = []8 b  y7 e+ b! g" v7 h# C$ K
            bestfit = fitvalue[0]4 }$ a( a1 R/ K4 ^' q" J+ G2 ]9 Y
            for i in range(1,px):
    : ]0 U* |4 n3 c; I                if(fitvalue > bestfit):2 O0 }& b) L# S4 q2 h/ C7 ]# J
                            bestfit = fitvalue- q1 O, l  r2 M
                            bestindividual = pop
    4 Y- n4 {% C) Q' }* ~        return [bestindividual, bestfit]
    + |, g' w# n  F+ Dimport random1 C2 E1 b0 A2 g- M$ {# D

    9 z6 n1 A7 Q9 Z2 xdef sum(fitvalue):
    % B9 T1 s1 q9 n3 u2 _' w/ V" ^7 a    total = 0# Z  F# ^9 \; r% ?3 l
        for i in range(len(fitvalue)):
    6 O. D$ n9 q* H+ N        total += fitvalue
    7 B% n, X- F( U    return total  R0 e" x( j* [; w7 D
    9 b. S. L/ K* r2 g; q/ Y
    def cumsum(fitvalue):& i9 }+ ^5 D( |/ s8 q' I
        for i in range(len(fitvalue)):
    7 O5 P* E8 |/ J7 X( p8 ^        t = 0;
    1 m# V/ U! H/ Z* p6 u9 Z7 n* W        j = 0;7 E/ `1 D$ ~9 p+ L) Z- ]6 f
            while(j <= i):
    : n# n) Q/ P6 c% E            t += fitvalue[j]
    ( X( H! y% U) v% @            j = j + 1+ ?' F2 h! S5 Z+ p6 `  E" m
            fitvalue = t;, H& W0 E1 p9 i6 Z+ N

    $ B6 b( N( p3 U* Y0 pdef selection(pop, fitvalue): #自然选择(轮盘赌算法)
    % ~3 t0 }0 o$ I6 V5 I* _        newfitvalue = []1 Y! @. l8 |! K) V( \% A
            totalfit = sum(fitvalue)
    , P0 Y. b, j( _1 X        for i in range(len(fitvalue)):) F4 F& }: ~+ C1 Y2 o
                    newfitvalue.append(fitvalue / totalfit): e! H3 b4 n, [
            cumsum(newfitvalue)
    ) J; g: D; A/ g1 H3 T5 r* _  P, |6 F        ms = [];  s0 ^% c0 O6 r: B
            poplen = len(pop)2 y7 ^* z1 @; z- I; q/ i1 M
            for i in range(poplen):
    - {2 W9 p  ?( E3 ^2 p( Q( W. Y                ms.append(random.random()) #random float list ms0 l8 y- V& C- F
            ms.sort()
    2 `0 @! f6 p) z8 _1 G( I0 F0 c        fitin = 09 Y; p# H4 ]; u8 a- N8 c
            newin = 0: l8 v2 O0 E+ q# p. q, u, z
            newpop = pop
    4 u) h, }2 x' u6 p        while newin < poplen:
    ! _. I% J$ W' E0 V6 u                if(ms[newin] < newfitvalue[fitin]):1 u" E: l; C! V( ^1 L5 k
                            newpop[newin] = pop[fitin]( F* M9 i) F( y4 n! }
                            newin = newin + 1; {; Q9 J5 V+ J& u' x
                    else:
    - x, v5 z" T5 r2 _; ^5 \% n                        fitin = fitin + 1
    ! |: q' s& E" T1 H3 P% j        pop = newpop2 a+ ]: m2 {1 L2 r) W$ m& x
    import random
    2 M! p( Z/ r9 s( ]8 Z
    & w& Z- }4 d) E( cdef crossover(pop, pc): #个体间交叉,实现基因交换
      c  J2 X# _. p# }5 w    poplen = len(pop)! d3 j. m. o' ?7 Y4 N
        for i in range(poplen - 1):
    # Q! y' q' y5 H: K7 B" L        if(random.random() < pc):! |0 B  L; e: ~% v
                cpoint = random.randint(0,len(pop[0]))
    0 H+ ]9 k/ r6 K% ~/ [            temp1 = []
    / C3 S% s# `1 r            temp2 = []4 T: S9 Q8 E2 k5 d0 X  T7 T3 a; V
                temp1.extend(pop[0 : cpoint])
    , u3 F. B* B4 C! ]; ~) U            temp1.extend(pop[i+1][cpoint : len(pop)])3 }6 v$ u  U0 w$ r; f0 N, F6 ^
                temp2.extend(pop[i+1][0 : cpoint])
    3 n& G6 W4 h! m/ b# ^0 |5 U4 `            temp2.extend(pop[cpoint : len(pop)])
    / S, F# `4 x- ^9 O) r            pop = temp1% u* v9 V/ m$ I9 J1 X6 E* x
                pop[i+1] = temp2
    7 p4 \! y) t, P8 zimport random
    % x+ N, T+ R" L+ ]# V7 I  Y9 x6 |4 G) O  p9 f1 y
    def mutation(pop, pm): #基因突变
    7 r$ W# H) K8 O    px = len(pop)
    ) z: V4 M/ s3 s# y    py = len(pop[0])5 E' Z0 V/ e/ R
    * Y! F/ q* F! K0 \! G+ |' i/ a
        for i in range(px):
    3 F& A, D# `% a5 \$ R. ^/ D        if(random.random() < pm):% [. D5 X# R: E
                mpoint = random.randint(0,py-1)/ a( G4 F# T+ [7 J2 T+ {
                if(pop[mpoint] == 1):8 [/ |/ `: Q0 b6 Y3 P
                    pop[mpoint] = 05 e9 t! d7 [0 q( j9 L+ g1 |: Q
                else:
    , g% ], Z. `" t: A3 g( l6 E) k                pop[mpoint] = 1  {7 n( p1 f0 K

    & M7 k6 \7 Y! L* m8 r) [2 ~
    0 N8 F( s' Z" Q: D  t# l7 J/ h————————————————+ z" ?2 w+ L+ m; R2 N! ^  O
    版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : o0 A9 n4 v$ {7 g) B' W( J- p, M原文链接:https://blog.csdn.net/u010902721/article/details/23531359# G0 C: C1 o/ N2 @. c2 C
    $ G  r5 ]" e7 i- b1 b" a6 f9 a- B
    / p8 U, W3 L: E/ ]
    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, 2024-5-8 00:02 , Processed in 0.459461 second(s), 50 queries .

    回顶部