QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5041|回复: 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实现的遗传算法实例(一)
    3 Y' m) f. X# Q7 V9 ]2 u6 H) |( r, ~/ G: P8 a0 Y6 q: L; t
    一、遗传算法介绍
    $ j. c6 X3 ^" N5 y/ X4 ?: o. R
    + K8 r& {. b8 z        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
    7 ~5 ?; U5 Y0 D9 ]$ G* ]) f. y        f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10* U6 R7 [0 D# k  C: \, w
    : O+ y  O5 c# ^0 k3 I* f
    1、将自变量x进行编码8 A" u6 h  @* i4 Q

    . U# @9 j' O/ Y/ |5 u      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    ( B& D9 r3 ?/ A( z  J* S8 g( ?- ?0 [/ y& k7 p" L$ V
    2、计算目标函数值
    9 x- t. G4 {* i: Y/ k  R( G/ d7 K  A3 A" |2 f
          根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    / I. l+ m) o6 v, [# ]" \6 F, x1 p/ T# L/ w0 X/ {. q' [
    3、适应度函数
    3 }2 G8 b) y5 Q) D" ]
    7 b5 W0 S! x7 r1 t: g) l2 I      适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。) V7 j0 q4 \1 H$ u! y0 _

    - V3 P! F# k8 ~+ y- B6 w5 E! Q4、自然选择
    : a& {0 Z3 K6 m0 s- W6 t: |7 v0 e% H: s& a: @/ `# x7 C
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
    & g+ o5 h* ^6 @' \6 @6 w' c
      d  m4 Z" j+ x$ J假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。: d& N6 X# a3 N  @

    3 s% V2 m, q" ^6 }. G5、繁殖7 ?: t( x' J6 R- n1 N* o+ V) W% x7 X' ^

    # w/ W" k6 e3 z/ P; J+ W假设个体a、b的基因是2 n$ e0 w+ u- l' h. Q. V% U

    , F& x, q& U; ^3 D1 ?a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]$ L* @6 [3 I3 o6 {( Q, n) D: P
    4 \9 i9 {, k8 r$ w8 V* j
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]; Q3 t& I* b' ]1 X1 Q
    , S( V* a; u% a! J) Z
    这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    ; `, v2 ?! g) M* _% N" V, v5 ]) _/ K# d+ W
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    1 K* m, x3 a. s) ]& X% N9 e5 `1 q
    b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]1 r) R; ]: ?4 a8 I
    / ^6 W& c; m& H' F
    交换后为:: b  Q) T: U8 x. P& n8 `* \* h
    : C, `, `0 b3 O6 b
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    4 p' i4 Y0 L7 y( w! @1 n# X0 p' i; B5 W4 P$ f: `2 {
    b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]7 O. `  ~7 P$ J+ F; C

    7 J! v* z% T4 J. a( T9 l5 N6、突变# i+ Z2 ^$ J8 ^, t! E
    ; B  g; `: u: U% L' k3 _1 X6 ^
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间1 c' C+ M: C' B: A  F* \0 Y5 R% p
    + F# x7 |) E/ r; m
    二、代码
      ~6 f. n- ?- g2 S! cdef b2d(b): #将二进制转化为十进制 x∈[0,10]
    3 V( J) S6 J( U3 S! ~4 _        t = 0
    : n- ^* \; s: [        for j in range(len(b)):
    $ u/ r. U; h: `! q( H2 ]                t += b[j] * (math.pow(2, j))0 _% H6 o% `9 t# Z8 e3 C
            t = t * 10 / 1023
    ! j; Z1 b( ^+ {        return t
    ( V: B% C: |* J9 `+ ~. v1 u% O* {
    * M7 A; s: P; z- a9 i8 M, E9 R/ Ypopsize = 50 #种群的大小
    2 b3 ^! z$ c5 w" [#用遗传算法求函数最大值:" e1 F2 Q  T% @, E  `" m, M
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
    " [( {: s$ G9 _' g7 j) l2 G: w! ]3 f) A4 k
    chromlength = 10 #基因片段的长度7 T, ]/ t/ M" G# w9 O# K" p
    pc = 0.6 #两个个体交叉的概率
    1 z/ \: J  H/ ]  o) D( l" rpm = 0.001; #基因突变的概率
    / U4 |9 I$ `) z# w4 H2 _9 @5 l3 o; c/ xresults = [[]]
    " U$ t3 C: Z6 {0 Abestindividual = []
    9 ]% K! e8 c! Z9 A1 g: ubestfit = 0# I8 U2 C, j& ^% X$ P; E* O
    fitvalue = []
    . J1 F- E3 t$ ?6 W* \0 qtempop = [[]]& e# M5 W8 Y; p' I4 q
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]3 V! o8 A' P/ Z0 c1 g  w
    for i in range(100): #繁殖100代
    9 U! l; Y! {, Z" |/ n; j        objvalue = calobjvalue(pop) #计算目标函数值" I/ y; @! |7 {% J( w
            fitvalue = calfitvalue(objvalue); #计算个体的适应值
    4 q1 Y& ~) P, o* ~/ E$ |        [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    ! N4 I" T+ O: k# ?4 k7 R        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来' X, Q, Z/ y# l- A4 ^
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    * l4 m! S# E- H        crossover(pop, pc) #交叉繁殖
    4 ~4 X+ n& d6 q- G  J' E2 j        mutation(pop, pc) #基因突变2 O% g0 m& Q( p1 c: u9 i, }5 m5 N. Z
           
    / n! [) a7 O1 m; M* H
    1 Q" z7 n& C: Z1 ?& [0 D% _results.sort()       
    5 U8 k8 A6 e+ uprint(results[-1]) #打印函数最大值和对应的3 ], l' P1 D0 l1 H4 M
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。0 ^& z3 H8 @/ n& _
        fitvalue = []
    & k% U% p4 R0 e- l2 t    temp = 0.0
    0 T! S8 l! D$ b1 E) S    Cmin = 0;+ e; V  C6 F6 m7 V; E* D
        for i in range(len(objvalue)):
    ) Y. _- K0 y% G        if(objvalue + Cmin > 0):9 ?. I4 y$ l) h3 Y* E; I5 a
                temp = Cmin + objvalue
    6 Y0 w: R4 w: _# }' _7 e        else:
    : {9 q) S. F' t            temp = 0.0
    4 e0 }+ j# t/ c2 P# b2 `        fitvalue.append(temp)- {5 h7 p2 T- ?3 ~1 `7 t2 q4 w
        return fitvalue
    $ V2 O' Z' i  L! Dimport math& ?) s0 |1 g: |' `1 r. E: B+ E

    2 x9 \$ k5 ]: \2 L; d* s5 |def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)7 i% W3 K* T& S$ s2 @
        temp = [];
    ' E) d7 F4 y. M    for i in range(len(pop)):8 ~3 q( G( K: m4 r1 Y% I& y
            t = 0;
    8 [$ [2 e; C& ~: n. t. g: z        for j in range(10):& R3 i2 l0 I* G
                t += pop[j] * (math.pow(2, j))
      v  P. n" X5 w1 M; G        temp.append(t)5 T( Q7 `3 Z. [' @- m' V+ K
        return temp) U1 D1 a8 d6 I

    % E; P, {1 Y# T/ E1 l4 ldef calobjvalue(pop): #计算目标函数值! C8 F7 u. q4 @8 {
        temp1 = [];( s" l+ O% }% d, W! l6 ]
        objvalue = [];
    ( O, j- S  z& w4 g3 x2 |$ }; _9 i$ \    temp1 = decodechrom(pop)5 c9 s4 B+ Z7 Q9 j8 K
        for i in range(len(temp1)):
    - x' Y$ @# H( ^  s% W- y        x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)1 G2 _" n, W* l8 |' X) S
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
    0 D3 I* [1 w$ c$ B9 K6 L4 o* U7 ~! G    return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    $ K9 A4 W3 D9 ~2 m& ?def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体- b6 p' n3 H' }3 e' g
            px = len(pop). v2 J/ a- w" H
            bestindividual = []' [8 d0 P# i* {3 K  U- i+ D9 s
            bestfit = fitvalue[0]$ n6 @. I3 |7 b. b  B, ]
            for i in range(1,px):
    2 H* u' Z# u, Y4 Y8 o0 P3 y& E+ b                if(fitvalue > bestfit):
    " J4 k' p% s0 Z( e* p" i                        bestfit = fitvalue
    % l9 f& }/ M0 i                        bestindividual = pop
    & ]3 _; m% _4 r. P- Q        return [bestindividual, bestfit]
    # ~3 m. K: C4 |- ximport random# I( X$ P/ \; R* O
    4 ^. A9 f/ S: }/ c4 l
    def sum(fitvalue):4 w7 c8 I9 i4 `, C' p( p
        total = 09 V9 M" R: E$ N
        for i in range(len(fitvalue)):
    , L0 [" u8 f7 j$ ~- W        total += fitvalue
    # C* |. N0 y2 E3 T! w2 B9 t8 Y    return total
    + Q7 K% k; n: m- ?7 f( x
    0 i$ W* G0 a* a5 t$ x! X0 Bdef cumsum(fitvalue):% C  Y: O5 ]# V" p
        for i in range(len(fitvalue)):
    9 G0 N% o3 s" m% h/ w        t = 0;0 W# k# x4 R0 H' e$ m
            j = 0;
    4 d% ~) M1 P6 c# L) Q        while(j <= i):& n9 j" X1 P, V
                t += fitvalue[j]$ t- y2 t1 `! R; U% s3 a
                j = j + 1
    $ b7 q8 F5 M, l4 O% ?/ G! u        fitvalue = t;
    # c7 y" G. Y! i& k$ z5 g9 b: ?
    & _0 p5 B) p7 G- |; adef selection(pop, fitvalue): #自然选择(轮盘赌算法)
    " |+ t* Q. T6 Y        newfitvalue = []
    5 }, X6 n- a2 D! a8 n- D/ C        totalfit = sum(fitvalue): v; H( Q. l) _2 b
            for i in range(len(fitvalue)):
    4 p  e  Q, `& v# S' X; d  l                newfitvalue.append(fitvalue / totalfit)
    4 G* T! f1 H- h        cumsum(newfitvalue)
    + A: w4 u. k: X# {        ms = [];
    . m" o1 I& `  i, E1 y5 W        poplen = len(pop)7 ]! V* e8 h9 T
            for i in range(poplen):
    & T* n- M7 X$ {- V9 w                ms.append(random.random()) #random float list ms) B9 @& ?, k, f
            ms.sort(); O, F- W8 Q2 j
            fitin = 00 a- l  C2 u4 d# h6 q  H$ C+ ^) s
            newin = 0
    $ Z8 l' a# H$ i' X$ @5 {        newpop = pop4 x: X, F, ^! i1 j
            while newin < poplen:+ @: p. g7 X% F" J7 L8 }3 s  |
                    if(ms[newin] < newfitvalue[fitin]):7 p2 M/ U: R% l  K1 k3 \
                            newpop[newin] = pop[fitin]
    4 `( T- F; q1 B, ^9 U                        newin = newin + 1. C6 q( H" S9 @) f1 z
                    else:& @2 g, B& I3 _- F7 D) Q5 m
                            fitin = fitin + 1
    $ v0 b4 q; t, \6 F        pop = newpop
    3 J  }- R3 e' `( t# `import random
    7 z. Q% G1 A# H" A5 y# u' t  W6 [* z; \7 e- t  V+ P
    def crossover(pop, pc): #个体间交叉,实现基因交换
    1 o% ^! ]( A, N! A" E    poplen = len(pop)6 C; W5 w2 H3 j
        for i in range(poplen - 1):
    1 K0 W1 U  |, L( j        if(random.random() < pc):
    : i2 \" o! p1 n5 W            cpoint = random.randint(0,len(pop[0]))# G5 H0 @) T  Q0 G1 B' A' |( N
                temp1 = []6 W, X) F+ U- x, u) @; ]
                temp2 = []
    ! a: l$ Z. J3 M9 g2 l  X            temp1.extend(pop[0 : cpoint])
    ' ?- |2 _  P; j' l) S            temp1.extend(pop[i+1][cpoint : len(pop)])! P  ^& y2 b: l
                temp2.extend(pop[i+1][0 : cpoint]); G5 m2 w3 H% N/ e1 o2 S8 l
                temp2.extend(pop[cpoint : len(pop)])2 L  }2 z* ^% ~+ B: A- n: N( v! F& ~
                pop = temp1
    $ D3 Z9 X- R0 Z" V: t  f3 @6 ~            pop[i+1] = temp28 H& ~1 n! c6 v! q8 ?0 d" C
    import random: f0 |# G$ Y( G
    - r( s+ d8 v2 O( M# O/ ^
    def mutation(pop, pm): #基因突变
    9 c, b' V3 V1 s, c    px = len(pop)
    ( V# m. v' O% \8 {* t) P    py = len(pop[0])
    6 {- W0 h9 x. y! H" _7 X$ O7 [) W5 t% H
        for i in range(px):
    ! I1 }( A1 q8 F5 A' Z- U        if(random.random() < pm):: f5 I% e' p' D9 q
                mpoint = random.randint(0,py-1)/ q0 y$ w: f  s, P9 g; @) [9 Y; @
                if(pop[mpoint] == 1):
    6 d" T) U( n% O' q; l& o6 X& m                pop[mpoint] = 03 d* f5 I% I4 B6 b% i0 L
                else:% w  [0 w( m$ F/ v" y) j  Q( R
                    pop[mpoint] = 1
    * A- P2 K2 r0 n. w
    % Z; }0 p: J, z9 g% h5 H3 y) B+ N. o. p" T* ]5 Y
    ————————————————
    0 M* ^2 M4 m0 \' O) A版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* E+ P; Q- ~& ^- |
    原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    ( }9 k3 E. r9 h5 L" V8 \, p0 \5 w9 q2 A6 h+ D: H4 M. O+ p
    0 S5 D% V1 ~  x
    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, 2025-8-1 07:10 , Processed in 0.443014 second(s), 53 queries .

    回顶部