QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5990|回复: 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实现的遗传算法实例(一)
    ; S! W/ E' B/ v1 \& _7 h, u0 U, |$ m6 e' `
    一、遗传算法介绍
    7 J  o) ~$ I* ^. D$ i+ S: T" g, u" V' q' v; I" Y2 z6 v
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。7 q4 f3 z  }/ V' M
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10
    8 \- M6 b1 c2 k1 o, j
    : v1 w9 Z' S3 |) F1、将自变量x进行编码) r4 D3 o2 O& @

    1 B  h7 u# \3 N1 d  h' t/ l      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
      {& g2 @" k8 y; E3 b, Z9 s' C
    2 r: `* Y% I% F. g+ W+ t2、计算目标函数值( S6 |8 _/ r( G4 m  n+ E+ i5 d4 K

    0 v3 J$ R- M: Q+ Z8 I/ u+ M      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    / k9 k8 @- l+ ~; R$ k  {( J3 Z' m! @9 }$ W
    3、适应度函数
    5 G) F( F, ]+ p5 F; I  n+ p9 g/ x, ^: v8 T% C. D7 N- C- W
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。8 f2 A9 `$ X; X& v: d3 `) {

    . M) ?3 F6 C& Q4 ?0 d7 b4、自然选择. r2 M. L! f. H/ G' v
    0 G8 X0 z, _# r% i- b) H0 C
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:, N0 T3 W/ V2 n

    ( D( }" q' H% P" Y( K; C9 U* v假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。' l  a* }5 ^5 y5 j2 d; V

    " v5 |) L$ j: S; F1 q5、繁殖
    " C/ w' K0 ]# s
    " U4 F3 ^3 L; h& K假设个体a、b的基因是8 ~7 |0 h- U7 k# y8 V# ]- `4 g/ f3 W- x
    1 Z" v8 V- P4 l  I% y' I
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]- ]' H& _! E6 t8 X& d
    % C6 R, S7 Z3 S2 C( v1 Z
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
      X3 [& ~; `4 P* \; i8 ~, D( y- H, w9 M) R  r+ ^5 l
    这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:! z4 z4 o9 d% R, |9 f7 e

    3 k$ m) u2 R& _7 f/ Wa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    1 o1 l! N4 \) f; p- s8 _) R- g" b( u) g9 `6 q, }/ C6 _2 C2 H' x$ n4 S1 R
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]7 a# g0 H1 E$ ^) ^

    ) q/ u' }( b: x3 H4 a交换后为:9 ]  ^# x& O- m1 j- h- O: p

    ; z' }3 ^$ h0 l: O6 N$ ?a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    : [- U% L0 ^) M' t% u. x0 U, d0 o3 ]2 v" k) B8 [% o6 k- m" W
    b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]9 B  x8 X3 k9 z

    . N/ g( E. }( j2 q2 U6、突变. k$ C/ r) Y. _1 h

    6 `- p( T3 J, b) [) n6 T1 R; s6 @遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间& z, ]2 i! }. f) P- F
    ; B9 @2 p& r& C$ G/ S, h. z
    二、代码
    7 c* f- @6 i5 I* g, w  E) ddef b2d(b): #将二进制转化为十进制 x∈[0,10]
    / N+ ^3 R2 N& @7 ~9 C5 M; L6 V        t = 0/ [! p) X! W/ ~" B" {6 a
            for j in range(len(b)):
    2 E% u+ @& P2 {  B9 }- ~$ Q' R                t += b[j] * (math.pow(2, j))- y) M5 q$ Q2 [! [$ p3 D. n
            t = t * 10 / 1023$ n  Y* |% _% `1 h6 }
            return t# I) _$ g- x4 w# P1 O! y7 _7 h0 _
      Y9 X5 {) q2 y5 I" Z
    popsize = 50 #种群的大小/ Q) `' q* g+ l* T" O& g" N2 \
    #用遗传算法求函数最大值:
    3 W/ d2 Y. @! i* @1 f9 c#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]$ s- _: s3 ?0 \9 N7 w$ R

    # O* P( I$ d) ichromlength = 10 #基因片段的长度# T9 P) s, n$ K. X, w
    pc = 0.6 #两个个体交叉的概率
    4 D1 S5 O6 D/ R' ~5 C3 ipm = 0.001; #基因突变的概率5 l/ _3 Z$ }, k
    results = [[]]
    , D2 Q" J* A. j8 d' ]+ \bestindividual = []) e, ~* \. b9 i- O; s
    bestfit = 0
    ' [+ ~* c/ E' [$ G: p9 p" {4 ufitvalue = []
    & Q0 q$ [  X% R9 o% V, u! V9 ptempop = [[]]6 o5 Z! e5 r2 c* s" u' _7 ~
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]3 p. x4 o# N% u  Y3 l
    for i in range(100): #繁殖100代
    : k: b/ ?' u7 W- [" Z        objvalue = calobjvalue(pop) #计算目标函数值& \  d! Y* S" [  @: q/ u
            fitvalue = calfitvalue(objvalue); #计算个体的适应值
    % I# E! r( \/ w2 e0 E) T8 @2 H        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值: d- h; j/ y  ?. n6 v
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    ( g; [9 `3 }( U! u5 H7 V        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    7 y  z, K1 X! Q        crossover(pop, pc) #交叉繁殖
    , H7 t. {, O! k/ y, X4 X# B7 A        mutation(pop, pc) #基因突变
    / k! ~' A% d) N0 f) S7 {       
    * V$ @2 r) Z. @4 K' u; w- u0 I+ _* ~5 A. d3 {2 O; c
    results.sort()       
    9 B$ p1 D" w" U& F! k) ?2 bprint(results[-1]) #打印函数最大值和对应的0 t9 x3 k6 L  I0 ~! [
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    - S1 q, P  ?+ p+ r( R3 F6 Z    fitvalue = []5 T% c" T- }8 r# r1 H2 I) }8 E
        temp = 0.0
    5 x. j. W8 N8 A/ g( T+ H    Cmin = 0;
    $ _. F& D) c9 D: {, P    for i in range(len(objvalue)):
    : ~- ]1 V* s  b0 h+ S  [        if(objvalue + Cmin > 0):- N- N6 S6 h. o2 K$ H& a3 i2 M& D
                temp = Cmin + objvalue
    6 \; N2 m7 k( i; X- @4 `+ o& W        else:! i8 N$ O+ o3 |4 Y# d$ O6 u: U
                temp = 0.0
      B' n7 {, |% D' _7 |1 a( ?+ k        fitvalue.append(temp)& u1 ^9 b, a1 Q* S+ p, V/ E
        return fitvalue
    $ S$ O- o. U" }* E/ w1 Aimport math; x6 i, ^/ \) _3 j, f' m. s4 B  d
    ; H' u# g8 ^5 b; Q. Q. o' t
    def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
    ' ]' B& A  ^7 h8 U" s: R    temp = [];7 z! V' i; M& n: W: [
        for i in range(len(pop)):+ N( K1 J! N9 {) P7 d& w# p
            t = 0;
    : [1 U5 q& M: X1 G- ^        for j in range(10):
    3 J5 H* s  L: t9 D! ?* G' p* C            t += pop[j] * (math.pow(2, j)), M2 P3 j4 }" ~) v
            temp.append(t)- c7 g! k. k$ R# W' u2 `
        return temp9 Q& R3 q- q$ t7 I9 d9 h$ R; N5 k

    1 u0 P/ y) _1 }# i, m, ?- m! j, Xdef calobjvalue(pop): #计算目标函数值5 [: ~- z" |, u5 g- F/ e
        temp1 = [];
    / E, `; I0 R- M, ~    objvalue = [];% {6 t) f. n; s. a' s
        temp1 = decodechrom(pop)  F5 d. r8 }: o1 v9 A) c# R
        for i in range(len(temp1)):4 n+ x: g( G3 |  I, E2 H4 W  _- V6 E
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10); R0 t. _5 ~% d0 K$ r: X4 @
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))& p1 b0 ~* i4 d6 W6 h' a% b/ |
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 6 k9 T" y6 I; p  o/ I/ a! P
    def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体( F% \* l. A0 z) G3 B
            px = len(pop)
    ) K2 z$ H$ V' ?; x! t        bestindividual = []
    3 i5 O$ [4 d8 v        bestfit = fitvalue[0]: r- V& _& S+ k- ~3 V
            for i in range(1,px):- I  u! z. Z& D# ]2 @
                    if(fitvalue > bestfit):4 L& a2 Q  I5 Q# b; r
                            bestfit = fitvalue
    5 I4 O, K$ f' Z* @* r                        bestindividual = pop# B9 v! A- J5 k& @# f
            return [bestindividual, bestfit]
    ! R1 R' j) V8 L4 c4 ]import random# u9 r+ M3 X6 }+ Q9 `2 l
    & s1 y5 Q. Y2 R# ~4 h- ~
    def sum(fitvalue):
    ) m- S, g( Z: Q9 C. K    total = 0
      w" g& g  {8 u# e; U    for i in range(len(fitvalue)):* D* E6 U! m0 E+ X: h: a
            total += fitvalue3 S8 q1 |' a  }) Y9 t/ }. x9 g
        return total
    7 b! o& {5 p* T8 o; H5 E  R
    6 z8 T# L2 b- N' `  n2 kdef cumsum(fitvalue):# S4 B8 B6 I# {# h
        for i in range(len(fitvalue)):
    ) r! E& G/ ?( p0 g7 p) A( K# P        t = 0;6 C! {" v" u; E0 u0 r
            j = 0;2 V+ H1 l) p% C2 c
            while(j <= i):
    % z3 g" [# E) A2 m7 o3 G6 T% a            t += fitvalue[j]+ A5 [/ m% K0 ?" Y$ Z7 a5 Y6 h( ]
                j = j + 1! g2 ^5 X4 L& {) l9 U, k- M
            fitvalue = t;( w- L8 @6 h9 O, n6 E) |0 q
    9 u. l' c- u8 r3 M: q' K
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)
    / p8 s& r% B8 |/ \5 O$ E; g        newfitvalue = []* ?& c4 Q' p9 u" o
            totalfit = sum(fitvalue)' W5 l6 V* T  u/ Q, B
            for i in range(len(fitvalue)):9 K& n" I- @% P& ]' F$ K9 y# y, ~! K& I
                    newfitvalue.append(fitvalue / totalfit)' k' v+ w5 v- W* G; B
            cumsum(newfitvalue)
    ) i7 u& L4 n3 u2 z  n* Q        ms = [];  ], Y* {* }1 C
            poplen = len(pop)
    + Z8 J+ o& w" X& m4 T! e" g        for i in range(poplen):
    . ]7 k; V! i7 t: ]$ @( P. s9 t: Y                ms.append(random.random()) #random float list ms# v& ^$ F1 Z" a' _3 A
            ms.sort()
    1 o2 P7 G$ J2 @( T        fitin = 0+ M& f" K$ G: i  W! f
            newin = 0& d6 [5 b/ b5 b
            newpop = pop+ G, I+ F* e; }2 `, ~/ L
            while newin < poplen:2 f1 [* L7 `: J
                    if(ms[newin] < newfitvalue[fitin]):' Z! K2 l3 p  {0 u
                            newpop[newin] = pop[fitin]5 a6 K5 u, l: Q; |# w
                            newin = newin + 1
    # Q) T! A( u* ]2 F: a8 _                else:
    & M1 |/ {' [0 C                        fitin = fitin + 1! y! W/ ?8 ?1 w: W7 c) M
            pop = newpop
    2 ]5 H* u5 V  _( `7 [0 [0 ~import random
    : e3 ^) m+ k5 T2 L9 Y8 k2 r
    8 W: v% \& p! e" Y9 I2 B* R4 Rdef crossover(pop, pc): #个体间交叉,实现基因交换4 C, R8 q+ s( s" S
        poplen = len(pop)
    % V5 L3 n, |( Q* W2 n+ D0 i5 F    for i in range(poplen - 1):9 @5 I' q7 c8 \' L4 {6 o
            if(random.random() < pc):( y! L( d" ~& T7 b
                cpoint = random.randint(0,len(pop[0]))
    * h: G5 e! {; w' H            temp1 = []
    9 ^1 J( ^, o- r! ~" s' ~5 U4 z            temp2 = []  @' c& {, M6 H1 \
                temp1.extend(pop[0 : cpoint])
    3 M* ^: q& @3 V3 K, x* @1 R$ O            temp1.extend(pop[i+1][cpoint : len(pop)])# }; C; B0 H. M3 s  B+ o4 l) o
                temp2.extend(pop[i+1][0 : cpoint])
    * K: J5 n- F" T( ~" F            temp2.extend(pop[cpoint : len(pop)])9 _! I. J+ L1 v  W
                pop = temp1
    ! P" F3 ~: ^* r9 T            pop[i+1] = temp26 v$ E9 J7 S2 U% d
    import random
    9 y# Y6 a# M; x' K/ G! e9 K% {( ]; M
    def mutation(pop, pm): #基因突变
    ) Q" U# b0 P: x7 i) |    px = len(pop)4 J' a8 a" u: R5 K
        py = len(pop[0])
    & q7 u2 @0 e% [  T+ p, F6 @# ^2 l, D" \3 h" r
        for i in range(px):/ @% E, E2 r* t7 Q; A5 Z
            if(random.random() < pm):, G9 v2 a' h- l/ d+ X) W3 {) W
                mpoint = random.randint(0,py-1)
    , Y: O& s* x: f            if(pop[mpoint] == 1):
    . D- m( L9 y/ h1 @& [* F& W                pop[mpoint] = 0
    # e- Z( U/ o/ v8 i2 t            else:
    5 z  H( i7 c1 U1 t- [                pop[mpoint] = 1
    % N9 V) P3 T( o
    ( r# d) W" |  a& t8 A: r
    $ u8 l7 K/ _7 x; m# J————————————————7 J8 ]6 W6 A$ q6 q- U
    版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 d5 m+ c, I6 H; ^  J' ]
    原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    + \2 B9 p" U) F5 u( W  }
    + x# x# R" x! d9 L5 [3 S5 }# e6 k) C: o1 f
    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-9-2 02:55 , Processed in 0.528158 second(s), 51 queries .

    回顶部