- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565360 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174831
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)" Q& S6 r" \. a* S; C0 X
2 a q o8 l" }* i2 d
一、遗传算法介绍7 U# X6 `3 J+ a0 ?
G; w7 S5 ~9 ~6 F- |- w 遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
- l1 j4 ~/ j! @8 Z f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10 D% X, f) b5 g& t8 i, A
5 Y' Z9 l7 ]* L4 k& V$ M* p' Z
1、将自变量x进行编码, W) p2 n. g/ n' r) N2 ]3 ^+ R
5 k% B& J6 v2 L
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
& W! o9 P! C. B+ N3 g% t+ N ]& b4 H! R2 b k' h* h
2、计算目标函数值
; V: I2 H" B0 C/ I6 V1 Y3 l
7 t- v" E3 v2 b# |9 Z$ G, L 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。* n7 L% H4 F& ^1 i( s! ~$ v! `
3 p* [1 H# H$ y
3、适应度函数
4 c( h) Q% Y$ c9 p& Y* z8 z$ h$ b$ ~- P) q8 {* A; o4 C( u6 r9 O1 z
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
2 q" P( D/ [5 N4 Y! z* f1 b2 T4 }
% A- _$ j8 P1 ^! u1 T4、自然选择
, n! ~% U( ]. l; j' H& u4 V( n5 B) ?; v$ z2 U7 M8 _# t
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
4 P0 W# h9 y) b' ? r$ t3 r" `/ k
; f, }1 q& K: _( y/ c% _ A& F假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
$ r _1 q0 H: ^4 p
" Y3 F# J4 c% D0 U5、繁殖3 \+ f! G) |& p3 b6 m2 t
+ I# q2 A# M! D2 n0 f% f* v; g& y
假设个体a、b的基因是
+ G" m2 U/ y) @! w' ?8 ?# V2 P4 Y2 T# p" s6 I
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
; l! i; E' S& O# _8 N: I" N
# p% K! x9 F' J* _7 Fb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
8 G+ D! F$ v1 b$ E+ q) ^: X
& ~2 A3 H- }, J& Q9 A& w) N# \这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
# B% B; S, \9 S, r; f" ^$ Z1 @. {! \- r
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
4 _4 C8 c& S0 j; z) _; {3 x" ?
1 y! s7 M# ^$ h& h4 F) [0 Db = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
; q. f- x7 X9 t7 r1 E6 e2 k9 X2 C5 D+ I8 T0 |6 L* D6 y
交换后为:7 {& y+ k0 U2 h, v/ @0 i4 C
) B$ m3 v. C; w, M- \# ?
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]. E4 {2 g! L+ p' T) l
8 ]$ b( ~5 G' w7 G' Fb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
' l: L# F8 G% Z: D0 F
6 o! c* u& a5 ]! B0 b* j5 I) \( \6、突变
" _) ]3 k9 R! O
- d- r8 B! }1 \ ^4 q. U遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间- r- Q, p) @" R$ v/ a& }. ?
+ m9 z" x: i3 U% k
二、代码
) K9 E5 D& j' n9 _def b2d(b): #将二进制转化为十进制 x∈[0,10]
0 f" i. y/ T- n1 |; e ~ t = 07 O$ @9 a' c; y/ R( P# d" f
for j in range(len(b)):9 n8 p) H8 ?. l: I
t += b[j] * (math.pow(2, j))" X, o" |+ O* B& n3 z
t = t * 10 / 10236 [$ p& K! N4 d% \0 t# U
return t
) s0 V7 q# L- `3 m' J/ f: H2 @( r3 o" K: h2 j0 ?
popsize = 50 #种群的大小
! d1 h: z5 C; V6 B9 G# D1 U#用遗传算法求函数最大值:3 Q8 H3 l. Q5 V
#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
, }2 _5 a9 C' g6 ?) P0 R, G- Q5 `, {- o+ c! `+ m, {: x6 b" ^9 ~
chromlength = 10 #基因片段的长度
$ [+ ~( [! a. y9 w; s8 Zpc = 0.6 #两个个体交叉的概率8 n* c9 C9 |; y) m, L5 ~- r
pm = 0.001; #基因突变的概率# G: o9 [8 `/ n1 t! ~" W
results = [[]]! m8 _- Y' J* h% R! ?/ I2 w4 M
bestindividual = []
1 q: e3 A0 N' cbestfit = 0
6 e2 x6 Y5 d7 L; c9 `/ f# I- }fitvalue = []9 g) ?( Z, Z# {" f% T7 u
tempop = [[]]" T! Z) ?7 H. [. m$ u
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
1 }' R' Z8 F3 f# ~% Q# r2 kfor i in range(100): #繁殖100代6 z* {4 c! I# v$ ~8 D) R
objvalue = calobjvalue(pop) #计算目标函数值
- J" C9 W$ p6 Q5 ?. V" Q fitvalue = calfitvalue(objvalue); #计算个体的适应值6 R$ }" @4 |& S0 A0 h" k
[bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值# m9 S; |3 r3 E s, @
results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
( K/ w6 G. j3 r$ S4 J6 s3 U9 K selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体9 q2 R6 u* E1 B1 ]8 Z$ R
crossover(pop, pc) #交叉繁殖* ?4 m8 J) |$ t8 X0 e& F) o6 ]0 c$ T6 B
mutation(pop, pc) #基因突变' B2 N% K0 a9 w: C
$ L1 ], h* C( Z9 G1 P
) K" J+ M" G' `2 `% [1 Presults.sort() + z4 J. X0 F+ T: R1 y& s. W
print(results[-1]) #打印函数最大值和对应的# ~; G" o% O4 v m$ q
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。7 U" [7 L5 G! z" _% A
fitvalue = []2 m* J. V/ h& c5 L' Y3 Z- Q
temp = 0.0
4 q3 d1 `# w( c1 j0 z Cmin = 0;
6 b9 q' W: e' P" o for i in range(len(objvalue)):
7 X' x' x1 U" n( J3 \/ g if(objvalue + Cmin > 0):3 U' y9 ]- f! X7 d0 w3 J0 J
temp = Cmin + objvalue6 p" I) h) r% W0 P3 K. a
else:
5 d* V: U2 W% C6 C temp = 0.0
1 U2 J' f+ M; q- o6 k fitvalue.append(temp)
! B& A+ G* I3 e ~! f1 u& ~ return fitvalue
+ H" Q; h" D8 @6 Z4 } I& \import math
* O! R8 X; X/ g& v9 ]" K; C2 r
2 H2 a3 H8 `+ J' L7 K# s2 hdef decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
$ h, I& W9 u0 N& h" f6 p7 [ temp = [];
3 e: j% x; l$ I! v for i in range(len(pop)):
+ B8 [+ C5 f0 [8 P. c" } t = 0;- N$ j4 ]; j% B. n' O* y
for j in range(10):
H8 K$ ]' W& q8 U, `( C6 l t += pop[j] * (math.pow(2, j))
% ~4 M# G3 y, r temp.append(t)
4 n' `+ w/ \& d( H$ `7 I# ^ return temp; }- G, y. A. l4 h. o# I
3 ?- g7 g5 y8 t/ T
def calobjvalue(pop): #计算目标函数值
9 Q6 p2 Y+ T, z9 l) Y temp1 = [];
) L r/ D1 J' t6 F8 p; O: G objvalue = [];
+ `& s u, N( x: K temp1 = decodechrom(pop)
% m L; c% E F3 _; _: k/ Y' q for i in range(len(temp1)):
( r' x [7 g8 J% X& E! R x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
* R" V; J& M& K& A6 \5 c d objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
4 X: m8 T" t, }4 | return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 $ M) ~- ]) n( U
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体- ?" m" c! v5 u
px = len(pop)
8 a8 K7 n' N/ l bestindividual = []3 x) Y7 y& K) U
bestfit = fitvalue[0]
; `8 L8 J9 f0 [: K for i in range(1,px):
6 G$ J1 B5 d6 R- f U" Q if(fitvalue > bestfit):; v2 O1 S" i. ^: D( x5 A
bestfit = fitvalue
8 D% U9 c! U5 q6 S. o bestindividual = pop
7 u" b* Q7 ?% Z5 Y9 J8 U; W return [bestindividual, bestfit]0 t3 L, a: @' `* K
import random
& h8 u/ D$ X1 m" R/ N' Y0 T K
4 x; ^5 Q: i+ w$ \( n+ ^ @def sum(fitvalue):3 T8 ^" s5 a- M: D4 }/ ^# e' m
total = 01 r0 g6 K( J7 N4 r+ o( @
for i in range(len(fitvalue)):7 H; Z& t# g9 s4 S7 u
total += fitvalue
% g0 b1 X& y; m2 |& m/ j return total
8 V7 S1 `$ B7 L, N3 ^$ [5 u4 T1 }5 M8 I1 y x! Q: z. x; E: i
def cumsum(fitvalue):* S2 b" e: }3 Q7 a) ~$ O
for i in range(len(fitvalue)):. c( B: \& ~; @" ^) _% J! l& b
t = 0;
- t; @, x) }4 F j = 0;6 d ?) b% N( R2 l
while(j <= i):1 n: @* d R* H0 ], F2 z
t += fitvalue[j]
/ X& r) e- W5 o$ w8 H5 h j = j + 1! G* L$ ?2 s1 D/ ]
fitvalue = t;
k: \; o7 {! `) ^# V. l7 N5 E* c$ e% q; \& U$ Y4 ]
def selection(pop, fitvalue): #自然选择(轮盘赌算法)0 o1 u. M) R& B' m
newfitvalue = []* r' k) J9 k9 k9 ^5 V2 a+ f
totalfit = sum(fitvalue)
3 @" w. q5 M$ O. X for i in range(len(fitvalue)):
$ w' ?* r/ f& Y% _* T newfitvalue.append(fitvalue / totalfit)
- U h# U" O$ D) |. k( h cumsum(newfitvalue)
9 M8 q0 |# \# F5 ?, b u `/ H ms = [];
6 K+ C% p! C8 q- X1 q9 J poplen = len(pop)
2 ? `. g; W, k5 E for i in range(poplen):
% v8 P: B, {8 J7 {2 G9 q1 G: P: r ms.append(random.random()) #random float list ms* M- f8 k$ M* `# a$ @9 W
ms.sort()
1 e: |* X8 Y8 A' O0 O) \* J fitin = 0
7 H' ^0 R$ t2 q5 v/ [4 w, A2 f newin = 00 k. C! [% ?. x/ d3 V5 F K
newpop = pop5 c; e$ Y& d+ M5 k1 ^
while newin < poplen:
# `- L4 I+ E8 }; l. f if(ms[newin] < newfitvalue[fitin]):4 H. S1 d* [3 z; t
newpop[newin] = pop[fitin]8 F; G% o% V( `+ a) K) b
newin = newin + 1
) y* W* E0 V7 A6 N else:+ N" H5 \- E) A, s8 \; K
fitin = fitin + 1
) ?1 B3 O8 @+ @* ~ O3 e( p pop = newpop
" J8 k# f0 g. O: ?import random( c0 p P7 q s
, L7 s b* R/ Q0 `* N1 w/ B: f0 a
def crossover(pop, pc): #个体间交叉,实现基因交换0 b% D2 M" p/ F o6 ]! S
poplen = len(pop)
7 o/ x8 O$ e$ {$ Q3 O: K for i in range(poplen - 1):
+ w! x" M4 t7 Y3 k8 j if(random.random() < pc):
* C6 d: E8 U$ r cpoint = random.randint(0,len(pop[0]))
0 v9 A( R! n5 |. x* W) H temp1 = []7 I! I6 x9 v3 R; X
temp2 = []# I- }- {0 F& v3 l4 t3 E
temp1.extend(pop[0 : cpoint]), b, a' y" t4 V4 X: ] j( }
temp1.extend(pop[i+1][cpoint : len(pop)])
* Y0 w2 o n% M6 |( x( r% F o8 J4 Z temp2.extend(pop[i+1][0 : cpoint])
" Q+ K( _/ ]$ T' p2 Z temp2.extend(pop[cpoint : len(pop)])
6 \& i+ v7 K% @" e5 F pop = temp1+ T6 r1 C; Q' S$ I2 O
pop[i+1] = temp24 `; A B6 K* e8 u5 N) ?
import random
. v3 a1 [- a2 b! w) @/ h2 @
+ c* a+ H% W$ G# W7 y+ c# P2 W2 _def mutation(pop, pm): #基因突变9 L" `, \% K# y5 ^6 ~ ~1 k
px = len(pop)+ l9 r. j& k% b$ t# d
py = len(pop[0])) {5 g9 Q8 b8 p+ e! p W1 t8 N
, `. V2 Y% n0 e7 @. [* h for i in range(px):
% ^$ X* V' u' k3 d$ _1 Y: q if(random.random() < pm):4 g! b2 H) w3 g( b
mpoint = random.randint(0,py-1)
- x/ J- i: E; }& M if(pop[mpoint] == 1):
A; }" E* U5 ] pop[mpoint] = 0 J! ~, n) V# K9 k# R/ W& e
else:
) T/ a1 J5 y* ^3 p/ G pop[mpoint] = 1
& z0 ^; }9 t) Z3 m
+ L: n' H: V7 L# |% d5 Y6 Y. Z
0 G! s: `: w7 [" m9 k3 e————————————————7 Z j# k& S2 P0 q9 W8 \
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* c. V4 P# `4 F原文链接:https://blog.csdn.net/u010902721/article/details/23531359* o3 ?' ~/ d. l' g
% z8 g: u# M9 U0 r- V
' w1 U; ]1 p4 w) P/ y8 R: @
|
zan
|