QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5862|回复: 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% U4 b+ N; E# T& k9 D( @9 n: a3 n  D0 J& G  Q# d/ b6 w
    一、遗传算法介绍
    ; ~* B* R* j- _& |0 Q; j8 H* z8 a( Y# k6 h/ O) F: u* S
            遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。' a9 s4 u. b: g! v1 V* Z
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 10, z  J) r- U( l7 X4 V" f+ P, U

    , ]# w+ s9 d- x  T, e! N+ }/ v1、将自变量x进行编码/ |2 v6 h4 Z1 p: c8 Y4 B& ?

    / R' F0 O, U- w4 j      取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]" `) Q% g3 {( f
    ! d8 M3 P5 ]% A, B3 e5 R
    2、计算目标函数值1 s2 E* T+ ]2 H  s+ }7 r  J

    2 {, r" y& p  G/ ]$ E2 T      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    5 A5 @3 Z% A4 J+ Z/ x! g: I! K$ i( l" ^! f
    3、适应度函数
    + M$ l+ e, T4 b
    + L2 r  l2 t7 j) `& q      适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    0 v, I& W) l% B$ F- s- Y
    ; K- x9 ]5 O) k% G6 P0 l4 X4、自然选择: L% T4 N9 Z* {6 w" A/ O4 H
    6 {# Q3 U3 G3 Z3 W3 i
    自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:' ?2 t# `  H3 l; o, D
      W2 g% a$ q% ]# S3 Y. d
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。/ N8 f/ H) G9 e. M

    ; b9 i, ?) U$ T# W( ]- E+ V( p7 N1 i5、繁殖/ y* Q0 [6 m+ I# M2 l
    6 V9 `# X0 T; T! W+ P
    假设个体a、b的基因是
    & D% _8 I. W5 Z, T& d; W# E7 w2 n0 O2 B- K2 i: w
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    # Q) k( {/ `( r# n
    , h4 ?" z2 f# `: p: wb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]1 _7 W" S! K# y
    ! O6 Y/ j/ A( [: e  J
    这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
    " |9 d5 [3 x  D& X, z+ S4 K- e% W$ z! E" O. ?
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]" f7 b6 Z; o8 s, }

    ; M  Y3 p3 G; J$ j" Y) Pb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    * z* }" ]6 J7 X! o) A
    $ W/ A. p! U+ P0 C8 k. F交换后为:- J3 n( ?+ u! g% U- ~
    , G2 u6 r% `' C. [+ a9 A
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]1 |7 x3 a7 V4 l$ `3 X- _1 z( `( B) [

    $ r: W* u9 t4 Y4 F, @, }0 [0 p) nb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    5 U* b- S  ~* S+ ^) X, d+ n' Z  \% T& e4 b
    6、突变
    5 r* R# P# o5 ^: Q3 r1 M
    " k+ {6 c7 |! j  D2 j6 A遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间; j  |* g+ S/ E7 I

    7 o* e4 y1 p& i1 L/ M/ j二、代码
    4 s% @0 T! e4 E5 l  E8 m4 [; F& B" Tdef b2d(b): #将二进制转化为十进制 x∈[0,10]
    ( f: S$ }4 p  Q7 e1 g5 c        t = 0$ i% B- B8 X9 W7 Y
            for j in range(len(b)):  B, F% O; |) _$ K3 ~
                    t += b[j] * (math.pow(2, j))4 }; v! a3 Z7 m# s1 Z
            t = t * 10 / 10234 f7 H' r. x9 s# i" F0 P: z5 y/ Z
            return t
    7 Y8 [6 F4 A5 L9 L" V
    8 h! P/ r! z7 S* m: X$ b) S3 {popsize = 50 #种群的大小
    7 d5 r: G8 _, C$ J3 b& H' d#用遗传算法求函数最大值:0 y$ ]. B4 {, n0 k0 Q6 @
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]; k/ p3 k3 B* L  p( d$ P0 r. m

    4 |) f4 M/ a2 hchromlength = 10 #基因片段的长度  g& g- c, F9 Y3 f
    pc = 0.6 #两个个体交叉的概率
    % ?/ `0 u# @4 Z: j6 ~* P6 f7 Jpm = 0.001; #基因突变的概率# R9 a. ~, _8 z- e8 E2 T: O. C
    results = [[]]4 \% a7 h  u$ @+ v1 S
    bestindividual = []: v2 J8 ]7 \; p! n5 s+ j4 K
    bestfit = 07 c- w# H( ~9 H% f2 s
    fitvalue = []
    : ~$ L; V: l, Y. w3 y) Otempop = [[]]' a& h4 A+ |/ A4 T* O6 V, q/ k
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]
    : i  H: {+ A/ a; q  Ifor i in range(100): #繁殖100代
    6 E3 E+ ^0 u# Q2 O+ u        objvalue = calobjvalue(pop) #计算目标函数值
    3 q9 s) b/ Q/ [        fitvalue = calfitvalue(objvalue); #计算个体的适应值( Z( @- p4 q! a& K) o1 l/ h
            [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值& p& J7 s' k; E& q3 N4 T0 @9 C
            results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
    $ ~! o/ ?/ E- g/ d3 T        selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    . }# ^3 q1 t3 E        crossover(pop, pc) #交叉繁殖
    & g% M1 M. B- R- o) |: d        mutation(pop, pc) #基因突变4 ~: J7 x# L" U- J8 O! i. d
            # N* k/ p: ]. g: F9 F" d
    . _6 p+ j& F. a! j( }2 i
    results.sort()       
      r6 Z1 Z5 P0 }% @" c& e( J  g. eprint(results[-1]) #打印函数最大值和对应的( A. V# F! K. @8 B
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
    ; {& T, z* q5 T& H# ~1 ]    fitvalue = []( `$ \) A! g( z, W% X( Y
        temp = 0.00 n* x: W4 Q/ X
        Cmin = 0;8 p' [0 J* J8 [. e0 }3 y2 ~4 `/ @6 R
        for i in range(len(objvalue)):
    ; K% ]- w. l; M0 W8 V        if(objvalue + Cmin > 0):
    * O6 n* ]( o. a            temp = Cmin + objvalue% C8 b) s8 n7 d! H/ B7 _" m
            else:. t) m( Z2 o5 y6 L9 N& d
                temp = 0.02 i8 ?8 i) B7 W- z- j9 x  A5 l
            fitvalue.append(temp)$ u8 r/ j9 E, X" }4 l$ G) c
        return fitvalue0 m" ~; w7 o: t$ ?! y6 y4 s3 e6 @
    import math
    1 N0 N+ N- h* o1 k) y
    5 B+ \# V2 k5 a/ x1 J! P0 H4 `! Wdef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)% l& d  P- x( v7 T4 m  _3 q8 U
        temp = [];& q' A: f5 n' N8 `% O
        for i in range(len(pop)):" z  q* d/ e. I+ H. |
            t = 0;
    - N) j& o3 @) a        for j in range(10):% L! q2 z) C* C: o( g
                t += pop[j] * (math.pow(2, j))* _! Q3 z- O+ A6 |0 k
            temp.append(t)
    9 ~# S# t. @# H& j( B    return temp* D1 Q0 l/ k, h9 y, M

    " N" a6 ?! q) ~& fdef calobjvalue(pop): #计算目标函数值$ \+ P) l6 T( Y8 [# |
        temp1 = [];6 b4 S+ N6 a2 P, M& t% t- r$ a7 q
        objvalue = [];
    % }( ^/ D, O4 R' L( K: B/ k    temp1 = decodechrom(pop)) R) U" X" C5 w- n4 Q& u; b; K
        for i in range(len(temp1)):" \6 ]9 ?' \$ d$ }. o) v  X7 L: A
            x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
    ' g3 Y) J/ g3 z3 T2 \" [        objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))+ c% _+ o* X; ~. {0 q1 h. Q# I
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    " v5 x* Y) S2 hdef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
    1 W/ b$ B3 d" g4 a2 a* p5 C" ^9 w        px = len(pop)( E: _; [6 d, O
            bestindividual = []7 |0 z) G) _4 j( b( h4 f
            bestfit = fitvalue[0]7 M6 c7 \! B* m: ~! |
            for i in range(1,px):" b/ p% R# m* @6 o! g1 _( Q$ |. P1 N3 K
                    if(fitvalue > bestfit):
    ) i0 p( B4 `/ l. ~4 W% E                        bestfit = fitvalue( n" J6 k% ^) }9 }) t
                            bestindividual = pop
    8 Q" P/ o, M; R) S2 ?        return [bestindividual, bestfit]
    / C7 \& Z) ?' B; Vimport random3 D. F& Z9 e; \2 l7 a

    # ^( @9 }% X& H* [1 M; wdef sum(fitvalue):& ~  h9 @6 S* S. [. w% K7 l
        total = 02 x/ l. V& _+ v* u4 ]2 [
        for i in range(len(fitvalue)):
    ' h' H6 Z" g  X2 R0 I7 i        total += fitvalue
    ) Q! H, W/ s/ w3 R    return total
    8 G3 t1 k7 W1 u% {0 v0 q. \: P7 z( h3 O
    def cumsum(fitvalue):2 f0 S$ |- a9 c+ R% U
        for i in range(len(fitvalue)):$ l: ^, h7 a4 b7 y7 o7 K
            t = 0;& }3 e, e2 Y* j
            j = 0;2 {0 n* s$ }4 u# }' ?  C
            while(j <= i):6 c) y( q* t- J" @7 E
                t += fitvalue[j]
    + n2 c) r/ _, S, I7 N5 l- M1 L            j = j + 1
    / b- ?1 `+ T% h1 f; V- I        fitvalue = t;  b2 Z/ G: |" v- Y, P8 K, e

    % y/ F/ u$ b7 ?* Adef selection(pop, fitvalue): #自然选择(轮盘赌算法); u2 o% {5 R3 |6 p1 C5 F5 X
            newfitvalue = []) v+ v4 P  y3 f2 Y9 d; R! G5 _
            totalfit = sum(fitvalue)4 l% ]$ S( W% H' w+ q# d4 L. C
            for i in range(len(fitvalue)):
    . L* \  V8 T' J2 S' r+ r$ x                newfitvalue.append(fitvalue / totalfit)8 |/ H1 \, }* z& Q& K0 p
            cumsum(newfitvalue)
    $ S3 i. u/ O' \. X7 Y. i        ms = [];" v7 S% Y/ X  c1 J
            poplen = len(pop)
    : A4 P$ b- _7 Z  _7 |        for i in range(poplen):5 E! J! N+ p9 k
                    ms.append(random.random()) #random float list ms$ A# y5 ~2 p0 U
            ms.sort()
    - F& [- o$ q  F. ]/ f( @        fitin = 0
    ! _7 Z9 C# m% E) Q$ B9 h        newin = 00 Y0 {1 \4 U0 V. k& E$ Q$ Q
            newpop = pop
    / O1 |# G( k: j+ }$ i4 S        while newin < poplen:
    + w' q' g( w3 n7 O9 |( _                if(ms[newin] < newfitvalue[fitin]):
    9 Z( b! D. S8 k2 F4 e                        newpop[newin] = pop[fitin]
    % l& g' p, `( p                        newin = newin + 1
    ( V- Y, [& x/ ^                else:6 R9 @, D" `. b0 I/ ?$ ^
                            fitin = fitin + 1
    4 c, {2 Z! j9 q+ q        pop = newpop, g( v% {3 c  f- H" T1 i
    import random% t" d  z" O8 i8 f/ y* D

    ; `1 f! I1 d5 ]$ R3 U$ [def crossover(pop, pc): #个体间交叉,实现基因交换
    1 K' l/ ^. l2 u3 E( d    poplen = len(pop)* R6 s: V: V' C+ w
        for i in range(poplen - 1):
    ( _* U2 F3 m- p        if(random.random() < pc):1 W6 o( K. n. A
                cpoint = random.randint(0,len(pop[0]))3 V" u) A/ z& }1 ?; X3 F
                temp1 = []# {2 @+ {& R1 I
                temp2 = []; ]' a( b+ I& Z: U
                temp1.extend(pop[0 : cpoint]). t2 h2 ]' K4 P2 e: s! S* t% t
                temp1.extend(pop[i+1][cpoint : len(pop)])  I6 }/ x2 Y$ Z# a
                temp2.extend(pop[i+1][0 : cpoint]), }' c* c; o& T$ v( Y% k( o  z
                temp2.extend(pop[cpoint : len(pop)])( o4 N7 Z; w! {, i4 ?+ X- x# \$ Y6 J2 }
                pop = temp14 v. |( ?0 i, k' b. q" \! p) E
                pop[i+1] = temp2
    6 R) i  t& a" @; @. o. jimport random' i% B1 H) v, n8 m* f+ p
    ' |8 @& h, K6 C% P
    def mutation(pop, pm): #基因突变1 a. H1 q  `$ @1 p7 x
        px = len(pop)
    : O1 H2 j$ J# ?' @0 M% C    py = len(pop[0])% v5 X& K9 t7 x! X% u6 S+ g
    3 l/ L) _, V  P0 F7 S/ f  o
        for i in range(px):
    . t7 X) @& Z# x3 _        if(random.random() < pm):
    7 S- n, \2 t/ `* {5 r' o  x0 R            mpoint = random.randint(0,py-1)
    & \. {2 r! K' |6 T( `" Z+ k            if(pop[mpoint] == 1):
    8 Z& I( m( D9 j& i                pop[mpoint] = 0( _& S4 V3 L# D" `" s# c
                else:
    8 l' {& V8 m0 {6 [, n& u                pop[mpoint] = 1
    1 L" z5 h1 M, ?. a) S, L
    ' C9 n! N) H9 ]/ x* s: f3 V2 _3 c9 R2 X! X7 a% M- `, Y( A  v$ W
    ————————————————
    ' |" F7 j& U7 X, C5 c! a4 b3 p- s版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 A8 [. |( p; F" L- N原文链接:https://blog.csdn.net/u010902721/article/details/23531359
    $ z/ ?5 U3 W2 T: S) r
    ! }7 a! v) w% U* B
    0 N1 [) W) H* B2 I. L7 ]
    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-6-3 11:18 , Processed in 0.413854 second(s), 52 queries .

    回顶部