- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564568 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174593
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
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
|