QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5970|回复: 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实现的遗传算法实例(一)" T4 M1 K; O7 j; s. W4 {
    7 }1 o/ {( s3 `: [
    一、遗传算法介绍
    1 A) J4 g& {6 [
    2 _6 X/ l7 }# l0 r9 A7 R        遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。1 B3 `. |  E8 ]9 A0 k  B3 `) Y' K
            f(x) = 10 * sin( 5x ) + 7 * cos( 4x ),    0 <=  x <= 107 T/ \$ S$ D; [* J
    ; c5 q3 H4 @& z
    1、将自变量x进行编码
    2 o7 s. s% c8 v2 B- f7 H0 _  i  Y; p5 h. j5 l5 F
          取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
    ' J0 D+ r0 s' z1 n+ K# d
    , ]: }5 k, r* v5 k9 W2、计算目标函数值3 t% c6 W- ]# U" L$ [  b5 t

    & I# X8 D9 @/ `+ U, T6 c) [      根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
    : x* N% I! E- _) N7 v1 t5 B" p0 C% {) N
    3、适应度函数
    1 f# `& L  d  C* D% X8 U* y" ?& i2 V4 R  \8 ^
          适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
    7 l: q- i2 g+ u  H* e2 l1 N
    ( o" q# I+ X; y$ T+ K$ E3 D3 }9 u4、自然选择
    $ M% B& ?1 M+ K8 N8 e/ a0 G  ~5 Z
    & T7 x, E2 g6 J& g1 S自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:1 C. a7 g$ }6 _) x" D7 |
    0 [/ L/ M+ ^$ R% m
    假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。; }4 ~- W/ K9 w# x8 v" A5 G
    $ N( j/ F$ `- H$ l$ `3 m) `
    5、繁殖' f+ k& [, P0 Q9 T/ w

    0 ?6 Q; `  I2 i3 E+ O4 t1 ]假设个体a、b的基因是0 p  D' U* d6 {5 Y7 @
    , [! w7 h( k- I! h4 w* Z
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]& z, y/ r/ U# q# U6 R

      T$ o' a9 d2 {b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]/ i" U9 ~# K, e2 l8 a6 @7 Z

    & ^" G) m  U- A9 T" E+ ^, f这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:* _2 L, n. ~7 i, ^: J( B$ K- U
    9 T2 s/ @3 q- [* y; ?
    a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
    4 X! [: A7 W3 t9 t3 a7 W$ j# a
    * }# X% i- ^# F7 vb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
    2 m8 V1 b( q$ i) \$ ~* A8 P  l! z" c3 j- A: W* l
    交换后为:
    7 U7 T! d1 E( ~( k4 C( _. F  [8 q" s7 i! x; g% K
    a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
    7 c4 x# q3 J; E
    - x: t; r; {% |+ y; a/ m3 {6 @b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
    $ E& a9 d+ z# u3 h% d; O' \  P# X9 _, V7 s
    6、突变" |$ w* w9 z$ b, |' z9 y$ v
    : U6 s# ^: [! N% C8 `
    遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
    ! t) o2 C8 g0 V9 O" t7 L& h7 ?% ~- S
    二、代码
    : R: A6 O' X- J- n6 ]6 mdef b2d(b): #将二进制转化为十进制 x∈[0,10]
    . T) t8 H' @) s) D0 y        t = 0
    3 W% F/ z8 V% W5 L. a        for j in range(len(b)):
    9 E4 i- C5 |! f" Q' s0 M, |" Z                t += b[j] * (math.pow(2, j))
    9 X1 k% ^: Y4 z) g        t = t * 10 / 1023
    3 _0 o+ O, M7 _6 ~/ t5 S$ V        return t  N) @1 S7 J. V. d0 Q" a
    : X" c* ]6 z8 t
    popsize = 50 #种群的大小
    & H" v% F, }8 h; ?; l#用遗传算法求函数最大值:+ }/ E0 a0 S0 h
    #f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]: r, \: _! n2 I; v; B# c2 c& O
    0 j2 f$ P' y5 p0 p" v. ^- Y0 I, U
    chromlength = 10 #基因片段的长度
    6 Z7 S. h. c+ R( E9 Cpc = 0.6 #两个个体交叉的概率2 Z  Z4 a/ X+ [4 D' W* Z
    pm = 0.001; #基因突变的概率
    ) s4 `  m: C) d& l% g$ Kresults = [[]]
    ' C7 p: \, ?7 M' u  V! tbestindividual = []
    1 r4 `  h9 E$ |1 Y; ?2 bbestfit = 04 M1 \. y3 C& G+ B
    fitvalue = []8 @  E) O3 ]5 U( S
    tempop = [[]]" I0 L$ ?9 {. r6 c  M2 P6 t* x
    pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]  for i in range(popsize)]5 G0 S% o+ v. s+ ?; z* @2 O' `
    for i in range(100): #繁殖100代4 R5 }# T5 E# x3 J  D3 `
            objvalue = calobjvalue(pop) #计算目标函数值% r% R6 S/ D; e& d. ]4 X
            fitvalue = calfitvalue(objvalue); #计算个体的适应值, u, g% z$ w4 G) \4 R
            [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
    , L3 p$ B$ {# J; A1 v% Y        results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来/ h6 q$ ~  {& ^6 o& t
            selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
    ( {! L! I$ L6 F! f' R        crossover(pop, pc) #交叉繁殖
    9 U. b* Z; e/ o2 H        mutation(pop, pc) #基因突变9 E0 ]9 H" o4 [! Z
           
    * H8 V! I1 n( F- [3 e/ J& \: p9 B2 E! A9 _6 T% G+ b% D7 e
    results.sort()        ' {  x. w* F7 M! J
    print(results[-1]) #打印函数最大值和对应的3 u0 M  M( Y% P5 u
    def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。" T) R) W7 {7 R2 _7 P% _
        fitvalue = []
    0 x0 \  }! [  Y4 u- T) M. X( I    temp = 0.05 A8 u' r  W9 @
        Cmin = 0;
    - e) {  p1 F* e: [6 n    for i in range(len(objvalue)):
    $ @/ \9 W0 [6 Q- j2 {        if(objvalue + Cmin > 0):
    ( f( G" a4 j8 A2 ]/ S- m+ z0 }) ]            temp = Cmin + objvalue- h: i5 f' @& `& U/ S7 m
            else:
    / J9 o5 V+ y* M5 L6 H            temp = 0.0
    % |- W  A1 z0 J$ d4 b' c+ o        fitvalue.append(temp), D. J+ I. e' h) C3 Y$ @
        return fitvalue5 {% \3 n6 e0 ?  V/ d: I
    import math
    & ?) m& |+ ^( K; ~: c8 [' J8 a: ?0 k* [+ I' `- U
    def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)9 b5 {9 l5 R6 ]8 s
        temp = [];% X6 A6 x" \) Y: W. N
        for i in range(len(pop)):! j- r0 G- _" w6 K
            t = 0;3 j- ?: B5 M6 J: {) L) F3 r
            for j in range(10):
    ) {8 W3 O0 f  o            t += pop[j] * (math.pow(2, j))
    / W, r  M5 ]: \) z) o        temp.append(t)4 A) h( J1 I2 n! ^# K
        return temp
    0 h- g/ |: b3 ^, q4 z  Y% B- L( m5 X* S7 M2 L& j
    def calobjvalue(pop): #计算目标函数值
    + E2 j- t" m$ G    temp1 = [];( C: W, w- {$ V. X7 V# @
        objvalue = [];
    1 i# @  _! k4 n+ `$ p    temp1 = decodechrom(pop)
    7 g$ L0 d+ P; Z) F    for i in range(len(temp1)):
    ! v" A; G' ?2 h  q8 E( u9 k        x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)5 w" e# V& y! B
            objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))/ p: q0 t2 n, d# t
        return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
    5 i" h: s/ a- y  E- B+ a) t+ Bdef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
    . u" \3 t& F' k! p% R3 d        px = len(pop)
    . {5 r: v6 N9 i/ Z' n- ?# b- v# }        bestindividual = []
    5 d$ P& \9 z; N8 R* g        bestfit = fitvalue[0]" S& D$ T( x* `8 f! ^: c% S
            for i in range(1,px):
    ( M# N) J6 @1 W                if(fitvalue > bestfit):
    ; ]& m/ n1 |2 R6 O8 X; f                        bestfit = fitvalue; N1 t$ }) r; Q" P. {
                            bestindividual = pop
    5 M1 O3 ^+ m- _  N7 T        return [bestindividual, bestfit]& ~6 P) ]# A, C" F, K
    import random
    * o! f: b9 J' P5 g- [9 O$ O3 Q+ ]: _# z
    def sum(fitvalue):
    + J$ I; E! U/ F+ q' C    total = 0
    8 z  I" E! u( d% r; m2 B    for i in range(len(fitvalue)):% p1 r; P) n! i0 e: V  [
            total += fitvalue
    3 M  I- {& A- F6 o    return total
    ; ?# I: e5 {# \0 N9 b" q# [) n4 b1 E) J" L* {! B5 ]5 W' c5 |1 F
    def cumsum(fitvalue):" ?, s  {( n2 z  M
        for i in range(len(fitvalue)):
    $ y& U7 t( ?" \: C+ h& a        t = 0;
    % n+ ?. p) C; W9 z5 U% @* r        j = 0;
    & _6 b% s  {7 n( x9 P7 M        while(j <= i):
    ( F$ ?! B+ P  |5 ]) U: ]9 j8 J9 o6 t$ K* \            t += fitvalue[j]4 {( P2 @5 M% V- s% V- e* t0 A
                j = j + 1: z8 M1 L9 u; K
            fitvalue = t;
    ' W1 b/ k2 v, t+ n: ]0 ?0 j3 @- w) q$ D: z, q+ R4 g: f
    def selection(pop, fitvalue): #自然选择(轮盘赌算法)
    & U, E" y3 m$ N& f# @        newfitvalue = []
    - d7 A1 u  {: \8 x; z        totalfit = sum(fitvalue)  Y% n0 [# w* u& A5 n' S+ o  G
            for i in range(len(fitvalue)):  X( W5 C$ e* U. z" I
                    newfitvalue.append(fitvalue / totalfit)/ H, H7 B( `7 D) z" F1 }# R" c+ T2 q7 M$ S
            cumsum(newfitvalue)
    & r2 W, n  J& A3 \5 d  G        ms = [];
    6 T) ~" Z# q* K+ L9 [( J        poplen = len(pop)
    - i) K/ i) S8 A$ I0 G5 I        for i in range(poplen):
    * c1 U: \" G0 M                ms.append(random.random()) #random float list ms2 U8 I7 P9 D5 R& U9 R' A
            ms.sort()& l) Y  o. ~  A: q- o$ e+ u4 k
            fitin = 0
    ' o' b& [/ w- s, i        newin = 0( V1 |$ ^( R6 n4 E
            newpop = pop7 a% H. r$ @: U. m
            while newin < poplen:. i! m& D" T/ l" f
                    if(ms[newin] < newfitvalue[fitin]):
    ; d% z: u4 ]3 f: h                        newpop[newin] = pop[fitin]
    . t% n3 B) Z- e) \  e; U                        newin = newin + 11 {; p: D, T* H
                    else:2 ~0 o/ l; S+ }3 l8 k
                            fitin = fitin + 1
    3 M. K: B0 V* M' e2 X8 D/ r4 Z        pop = newpop& b& \1 q, g: D1 k4 ^
    import random
    6 }3 t0 ^' R0 K( |
    , `3 t7 T7 H8 U3 u7 b6 ~' m) kdef crossover(pop, pc): #个体间交叉,实现基因交换
    + K) d8 G' W$ A, i    poplen = len(pop)
    - L6 o- @0 v3 r' X    for i in range(poplen - 1):- D2 Y! g* E! e2 n! J- |
            if(random.random() < pc):0 f  }+ G0 i  [7 A, U& b9 I
                cpoint = random.randint(0,len(pop[0]))
    1 X- ~7 h0 D( `5 H) {2 Q2 c* ]            temp1 = []
    . s5 i, z4 z6 R1 {            temp2 = []# h! m' X$ a  f- y2 [
                temp1.extend(pop[0 : cpoint])' K+ K( `% v) }  X, Q
                temp1.extend(pop[i+1][cpoint : len(pop)])% E* Y7 q- Z$ R; e
                temp2.extend(pop[i+1][0 : cpoint])
    - A' H' s; j% J$ o5 d            temp2.extend(pop[cpoint : len(pop)])
    ! q  P, V* q/ M/ K5 X- _+ ]            pop = temp1) W) p7 @. O' G& M! n! J  k
                pop[i+1] = temp2% y  Y, b' H! w$ h9 a3 O! z7 W
    import random
    6 V4 k' n+ z2 x5 f" ?% H
    : [2 r4 g/ S7 l4 r5 Z, rdef mutation(pop, pm): #基因突变  D$ f: @2 z# [* Y' X2 L4 \3 D
        px = len(pop)
    : @$ b, c0 L" [9 `) n    py = len(pop[0])' F/ h! G! s8 V

      B) o  Q1 ?7 C* K    for i in range(px):6 u2 e5 X7 R% D5 h/ h
            if(random.random() < pm):& K5 m: n- z5 }) b5 p
                mpoint = random.randint(0,py-1)5 y( H/ U. P. J4 s
                if(pop[mpoint] == 1):8 |6 C* W/ K; n4 B$ R6 y
                    pop[mpoint] = 0& L' e, A- G! a1 p; D
                else:% N- `# H& Z6 `! d) n) K
                    pop[mpoint] = 1
    0 L3 H1 W7 S! `
    : _7 x* ?& c; I' m+ ^) h) l0 g. S8 E
    ————————————————& \, Q$ P- Z$ \9 d
    版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。# w& @* u$ m. f& S! e+ h9 y" B
    原文链接:https://blog.csdn.net/u010902721/article/details/23531359- h6 h$ \6 T' x+ E! Q
    * L9 T6 q; t+ |

    5 S+ S7 c/ _- x2 L9 |
    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 03:55 , Processed in 0.408982 second(s), 50 queries .

    回顶部