QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5977|回复: 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实现的遗传算法实例(一)
    / t$ ~& M$ b/ h& Z; R% {6 g0 ^, D  O- L6 T" X  J0 W
    一、遗传算法介绍
    - m8 p8 G5 g& J) ~3 E- i' l9 P3 f* U- l
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。' f" J1 s/ _+ s: f  Q
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10
    5 E+ Y0 O; F- f) e6 c' w* d$ o( t4 g2 b7 d" f
    1、将自变量x进行编码
    : Z& y3 m! w4 d0 Z; b* M
    / b; {8 O+ U4 J( \6 t3 l) b: J- m. v1 E      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]2 k/ _, F" f; F; {- E
    , r& [: o, I2 [5 [" \/ Y2 O$ I
    2、计算目标函数值
    3 o# D* _( g* m, L, L1 _8 E& ?8 h& A2 H
    ! W3 ^- R: N* X      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    2 g" u' O, M: m; t9 e, f
    ) r  J" I: q! Q8 _+ E+ `) l3、适应度函数
    0 e3 ?3 I8 d! i/ E- J' Z1 h) v, ^6 M" \, E( e
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    & p# U8 N4 K5 `) o, D! L, X; j( ^% a7 f+ ~' v' a) d. x
    4、自然选择/ W8 ?; h: I: O2 i
    - _/ [% p0 D/ C0 s! `  _- ^
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:$ X8 C; A& F* c( P

    1 c8 ?& {  N9 }/ C+ G2 l% X假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。* z+ U' ~/ N3 G7 P5 D

      @- z6 D) E" J' `0 p) G5、繁殖
    ) X! r! r: S, ^9 P1 E% V' y9 D3 n6 v) ^
    假设个体a、b的基因是4 K$ X: I8 h5 G
    4 H, E5 a# Z! M; u" F5 `4 O
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]! `' n+ b( V7 ]) |+ n
      |. h$ x; A  v( y
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    0 b2 J. ]# u% W) [/ i
    0 e3 ?- D/ a4 [7 J% ^% T4 P8 G* q这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    & o- J. z( S- Q) U: Q7 i) U3 k, X" f
    5 z5 k, }9 u8 Oa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]* J1 W' m) V+ G; y6 _) g3 G0 f9 {6 Y

    3 O) }# L) m- R, xb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]4 h/ Q1 V5 n1 X1 b$ y8 V
    # o: i- c# y0 L- H1 `
    交换后为:
    ; a& r6 J6 O( R& v& ~% d1 h/ y5 {! s. O( M2 g. L7 ?: C2 z* E& ~
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    4 N5 z" o6 P- x6 X% l- c2 U
    2 Z: A8 T; [/ j: {$ f2 j6 e' ~b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]( S" t6 X# p; x, e5 e$ j/ L7 s
    * L5 K: z) q! j" {" B4 c
    6、突变
    $ p7 g5 I% C& J+ y2 u. t5 b
    . t8 n/ ]/ n2 k% P5 e/ A; L$ Z. a( ]遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间, q1 `( W5 p# g. S1 u

    5 [3 M1 R* g' I2 I& E1 w- p/ c8 J二、代码
    2 x% W4 b. n5 c( R8 W# ^def b2d(b): #将二进制转化为十进制 x∈[0,10]* n5 U, m  n1 N0 t
            t = 0
    . k& e$ D+ t: [* {2 V, Z; R        for j in range(len(b)):
    8 g* \2 d2 h& b- m( {- c                t += b[j] * (math.pow(2, j))
    5 D5 r% P0 r* F& ^        t = t * 10 / 1023
    4 B6 I4 H, V* g* t% B        return t9 z; U! V7 P6 N$ h4 L& G) R2 ?4 G5 U  W+ }

    . ]% O& k( g% I4 m5 bpopsize = 50 #种群的大小  `0 J0 N! h: D/ Q+ j6 I6 Y- `
    #用遗传算法求函数最大值:
    + s5 X5 ]9 I* o3 H#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    / k8 v* r6 b" G* y. t) d0 I9 y0 G2 t
    chromlength = 10 #基因片段的长度
    ) l8 y) b5 r) M7 ^8 o' Rpc = 0.6 #两个个体交叉的概率
    ; q1 W' w0 |! f! \, k$ Spm = 0.001; #基因突变的概率  K3 a( M# l6 d2 Z
    results = [[]]: P; G- y  d1 |7 f$ ]& ~. r5 A
    bestindividual = []
    $ ^; I4 l( l: B: \; F# b, t7 u' qbestfit = 0
    " e5 r) ]' `  N' C1 Zfitvalue = []
    5 s" S, B( w& V+ u* H* Q/ Xtempop = [[]]
    ! r  T3 \' K/ E7 c7 d4 @7 J+ i5 y4 Dpop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    , {1 e( \7 P/ |! Cfor i in range(100): #繁殖100代/ C' `8 t$ g9 x' Z- ]$ G6 d7 s2 M
            objvalue = calobjvalue(pop) #计算目标函数值$ l7 @) S' K! |2 D
            fitvalue = calfitvalue(objvalue); #计算个体的适应值
    " A* ^; o: q: A" o0 E        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    ( L5 k% f2 R$ H# p4 C        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来: T8 v9 G2 A1 b6 S9 I: D: C
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    3 P- h. ?5 Y# E- D9 u! P        crossover(pop, pc) #交叉繁殖+ T. F! B: b$ y7 o2 m4 X5 |
            mutation(pop, pc) #基因突变
    & |7 u! ?' N) D' e! ?       
    $ z9 X7 I2 a7 I5 R  l' w- k  b1 E  `3 P2 h
    results.sort()       
    5 ?; v) s1 p/ eprint(results[-1]) #打印函数最大值和对应的
    5 X! L8 G  e) w4 l# S& }def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    # [! Y6 e+ F, k- H+ p  x5 Q    fitvalue = []
    8 {' ?7 c) F& u6 h* Q6 u    temp = 0.0
    $ X6 K+ U  q! c3 e1 e+ u    Cmin = 0;
    + w' y# A+ a# F# S    for i in range(len(objvalue)):! X7 l( r/ h# ^4 h7 R* Y
            if(objvalue + Cmin > 0):
    9 \) z. a( p* ]4 f+ F* q0 s8 }( o4 g            temp = Cmin + objvalue
    1 s. O% o! y( L+ e$ K# e        else:
    7 a! L9 X/ T2 U! H3 X/ N/ k) V5 ]            temp = 0.0
    % G- a) p: q, C6 I        fitvalue.append(temp)8 ?! f' q( X* V, \+ d
        return fitvalue( e" T7 o. U& [- e7 G% c* @7 g
    import math
    ; ]4 ?4 p/ O0 P, W" D, M* o. x- B. V6 O) ~# N# }  W
    def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
    . k, R* |7 E- d" |    temp = [];
    & _1 K  `8 O4 F4 }- m5 l* ]0 L    for i in range(len(pop)):" \4 h" o* n4 C' S& u' s9 Y' v  j* n
            t = 0;
    * l# y- i9 ]5 R7 P4 |' X        for j in range(10):
    ' ]8 g4 V& M- |            t += pop[j] * (math.pow(2, j))" v9 Y" P# E$ g2 X
            temp.append(t)
    4 N4 c, Z2 H3 r8 w9 W& ^    return temp3 i8 n6 o0 p3 M1 S% k( F1 U. e
    + ]; K$ j, ]& j* y* C6 R* x0 w
    def calobjvalue(pop): #计算目标函数值
    / `& p, q- ~& a! ?' v    temp1 = [];9 I9 }  v2 Q. P- ^1 T' ?
        objvalue = [];
    . A( z6 h5 t) i. k# p    temp1 = decodechrom(pop)
    2 U" T. ]/ f  G, N9 `    for i in range(len(temp1)):; w3 {  a' U" b; W/ g& y8 Z$ h
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
    . o% B  R  }' O% Y        objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))0 K$ X& d4 X3 c) X% D5 }  [9 D
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 6 j9 v# _3 ~. o1 s7 r% p
    def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
    - R3 v6 c! ]7 s  W3 w% y        px = len(pop): R1 L5 K4 |2 D' y! S% x
            bestindividual = []1 J! C1 ]* N9 X: ]' n7 P
            bestfit = fitvalue[0]( p7 y8 q+ i3 }: o) C1 H
            for i in range(1,px):
    + T, ]. L* i8 l  A' d5 K* k                if(fitvalue > bestfit):  x/ J9 X# y+ S9 c7 r
                            bestfit = fitvalue
    ! w' W% U$ M) s) C5 }6 K                        bestindividual = pop, w8 c: y0 R, g; i
            return [bestindividual, bestfit]
    . r& t6 c4 Y1 h6 g  himport random* P7 V. C% ]" K3 ~5 b
    7 o: X: ]8 ^* y4 H% E; }* V- R% ]
    def sum(fitvalue):- a1 d! k4 y2 c! s# g* n3 N2 ^& d
        total = 0
    3 Y2 h9 U/ T8 `& d) }  g7 j# n8 y* M    for i in range(len(fitvalue)):$ J8 f* B8 u4 T4 d. d
            total += fitvalue
    ! f4 ~0 q& r+ e# H1 m3 O) Z7 ?    return total
    6 O5 a4 N6 F" `2 a1 k" Q, @' y, }' K- g; M* t
    def cumsum(fitvalue):
    1 s' t! D) E' t8 O" C    for i in range(len(fitvalue)):
    $ N  K5 X: h7 J2 h        t = 0;% u2 v: [! y+ Q
            j = 0;
    ; I. c. r( O9 y        while(j <= i):" t$ l$ h. \4 G1 H. y% d$ x8 ]
                t += fitvalue[j]
    ( ~, y7 ?. G" q, b4 f            j = j + 1. F9 ~8 N: j$ J; J0 s
            fitvalue = t;
    # V, }2 t5 N$ P8 l( U8 `8 H: q+ o4 Q" A# S
    * q# m7 [- P4 `0 F/ E% Tdef selection(pop, fitvalue): #自然选择(轮盘赌算法)
    7 w) Z9 ], S  V, x# q: V9 G/ @        newfitvalue = []# Y( g, z. `* m2 o1 {
            totalfit = sum(fitvalue)
    $ J! h) S* |+ K% m- e6 L8 I7 C        for i in range(len(fitvalue)):
    4 V9 F, D$ r0 ~$ w- b4 a" g& W                newfitvalue.append(fitvalue / totalfit)- D; g: J7 Y5 k5 }8 u& [3 l8 C% {9 s# _
            cumsum(newfitvalue)
    - x4 u. d" M. X        ms = [];
    / `& ]+ V& r! u4 d" N        poplen = len(pop)
    ' I1 k: {7 D( r. S/ T3 c2 Y( q6 j        for i in range(poplen):2 j: {( n3 y; [& J, H+ r/ ]3 O
                    ms.append(random.random()) #random float list ms/ G/ P; q; L3 j! t1 W  Y& {' y
            ms.sort()
    ; s- Q( J# h' g0 ~1 S) x        fitin = 03 i4 Z) z" z6 F0 ~
            newin = 0
    ) r8 m- h- N2 Z& t3 ?: Z        newpop = pop
    ) m- n& R5 \4 s( B        while newin < poplen:
    ( n7 S1 |7 P) F9 p4 }% B  m                if(ms[newin] < newfitvalue[fitin]):3 S" g/ _1 Q0 N( a+ l
                            newpop[newin] = pop[fitin]
    1 g: P* r" S# h( G                        newin = newin + 1* t7 @) w8 m: }5 e1 i6 c" O
                    else:  {4 Z, k/ w( }- H" c
                            fitin = fitin + 1
    1 w: n% y" O: b7 }6 N7 B# L        pop = newpop
    " T! D0 k2 f4 Q0 Rimport random: ^( F$ X' _1 T# h7 c* b  [

    8 Z% `4 S( _" E% Rdef crossover(pop, pc): #个体间交叉,实现基因交换
    4 q' V/ _7 `; i. k    poplen = len(pop)
    : x5 E$ X# A2 }2 J! G    for i in range(poplen - 1):
    * a: V) g% l4 ^9 V; Y        if(random.random() < pc):
    9 A* |, \1 R' p9 ?% V4 t            cpoint = random.randint(0,len(pop[0])), c; `2 S2 u8 @& [
                temp1 = []7 Y' Q8 _  E$ l, K
                temp2 = []
    8 B4 }7 k* r! Z            temp1.extend(pop[0 : cpoint])
    8 B$ J* s% l3 n( V7 V            temp1.extend(pop[i+1][cpoint : len(pop)])4 R( T( |3 Q2 W4 E0 g4 _# V
                temp2.extend(pop[i+1][0 : cpoint])
    . E/ A& J# j! k( F3 E( ^% D            temp2.extend(pop[cpoint : len(pop)])
    4 \: Q  T7 ?2 o' J3 G" w; r            pop = temp1
    5 |5 u, p. g) a+ K0 g  d- m+ p! j            pop[i+1] = temp2
    5 x5 Q3 R* M) g1 O( H7 simport random
    - S* F: _; D' S% ?6 r& D* C: d7 @* T$ G& }$ i
    def mutation(pop, pm): #基因突变
    5 c& A* J6 R/ O, y    px = len(pop)
    ! M3 F! v3 S* a3 w) W    py = len(pop[0]); B. W( F' ~% H! ~0 l) V
    & R% }1 s! i# }* ]& u
        for i in range(px):: P! l6 W5 U$ o
            if(random.random() < pm):
    ! K4 w( O( O( l: |) H            mpoint = random.randint(0,py-1)# C8 A5 u5 q  L" R
                if(pop[mpoint] == 1):
    3 o) m: Y) y" X6 q                pop[mpoint] = 0
      o" b+ u: `2 _            else:
    ) f- {! n/ q. U* ?+ k7 F                pop[mpoint] = 1% m* G1 j0 f. \
    " V( Q; l& b, u
    ' h+ H$ b' T& B0 r, A: u2 K" f
    ————————————————
    ( N7 O0 P. s3 u版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 H; b; y6 T, B1 s原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    ! i6 A' K/ E2 _5 i5 A, q; c$ F& |; P$ a
    3 \, n. l2 }4 N. O) p
    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 16:57 , Processed in 0.402091 second(s), 51 queries .

    回顶部