- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 556388 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 172289
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 18
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)
" b1 R' `* S( _/ X u. Y# V
! u( P8 T. n* J0 T0 u一、遗传算法介绍
; E2 a* s: l, d; U
" f6 M! w S2 n 遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
' H2 v( [; g* g f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10
( T8 h G: k) o) _* g) N1 z; W: c# N7 r8 D @
1、将自变量x进行编码
+ }1 T+ ^* }# J5 k/ J6 [6 i- x
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
$ U3 u1 j& [& x6 L& }4 R" l0 R/ m1 y& U3 _& {0 j" u; o: f) |
2、计算目标函数值
- b& B/ H$ B Q: |
& ~3 e6 T) u# D$ d 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。' x) ]+ q9 J4 p. X5 P1 k H
( V% |" z( Z% a! W
3、适应度函数" c6 {3 E. ] r& L# _
7 d) X; U6 k1 U7 J' G$ u/ W 适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
! m) u- |4 V1 T, \1 O, }# z
. ^ q% H. ~4 v4 _2 P4、自然选择
& A1 j4 e* I+ ~0 S+ W( h
0 u. W6 h: S9 T; x0 q自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
9 B# J8 i9 o% v2 R
+ Q9 j. u5 H- }* i& u3 L假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。; H7 q9 E. A7 M0 j0 u- _- Y
2 ~" z1 Y1 x9 Y) h2 D7 i2 X4 h% J0 P
5、繁殖
; E: c4 m+ _7 `! n$ O
5 F" n1 w1 G+ z6 I; W* t假设个体a、b的基因是) ^/ v4 g6 P6 q" e- y% o8 o7 v
+ A$ h8 M. i4 M% W( r) f- t
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]# i4 W1 w' E. o2 h! s
: ?/ ?+ W" V+ w
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
4 n$ P, y$ i$ b; V F" n; i% B: u: V+ z. g* q
这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
5 \" \7 [" x/ L9 m* d& Z& s, D" g6 }* O {8 Q$ [
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]6 ]- g" e" g' z& n) _
2 ^' Z9 Z }2 F$ O
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
& \* J- V9 C! B7 `3 C% j# V5 }
& O( B$ y2 b7 {, g& t7 Z: m) u6 _交换后为:
; V) `9 R" s1 W% i; w. F1 A5 w- J( Q, L' P% J. a
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
* M1 U: T% Z8 a8 v3 d& R0 Q5 E" \
B3 X4 k, Z: p7 i6 h: q: p* o& lb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
8 h6 ?1 b3 d" \) v; K* u( v; x: t- a4 e+ u: I5 R3 C+ T. |
6、突变/ r# S3 K; r* l8 L: ?- q$ u( L
3 R8 {9 b5 o6 t* U/ f4 `8 R8 R [遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间2 Z% B* W, ?* U* o
/ T# _* S) D( B5 \3 N$ F
二、代码1 S& C* ]+ H6 G, J. n
def b2d(b): #将二进制转化为十进制 x∈[0,10]
+ S; H4 t9 f0 |, Y5 j- V t = 0
, V* A* ^% h3 x; P$ X) w for j in range(len(b)):
' @) U4 @7 x$ { t += b[j] * (math.pow(2, j))& q _& O1 j6 }- }" ]
t = t * 10 / 1023
) Q6 @" P2 I2 `+ R4 P2 r7 D return t
3 K6 ?. M% l$ `+ i
7 E$ Y% j. H8 H7 u: X5 ]1 Q+ _popsize = 50 #种群的大小
5 j9 R' Z: s6 V) x3 g3 }' _7 _#用遗传算法求函数最大值:
/ F2 l; ^% Y7 w" o1 I+ `#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]5 N3 q& K! Y9 _
& z) ?5 q$ f3 j, N% Q/ nchromlength = 10 #基因片段的长度
& N# z- \5 ]: Upc = 0.6 #两个个体交叉的概率) u) f% v6 M8 r' O) L
pm = 0.001; #基因突变的概率( F' ?. i; Y3 `( {
results = [[]]
0 \( L4 L& M$ h4 ?, r2 A1 Nbestindividual = []
) D' D& J7 O* p) t& mbestfit = 0+ ~* I- ]7 r7 A5 P6 ?
fitvalue = []& \" u/ | `4 v* K' \8 R
tempop = [[]]
' u8 b$ ?! e5 ?3 mpop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
! B% E1 V' d. _" x2 a$ _" s- Q5 Wfor i in range(100): #繁殖100代
' _( x/ [! @4 q9 \8 O& ` objvalue = calobjvalue(pop) #计算目标函数值
4 w8 }1 ^! T8 l! _( V fitvalue = calfitvalue(objvalue); #计算个体的适应值
) |' B1 K0 Y8 J/ _; M [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
: h3 Y$ ?8 p, @" I" w ? results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来) \2 L! K/ M2 R0 ~2 V& S. i
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体8 Q- C# c8 p# { f; H, K' v- h9 G; Y3 m
crossover(pop, pc) #交叉繁殖$ u, w$ ~) B) |4 J' z" k
mutation(pop, pc) #基因突变& V) ^- J+ Q$ G( r2 @! h) w
9 l2 M; g( I% K# }; _
3 l! E0 `7 a6 L2 H" v8 m. f" Yresults.sort()
# t7 H w g5 b$ Nprint(results[-1]) #打印函数最大值和对应的
3 n" w. I5 H; n6 C0 mdef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
( o$ b5 @1 K' C$ Z$ X fitvalue = []) D8 W% v& n0 d k8 P
temp = 0.0
" x a% }2 o6 `% K) g% J* u Cmin = 0;
$ F% l8 z: q' S+ Y+ T$ n: R for i in range(len(objvalue)):+ l& ], A# U$ z: Z. ]
if(objvalue + Cmin > 0):4 j7 I2 {2 g6 ~$ E. ~2 P) y# }
temp = Cmin + objvalue0 j. f6 u% L& S7 p
else:' A* M6 ~& k; G7 H
temp = 0.09 S" _' N5 J7 [; z t
fitvalue.append(temp)
: C( A' y7 M/ b return fitvalue
4 C4 ~) ^* G3 ~1 W: y; `" dimport math2 ?6 X1 J5 T" u8 k+ ~' d, b( s: F+ o
" F0 r% R3 f0 t0 adef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)0 ]5 `1 p* \) x' X
temp = [];
4 H/ b+ z5 u. n% L) g% G# h9 ?) R6 O; k; o% z for i in range(len(pop)): F/ r1 {' s; D' t _8 S
t = 0;( c9 M) G8 m7 D; k8 C% r
for j in range(10):: E+ l/ t' v9 ~2 O0 E5 {
t += pop[j] * (math.pow(2, j)): B# |+ a- k- @; V0 r
temp.append(t)
- S- Y! r" V. S% z return temp
6 @( `3 Q: K3 q& v5 U+ e( _2 U& g6 [- [( e/ U; \0 X. p4 }
def calobjvalue(pop): #计算目标函数值
+ D/ |- n8 _5 m o0 _8 E* q temp1 = [];
. V. u6 A& m3 O( F8 f9 B' M objvalue = [];
7 y8 v4 T, U; w0 [ temp1 = decodechrom(pop)
. v5 X0 E7 U, g4 x3 A8 ?8 S- Y for i in range(len(temp1)):) [0 ~3 L' s. w, @/ ]) l# e' Y
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)+ _# W" }+ \& V- G
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))7 v8 Q+ d+ k c% j, Z. z
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
) a. Q* ]5 Z5 D/ _8 J7 Edef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体1 K% O" { b( S5 u2 ^; n! s
px = len(pop)
@0 u) P: e' G; K$ c1 j bestindividual = []
& q; [" h" ?, A bestfit = fitvalue[0]
6 o* K: Z; \, m w1 m for i in range(1,px):# f9 ?# W. |7 l. X' c% F
if(fitvalue > bestfit):5 A Z e& C0 h- Y9 b5 ^+ R% c
bestfit = fitvalue
9 \+ B* w& d; D4 r; S) @, |& e bestindividual = pop
+ G& t, m2 }6 G, c5 ]# u9 s0 I. Q return [bestindividual, bestfit]% @( P7 H. h) h5 C, x! J e# Y
import random' d) D+ F% t* k5 l) P& m7 i$ _
6 ^! \3 ]% m, W, z' v9 Xdef sum(fitvalue):
: H0 g( j1 p( ~& g2 j2 X+ e total = 0
& v% K. R! [; K. \9 i for i in range(len(fitvalue)):
8 `1 d' ?- M- K% s total += fitvalue
! {4 a+ T4 s, P- @$ Z9 s return total
! ]5 J. Y; [1 t+ s: W/ I' @, r" ?* Q) \/ F5 d$ p
def cumsum(fitvalue):
I$ i9 o+ Q8 n- F" k- s* U5 g for i in range(len(fitvalue)):
+ E+ V1 Y) L: ?( ?3 Z. R- [ t = 0;
+ A C" w* ]+ ?7 A j = 0;
4 t8 h! c8 W8 D& L$ L7 t while(j <= i):
/ A, z4 \! B4 j: T3 W D1 O: z t += fitvalue[j]9 I+ Z, Q" }. i7 U) e
j = j + 10 `) [: V/ d/ |" n/ s. C4 K
fitvalue = t;
. M- Y5 F$ o i1 c& \0 w: Y/ U; j2 C/ g9 ~. U) f
def selection(pop, fitvalue): #自然选择(轮盘赌算法)4 ?) m! j/ s) i. I w
newfitvalue = []
9 x6 I. q+ _, e+ m totalfit = sum(fitvalue). |" r, Q" Y2 m' p9 ?
for i in range(len(fitvalue)):
( B( b, Z: p6 v- v- K newfitvalue.append(fitvalue / totalfit)
5 x: x# |4 J4 h! B5 B' U& |$ p; o cumsum(newfitvalue)0 b" ^$ h: S* `, c0 Y9 @2 R
ms = [];! E4 C! L& ?3 R* B# y
poplen = len(pop)
4 w, W: _+ \! }6 `& g" m9 ~! b for i in range(poplen):
2 y" K& j3 R' ] ms.append(random.random()) #random float list ms
1 `0 b9 \# v$ ~3 s$ P" S ms.sort()" I# I2 I( z* ~% c. }* H, |9 }
fitin = 03 p# k, N A9 |/ H4 G7 H5 x1 l' C
newin = 06 p. ?4 D6 F. q) G& w) c
newpop = pop
3 s* w& _) X, k7 E6 e while newin < poplen:
" P' n2 I- q$ ^, n9 A if(ms[newin] < newfitvalue[fitin]):
m* c( @2 c! I7 |' c newpop[newin] = pop[fitin]
! D8 {* }: w1 Y5 Q newin = newin + 1
5 L3 t8 p6 B/ }+ Z# ]% |' n5 E else:
. z) h! p) u$ R fitin = fitin + 12 X- D1 j4 F5 z- r0 W% L! [( Z% W
pop = newpop
& r! Q7 I& ?$ A6 uimport random
9 d1 n: R0 @ ]: o$ \ u- g
4 i6 Q7 A/ m2 s) h0 Ldef crossover(pop, pc): #个体间交叉,实现基因交换
8 c* V5 F1 s- }& _; O4 t: S9 ~ poplen = len(pop)
8 l6 X% M- D$ s8 c4 u0 K% A for i in range(poplen - 1):" h1 B+ Z# }& |# {% Z" N" W, W0 _
if(random.random() < pc):. n) Z O( r. h' c; u$ F0 [
cpoint = random.randint(0,len(pop[0]))% X7 O% o( G# \1 N4 r# R
temp1 = []
; H6 W& H7 P8 W% }% c temp2 = []
2 J. e. j) ^7 x: X' o( v U8 L temp1.extend(pop[0 : cpoint])* _! y' ~2 k0 e# P3 F
temp1.extend(pop[i+1][cpoint : len(pop)])
4 ^4 Z5 u6 J O0 p% Q: M temp2.extend(pop[i+1][0 : cpoint])
4 _; I( Z0 b9 J! R L5 t, B temp2.extend(pop[cpoint : len(pop)])2 _2 O* D6 C3 }
pop = temp1
% F5 }4 f7 T6 E pop[i+1] = temp2" Z1 A2 t* v/ R" n3 F# r% W9 O
import random$ [$ {+ J+ }( X! b5 K7 l, w' ?
" s6 O+ ?: C/ S c
def mutation(pop, pm): #基因突变) Q; L d2 a- ` _* a9 s0 x8 n
px = len(pop)
' B3 v3 P8 Z' k& K) t k) Z py = len(pop[0])( `" O2 I$ P7 T% ]: \
: P' ^: N4 S# Y% s' F. P& P9 y7 [
for i in range(px):
+ `2 e) Y: \: Q$ A! g if(random.random() < pm):
/ p8 ?' P* J+ s- G+ E" d" w mpoint = random.randint(0,py-1), B% i) X6 J3 i; c6 e$ n
if(pop[mpoint] == 1):
4 M1 ]9 n& J+ y1 H+ z1 T; U* N1 b pop[mpoint] = 0
4 J7 L( g6 r F6 J0 z6 a else:
; O$ c6 R: U2 B, g9 C/ a$ @, S pop[mpoint] = 1
?' C5 }/ O4 ]- s6 T# [/ H3 g: I. q* q& Y$ f* Q l2 v5 h7 x
3 W9 J$ v" ]% `; B. w
————————————————
5 x' P* E1 M4 X4 j版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& ~' D# R; {3 T/ z# h
原文链接:https://blog.csdn.net/u010902721/article/details/23531359
, \- t, {- n8 L8 P2 t; j! e+ k) O2 l# t4 l
) \+ L( a" p2 A6 D9 S0 {$ T+ [- ? |
zan
|