- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565365 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174832
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)8 @! J$ F3 b3 x& c
2 `, \) I- N( l! i一、遗传算法介绍# ~, g, e2 S. K1 A' _9 }' Z6 W. B
. ^) d% Q( C- |7 J" @9 t' H: u
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。1 v+ c! q: {+ z) D
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10- s! W1 E3 ~3 N/ t5 w- G3 E
3 `, w0 }$ V) R& D6 [' ]
1、将自变量x进行编码+ h0 U0 U v) ?1 s. _( T @7 _' v- N
8 `2 n/ \; M( v8 A0 l 取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
0 O( j! q$ Z( o+ S) x
, X# \9 z% U* E2 S# z! T+ A! W2、计算目标函数值$ E9 |6 \ }9 s c- g1 \
0 u* v$ Q$ S' @# m( Q. I" W0 w
根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
; `1 o% Z, \* h6 t: s5 C- v1 v4 T/ R
3、适应度函数
* m) w1 R6 n) S. ?$ D; k+ w2 r l7 s( I8 s9 s' {
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。% f2 w f7 u. x( c4 H
2 o" W# [8 w+ X- `8 b
4、自然选择+ P; |$ o" c+ I( {8 T
+ D6 M8 @; _3 y% `$ {/ o$ e, _2 w
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:. h, @2 I8 I; l0 O5 ?
! n5 e8 s1 e7 {5 N6 C# Y$ f5 A假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
) G) \" X$ k' b. f4 N/ x5 o% F5 g- m: G( `1 e
5、繁殖& J: x F/ E3 ]; ~6 G0 w ?) M- a
! r. w& b ?8 S3 A3 V假设个体a、b的基因是) c/ H4 ]2 \8 y" c0 J9 e" K6 h
# P' q% K y" |a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]$ L5 W! S/ `# G2 D) S
4 m! E' f4 _6 ^' \# T7 n9 l4 k) ^b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
: t$ w) p" o0 i9 t! K5 U# l$ R0 j
- D& _. _+ v4 }6 `+ R( D, X这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
8 U3 p. P1 [2 g% b. t8 ]! \7 Y, ^ m0 v
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
* b' w; c) i- z6 m, P! U; p7 u$ i& s
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
8 W( P1 E) |' c+ d- e7 |$ G6 c8 t* |4 O' I
交换后为:
4 M0 p* ^( R/ ~5 y. v1 c1 n; t/ p& H3 y, r
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
$ b5 _% @( s: K: {* Q+ N( Z, C$ n( w% }1 |: \& \9 ^
b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
7 G% a8 t; A+ F2 H$ b8 u* N5 m* \% x5 U# u" L X
6、突变
6 S ?( d8 T6 q) `7 u# ]' i, I0 c& T: V1 m8 e. P0 Y
遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
1 @8 c {/ n) x+ [6 h# U* P. I( H- X* G2 b
二、代码
5 w' i4 { n! m! b3 r( Jdef b2d(b): #将二进制转化为十进制 x∈[0,10]
8 j9 f, B2 r, k! ]$ N* v t = 0
+ n( J$ t- R; l& |3 P- w" O for j in range(len(b)):
* Q7 S7 y$ F2 q. `" d* g t += b[j] * (math.pow(2, j))
[* h! s5 l! d, R1 {. t* k6 I t = t * 10 / 1023
$ ~; R u4 F9 ?8 o+ w8 X- ~: ~ return t
: s, D, }! ]' H
8 G, `6 g3 C P2 n$ P1 F4 Cpopsize = 50 #种群的大小
7 J* r. j C$ K& l: b0 r4 w$ x#用遗传算法求函数最大值:
- ^9 a: F3 n) g$ P#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
1 s' i! f0 J* _2 ]& N2 Y1 F G( D
chromlength = 10 #基因片段的长度; O$ z; F( h# Q" Q v0 Y& @) o- f
pc = 0.6 #两个个体交叉的概率
1 m& z* @+ v( D' n7 U) o" V" Dpm = 0.001; #基因突变的概率" ^9 ~0 ~5 C( z" N( v. l
results = [[]]
o2 {( H! h& ?* H0 d7 Qbestindividual = []
% e4 P1 K$ _1 V2 ?# I+ ^: [bestfit = 0
3 K' e- U: ~. v- V+ \fitvalue = []( G$ D% \8 r2 h. _. k
tempop = [[]]$ ]8 M5 F# A% S, J
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
* I, O2 I) o* I1 r0 Gfor i in range(100): #繁殖100代$ A: c3 K; V1 \* e2 w9 K
objvalue = calobjvalue(pop) #计算目标函数值
& @0 x! _" @& J fitvalue = calfitvalue(objvalue); #计算个体的适应值
. }, e7 Q4 w T! a) j2 O- w0 y [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
7 M- T* |" d# N8 Y; b B results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来' {& i4 r* W# g8 ]. Z7 R% ~* h
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体2 S4 q* n6 w: B; Z. D' q& j8 T
crossover(pop, pc) #交叉繁殖
1 V1 e( s$ O3 `& U/ p3 a" C1 u6 K, T mutation(pop, pc) #基因突变' o. u6 |6 e# H3 C, A
5 |5 u. y8 [; T% h
5 P; P4 S1 K' W4 u1 fresults.sort() % m% a9 Z0 t/ X
print(results[-1]) #打印函数最大值和对应的
0 J, X% B( [. F; s+ y5 @; {# Udef calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。" {! F- |4 G6 m& h, u! B% e- K8 u
fitvalue = [] b9 H( V! @+ u$ e
temp = 0.0
% J! @6 S" P$ ^( n. x Cmin = 0;
; E1 u1 _) P0 M) S Y$ W& |7 Y for i in range(len(objvalue)):4 C% F6 ]$ P/ D
if(objvalue + Cmin > 0):
6 P! Y8 U- V. ^& w9 C1 Y7 R temp = Cmin + objvalue4 W, J- t2 ?! V5 ?6 I* _) r+ L
else:
# w" C: q( s3 |7 c temp = 0.00 m$ ?, s& \7 u( N H9 \" w+ j
fitvalue.append(temp)# V! Y @1 ^6 H& T$ |& |7 U h% ~5 A1 C
return fitvalue
) z; W$ ]4 ^' r/ E& z; [" Dimport math3 [ M( s/ o- i0 @! t
6 F3 \5 M) {! Y- |5 ]def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)1 ]9 b" V* ]9 \: j7 S: Y
temp = [];
. O$ T: r" H1 H2 ]. h for i in range(len(pop)):7 J7 g" @0 {* u% h7 ]1 G# `7 j
t = 0;
3 f& f- o5 j, k7 _2 z$ L for j in range(10):7 c4 u u8 |6 s+ T$ V2 z9 e
t += pop[j] * (math.pow(2, j)), O+ w+ O$ s* }: A% ~7 _
temp.append(t)
- E' x4 u/ y0 R return temp
& i% @5 P" I) ?' x% u2 P+ y% s7 G0 L1 f! x$ q
def calobjvalue(pop): #计算目标函数值
" I4 |$ Y/ f$ c temp1 = [];. d8 g( C6 N# b
objvalue = [];7 n3 v" K) y/ h2 n; h" T3 e
temp1 = decodechrom(pop)2 g6 t" A q) T* h# v
for i in range(len(temp1)):/ P# m: W6 ^/ u, T: @% D
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)) p4 h0 y1 E( x0 Y! a9 T" i6 @
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))' f6 I4 \$ J5 ` U" @
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
" J3 h U+ F! ^; \+ `def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体# }4 U4 S/ D; h( r8 q' ]! C
px = len(pop)6 {+ p( P$ j0 a: \$ x# r
bestindividual = []
7 ~$ ]+ {( m# p( [7 A( }+ @+ d bestfit = fitvalue[0]
& b7 ~2 i1 ?5 s for i in range(1,px):; M; F! _* o$ C2 q. \
if(fitvalue > bestfit):+ M. e6 }/ C. ^5 |
bestfit = fitvalue: o7 A" }; A. b
bestindividual = pop2 p4 D$ o/ P8 H1 q! w
return [bestindividual, bestfit]
' k$ E1 T( \5 p# M2 R6 u. Yimport random
9 B) n& l1 y9 L2 ? Q* {" j+ r& b7 Z8 [
def sum(fitvalue):
, }9 c8 s b! R& ~. V& M* R total = 07 U' Q; K! k, u# n: L
for i in range(len(fitvalue)):" q* M/ Q. b8 u+ B. O7 j: [
total += fitvalue- F2 K G, |& |2 T
return total
$ M/ g5 b2 P U+ t& A; ]. i
s9 h" k* o* r7 n1 fdef cumsum(fitvalue):* a8 G- g- K9 P/ Z: D
for i in range(len(fitvalue)):
* A& U9 G. u: l, L+ c1 K2 T t = 0;. z% C; K1 {. |% z
j = 0;
2 H. e A- ^) {. f2 F2 f; \5 N while(j <= i):
, f/ Z8 P; o) V+ n5 l) O' [ t += fitvalue[j]3 D5 k9 T* L g. U3 U: h
j = j + 1
# R' ]( L5 u& l3 [ fitvalue = t;; y' F- `) L+ O \) j5 v! r
4 l/ J' ?7 y" z8 u: C
def selection(pop, fitvalue): #自然选择(轮盘赌算法)
. e# p# g- J+ u' M newfitvalue = []4 m- s! p% h0 C
totalfit = sum(fitvalue)/ a4 C A3 {* L4 z2 c Y' V
for i in range(len(fitvalue)):
( J% A. m( \% _4 g% z" Z( g newfitvalue.append(fitvalue / totalfit)% C3 C* Y* W. [" W
cumsum(newfitvalue)
2 y! _: M/ Q/ F) ?$ k( p ms = [];
' ~% G/ Q" w8 ^& { poplen = len(pop)$ f# q0 y1 o. {( N0 A! c
for i in range(poplen):* B2 `/ \1 a \; c! b. j2 n. A
ms.append(random.random()) #random float list ms+ v+ C! ]- v2 V$ K
ms.sort()
- Z, L( R) g/ q/ R% X: I* {4 f& K& F fitin = 0$ P' q. W% e) }4 P: e5 y- r' T
newin = 0
6 f/ V, M+ u3 n2 {! ?: X2 o newpop = pop# r. A; J7 _. S' w( K' S+ h
while newin < poplen:) v! M4 D" X/ Z; }& r
if(ms[newin] < newfitvalue[fitin]):
/ S9 M. _( O b newpop[newin] = pop[fitin]7 B$ A4 I7 ]8 q4 Y% _" u
newin = newin + 1# a/ P$ v2 I( k" i) Y5 C1 {
else:
; { q( x6 Y% \8 d: O& u fitin = fitin + 15 C8 c( K, e' X0 }) I
pop = newpop; \1 }: O7 C8 I& h8 k& o
import random
* ~( _: q3 O: t
1 W0 W- J& P6 [" w# |' tdef crossover(pop, pc): #个体间交叉,实现基因交换
5 ` u8 j. Q* [6 o! f2 A8 q poplen = len(pop)
( o8 c4 b7 s: h for i in range(poplen - 1):5 Z5 ?3 }8 x4 F5 }0 n) ?* Q! T3 a
if(random.random() < pc):
9 H6 g/ ]/ d8 Z6 P6 i cpoint = random.randint(0,len(pop[0])) q/ }8 }4 V% n/ ^3 Z
temp1 = []
( |4 `, h* n0 z temp2 = []& u. c7 V7 v4 l* p0 o* M$ T* ~
temp1.extend(pop[0 : cpoint])
' C: A5 \; ^+ B; P$ T temp1.extend(pop[i+1][cpoint : len(pop)])
- G) H8 f4 a* G temp2.extend(pop[i+1][0 : cpoint])
7 H$ s0 `' ^: c! b0 x temp2.extend(pop[cpoint : len(pop)])5 q7 {/ Z8 ~$ p! N* \ M, ^& M
pop = temp1
0 ^' I; {1 @2 X9 r; A8 |& d& N( F pop[i+1] = temp25 L9 a- o( t# Y/ d- A9 p" a2 j& }
import random% u8 h; l; C) M! {- P. n: S$ |
^0 \! R! q) Idef mutation(pop, pm): #基因突变7 ?# `# o' t7 ?$ Y6 N7 r
px = len(pop)
8 X9 D g. b, u+ Q3 F: J py = len(pop[0])
; _" e" U/ t/ K: ?
# J, @9 p# A+ }) u! s: j for i in range(px):
. P# l! T$ o* @! ~- A* L% T if(random.random() < pm):
7 C. b. p% E5 H mpoint = random.randint(0,py-1)
2 C) z* n0 ^ w" { if(pop[mpoint] == 1):- |. r) g/ c9 X3 {' e) p
pop[mpoint] = 0
6 x+ X# k$ Q9 q5 N else:
" G/ _# U3 ?# h* l pop[mpoint] = 1
0 p7 H! U1 b5 [" Y3 F# X1 R
; V7 C7 s4 R1 g+ ?! l) x5 {8 m& Q* |; c- A
————————————————6 i6 j; X4 ^) _& k5 r- F: [
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
2 G" a3 b& @$ j/ e# J0 y2 V原文链接:https://blog.csdn.net/u010902721/article/details/23531359
7 z2 c( k+ Y8 m' \' r# r
- h j/ _- o" X/ W! e- p- ]( g" X1 T% ~" l/ p1 b% g' C
|
zan
|