QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5971|回复: 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实现的遗传算法实例(一)" Q& S6 r" \. a* S; C0 X
    2 a  q  o8 l" }* i2 d
    一、遗传算法介绍7 U# X6 `3 J+ a0 ?

      G; w7 S5 ~9 ~6 F- |- w        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
    - l1 j4 ~/ j! @8 Z        f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10  D% X, f) b5 g& t8 i, A
    5 Y' Z9 l7 ]* L4 k& V$ M* p' Z
    1、将自变量x进行编码, W) p2 n. g/ n' r) N2 ]3 ^+ R
    5 k% B& J6 v2 L
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    & W! o9 P! C. B+ N3 g% t+ N  ]& b4 H! R2 b  k' h* h
    2、计算目标函数值
    ; V: I2 H" B0 C/ I6 V1 Y3 l
    7 t- v" E3 v2 b# |9 Z$ G, L      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。* n7 L% H4 F& ^1 i( s! ~$ v! `
    3 p* [1 H# H$ y
    3、适应度函数
    4 c( h) Q% Y$ c9 p& Y* z8 z$ h$ b$ ~- P) q8 {* A; o4 C( u6 r9 O1 z
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    2 q" P( D/ [5 N4 Y! z* f1 b2 T4 }
    % A- _$ j8 P1 ^! u1 T4、自然选择
    , n! ~% U( ]. l; j' H& u4 V( n5 B) ?; v$ z2 U7 M8 _# t
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    4 P0 W# h9 y) b' ?  r$ t3 r" `/ k
    ; f, }1 q& K: _( y/ c% _  A& F假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
    $ r  _1 q0 H: ^4 p
    " Y3 F# J4 c% D0 U5、繁殖3 \+ f! G) |& p3 b6 m2 t
    + I# q2 A# M! D2 n0 f% f* v; g& y
    假设个体a、b的基因是
    + G" m2 U/ y) @! w' ?8 ?# V2 P4 Y2 T# p" s6 I
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    ; l! i; E' S& O# _8 N: I" N
    # p% K! x9 F' J* _7 Fb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    8 G+ D! F$ v1 b$ E+ q) ^: X
    & ~2 A3 H- }, J& Q9 A& w) N# \这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    # B% B; S, \9 S, r; f" ^$ Z1 @. {! \- r
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    4 _4 C8 c& S0 j; z) _; {3 x" ?
    1 y! s7 M# ^$ h& h4 F) [0 Db = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    ; q. f- x7 X9 t7 r1 E6 e2 k9 X2 C5 D+ I8 T0 |6 L* D6 y
    交换后为:7 {& y+ k0 U2 h, v/ @0 i4 C
    ) B$ m3 v. C; w, M- \# ?
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]. E4 {2 g! L+ p' T) l

    8 ]$ b( ~5 G' w7 G' Fb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    ' l: L# F8 G% Z: D0 F
    6 o! c* u& a5 ]! B0 b* j5 I) \( \6、突变
    " _) ]3 k9 R! O
    - d- r8 B! }1 \  ^4 q. U遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间- r- Q, p) @" R$ v/ a& }. ?
    + m9 z" x: i3 U% k
    二、代码
    ) K9 E5 D& j' n9 _def b2d(b): #将二进制转化为十进制 x∈[0,10]
    0 f" i. y/ T- n1 |; e  ~        t = 07 O$ @9 a' c; y/ R( P# d" f
            for j in range(len(b)):9 n8 p) H8 ?. l: I
                    t += b[j] * (math.pow(2, j))" X, o" |+ O* B& n3 z
            t = t * 10 / 10236 [$ p& K! N4 d% \0 t# U
            return t
    ) s0 V7 q# L- `3 m' J/ f: H2 @( r3 o" K: h2 j0 ?
    popsize = 50 #种群的大小
    ! d1 h: z5 C; V6 B9 G# D1 U#用遗传算法求函数最大值:3 Q8 H3 l. Q5 V
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    , }2 _5 a9 C' g6 ?) P0 R, G- Q5 `, {- o+ c! `+ m, {: x6 b" ^9 ~
    chromlength = 10 #基因片段的长度
    $ [+ ~( [! a. y9 w; s8 Zpc = 0.6 #两个个体交叉的概率8 n* c9 C9 |; y) m, L5 ~- r
    pm = 0.001; #基因突变的概率# G: o9 [8 `/ n1 t! ~" W
    results = [[]]! m8 _- Y' J* h% R! ?/ I2 w4 M
    bestindividual = []
    1 q: e3 A0 N' cbestfit = 0
    6 e2 x6 Y5 d7 L; c9 `/ f# I- }fitvalue = []9 g) ?( Z, Z# {" f% T7 u
    tempop = [[]]" T! Z) ?7 H. [. m$ u
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    1 }' R' Z8 F3 f# ~% Q# r2 kfor i in range(100): #繁殖100代6 z* {4 c! I# v$ ~8 D) R
            objvalue = calobjvalue(pop) #计算目标函数值
    - J" C9 W$ p6 Q5 ?. V" Q        fitvalue = calfitvalue(objvalue); #计算个体的适应值6 R$ }" @4 |& S0 A0 h" k
            [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值# m9 S; |3 r3 E  s, @
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    ( K/ w6 G. j3 r$ S4 J6 s3 U9 K        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体9 q2 R6 u* E1 B1 ]8 Z$ R
            crossover(pop, pc) #交叉繁殖* ?4 m8 J) |$ t8 X0 e& F) o6 ]0 c$ T6 B
            mutation(pop, pc) #基因突变' B2 N% K0 a9 w: C
           
    $ L1 ], h* C( Z9 G1 P
    ) K" J+ M" G' `2 `% [1 Presults.sort()        + z4 J. X0 F+ T: R1 y& s. W
    print(results[-1]) #打印函数最大值和对应的# ~; G" o% O4 v  m$ q
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。7 U" [7 L5 G! z" _% A
        fitvalue = []2 m* J. V/ h& c5 L' Y3 Z- Q
        temp = 0.0
    4 q3 d1 `# w( c1 j0 z    Cmin = 0;
    6 b9 q' W: e' P" o    for i in range(len(objvalue)):
    7 X' x' x1 U" n( J3 \/ g        if(objvalue + Cmin > 0):3 U' y9 ]- f! X7 d0 w3 J0 J
                temp = Cmin + objvalue6 p" I) h) r% W0 P3 K. a
            else:
    5 d* V: U2 W% C6 C            temp = 0.0
    1 U2 J' f+ M; q- o6 k        fitvalue.append(temp)
    ! B& A+ G* I3 e  ~! f1 u& ~    return fitvalue
    + H" Q; h" D8 @6 Z4 }  I& \import math
    * O! R8 X; X/ g& v9 ]" K; C2 r
    2 H2 a3 H8 `+ J' L7 K# s2 hdef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
    $ h, I& W9 u0 N& h" f6 p7 [    temp = [];
    3 e: j% x; l$ I! v    for i in range(len(pop)):
    + B8 [+ C5 f0 [8 P. c" }        t = 0;- N$ j4 ]; j% B. n' O* y
            for j in range(10):
      H8 K$ ]' W& q8 U, `( C6 l            t += pop[j] * (math.pow(2, j))
    % ~4 M# G3 y, r        temp.append(t)
    4 n' `+ w/ \& d( H$ `7 I# ^    return temp; }- G, y. A. l4 h. o# I
    3 ?- g7 g5 y8 t/ T
    def calobjvalue(pop): #计算目标函数值
    9 Q6 p2 Y+ T, z9 l) Y    temp1 = [];
    ) L  r/ D1 J' t6 F8 p; O: G    objvalue = [];
    + `& s  u, N( x: K    temp1 = decodechrom(pop)
    % m  L; c% E  F3 _; _: k/ Y' q    for i in range(len(temp1)):
    ( r' x  [7 g8 J% X& E! R        x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
    * R" V; J& M& K& A6 \5 c  d        objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    4 X: m8 T" t, }4 |    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 $ M) ~- ]) n( U
    def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体- ?" m" c! v5 u
            px = len(pop)
    8 a8 K7 n' N/ l        bestindividual = []3 x) Y7 y& K) U
            bestfit = fitvalue[0]
    ; `8 L8 J9 f0 [: K        for i in range(1,px):
    6 G$ J1 B5 d6 R- f  U" Q                if(fitvalue > bestfit):; v2 O1 S" i. ^: D( x5 A
                            bestfit = fitvalue
    8 D% U9 c! U5 q6 S. o                        bestindividual = pop
    7 u" b* Q7 ?% Z5 Y9 J8 U; W        return [bestindividual, bestfit]0 t3 L, a: @' `* K
    import random
    & h8 u/ D$ X1 m" R/ N' Y0 T  K
    4 x; ^5 Q: i+ w$ \( n+ ^  @def sum(fitvalue):3 T8 ^" s5 a- M: D4 }/ ^# e' m
        total = 01 r0 g6 K( J7 N4 r+ o( @
        for i in range(len(fitvalue)):7 H; Z& t# g9 s4 S7 u
            total += fitvalue
    % g0 b1 X& y; m2 |& m/ j    return total
    8 V7 S1 `$ B7 L, N3 ^$ [5 u4 T1 }5 M8 I1 y  x! Q: z. x; E: i
    def cumsum(fitvalue):* S2 b" e: }3 Q7 a) ~$ O
        for i in range(len(fitvalue)):. c( B: \& ~; @" ^) _% J! l& b
            t = 0;
    - t; @, x) }4 F        j = 0;6 d  ?) b% N( R2 l
            while(j <= i):1 n: @* d  R* H0 ], F2 z
                t += fitvalue[j]
    / X& r) e- W5 o$ w8 H5 h            j = j + 1! G* L$ ?2 s1 D/ ]
            fitvalue = t;
      k: \; o7 {! `) ^# V. l7 N5 E* c$ e% q; \& U$ Y4 ]
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)0 o1 u. M) R& B' m
            newfitvalue = []* r' k) J9 k9 k9 ^5 V2 a+ f
            totalfit = sum(fitvalue)
    3 @" w. q5 M$ O. X        for i in range(len(fitvalue)):
    $ w' ?* r/ f& Y% _* T                newfitvalue.append(fitvalue / totalfit)
    - U  h# U" O$ D) |. k( h        cumsum(newfitvalue)
    9 M8 q0 |# \# F5 ?, b  u  `/ H        ms = [];
    6 K+ C% p! C8 q- X1 q9 J        poplen = len(pop)
    2 ?  `. g; W, k5 E        for i in range(poplen):
    % v8 P: B, {8 J7 {2 G9 q1 G: P: r                ms.append(random.random()) #random float list ms* M- f8 k$ M* `# a$ @9 W
            ms.sort()
    1 e: |* X8 Y8 A' O0 O) \* J        fitin = 0
    7 H' ^0 R$ t2 q5 v/ [4 w, A2 f        newin = 00 k. C! [% ?. x/ d3 V5 F  K
            newpop = pop5 c; e$ Y& d+ M5 k1 ^
            while newin < poplen:
    # `- L4 I+ E8 }; l. f                if(ms[newin] < newfitvalue[fitin]):4 H. S1 d* [3 z; t
                            newpop[newin] = pop[fitin]8 F; G% o% V( `+ a) K) b
                            newin = newin + 1
    ) y* W* E0 V7 A6 N                else:+ N" H5 \- E) A, s8 \; K
                            fitin = fitin + 1
    ) ?1 B3 O8 @+ @* ~  O3 e( p        pop = newpop
    " J8 k# f0 g. O: ?import random( c0 p  P7 q  s
    , L7 s  b* R/ Q0 `* N1 w/ B: f0 a
    def crossover(pop, pc): #个体间交叉,实现基因交换0 b% D2 M" p/ F  o6 ]! S
        poplen = len(pop)
    7 o/ x8 O$ e$ {$ Q3 O: K    for i in range(poplen - 1):
    + w! x" M4 t7 Y3 k8 j        if(random.random() < pc):
    * C6 d: E8 U$ r            cpoint = random.randint(0,len(pop[0]))
    0 v9 A( R! n5 |. x* W) H            temp1 = []7 I! I6 x9 v3 R; X
                temp2 = []# I- }- {0 F& v3 l4 t3 E
                temp1.extend(pop[0 : cpoint]), b, a' y" t4 V4 X: ]  j( }
                temp1.extend(pop[i+1][cpoint : len(pop)])
    * Y0 w2 o  n% M6 |( x( r% F  o8 J4 Z            temp2.extend(pop[i+1][0 : cpoint])
    " Q+ K( _/ ]$ T' p2 Z            temp2.extend(pop[cpoint : len(pop)])
    6 \& i+ v7 K% @" e5 F            pop = temp1+ T6 r1 C; Q' S$ I2 O
                pop[i+1] = temp24 `; A  B6 K* e8 u5 N) ?
    import random
    . v3 a1 [- a2 b! w) @/ h2 @
    + c* a+ H% W$ G# W7 y+ c# P2 W2 _def mutation(pop, pm): #基因突变9 L" `, \% K# y5 ^6 ~  ~1 k
        px = len(pop)+ l9 r. j& k% b$ t# d
        py = len(pop[0])) {5 g9 Q8 b8 p+ e! p  W1 t8 N

    , `. V2 Y% n0 e7 @. [* h    for i in range(px):
    % ^$ X* V' u' k3 d$ _1 Y: q        if(random.random() < pm):4 g! b2 H) w3 g( b
                mpoint = random.randint(0,py-1)
    - x/ J- i: E; }& M            if(pop[mpoint] == 1):
      A; }" E* U5 ]                pop[mpoint] = 0  J! ~, n) V# K9 k# R/ W& e
                else:
    ) T/ a1 J5 y* ^3 p/ G                pop[mpoint] = 1
    & z0 ^; }9 t) Z3 m
    + L: n' H: V7 L# |% d5 Y6 Y. Z
    0 G! s: `: w7 [" m9 k3 e————————————————7 Z  j# k& S2 P0 q9 W8 \
    版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    * c. V4 P# `4 F原文链接:https://blog.csdn.net/u010902721/article/details/23531359* o3 ?' ~/ d. l' g
    % z8 g: u# M9 U0 r- V
    ' w1 U; ]1 p4 w) P/ y8 R: @
    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-18 06:12 , Processed in 0.349492 second(s), 50 queries .

    回顶部