- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565408 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174845
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)
/ t$ ~& M$ b/ h& Z; R% {6 g0 ^, D O- L6 T" X J0 W
一、遗传算法介绍
- m8 p8 G5 g& J) ~3 E- i' l9 P3 f* U- l
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。' f" J1 s/ _+ s: f Q
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10
5 E+ Y0 O; F- f) e6 c' w* d$ o( t4 g2 b7 d" f
1、将自变量x进行编码
: Z& y3 m! w4 d0 Z; b* M
/ b; {8 O+ U4 J( \6 t3 l) b: J- m. v1 E 取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]2 k/ _, F" f; F; {- E
, r& [: o, I2 [5 [" \/ Y2 O$ I
2、计算目标函数值
3 o# D* _( g* m, L, L1 _8 E& ?8 h& A2 H
! W3 ^- R: N* X 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
2 g" u' O, M: m; t9 e, f
) r J" I: q! Q8 _+ E+ `) l3、适应度函数
0 e3 ?3 I8 d! i/ E- J' Z1 h) v, ^6 M" \, E( e
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
& p# U8 N4 K5 `) o, D! L, X; j( ^% a7 f+ ~' v' a) d. x
4、自然选择/ W8 ?; h: I: O2 i
- _/ [% p0 D/ C0 s! ` _- ^
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:$ X8 C; A& F* c( P
1 c8 ?& { N9 }/ C+ G2 l% X假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。* z+ U' ~/ N3 G7 P5 D
@- z6 D) E" J' `0 p) G5、繁殖
) X! r! r: S, ^9 P1 E% V' y9 D3 n6 v) ^
假设个体a、b的基因是4 K$ X: I8 h5 G
4 H, E5 a# Z! M; u" F5 `4 O
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]! `' n+ b( V7 ]) |+ n
|. h$ x; A v( y
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
0 b2 J. ]# u% W) [/ i
0 e3 ?- D/ a4 [7 J% ^% T4 P8 G* q这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
& o- J. z( S- Q) U: Q7 i) U3 k, X" f
5 z5 k, }9 u8 Oa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]* J1 W' m) V+ G; y6 _) g3 G0 f9 {6 Y
3 O) }# L) m- R, xb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]4 h/ Q1 V5 n1 X1 b$ y8 V
# o: i- c# y0 L- H1 `
交换后为:
; a& r6 J6 O( R& v& ~% d1 h/ y5 {! s. O( M2 g. L7 ?: C2 z* E& ~
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
4 N5 z" o6 P- x6 X% l- c2 U
2 Z: A8 T; [/ j: {$ f2 j6 e' ~b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]( S" t6 X# p; x, e5 e$ j/ L7 s
* L5 K: z) q! j" {" B4 c
6、突变
$ p7 g5 I% C& J+ y2 u. t5 b
. t8 n/ ]/ n2 k% P5 e/ A; L$ Z. a( ]遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间, q1 `( W5 p# g. S1 u
5 [3 M1 R* g' I2 I& E1 w- p/ c8 J二、代码
2 x% W4 b. n5 c( R8 W# ^def b2d(b): #将二进制转化为十进制 x∈[0,10]* n5 U, m n1 N0 t
t = 0
. k& e$ D+ t: [* {2 V, Z; R for j in range(len(b)):
8 g* \2 d2 h& b- m( {- c t += b[j] * (math.pow(2, j))
5 D5 r% P0 r* F& ^ t = t * 10 / 1023
4 B6 I4 H, V* g* t% B return t9 z; U! V7 P6 N$ h4 L& G) R2 ?4 G5 U W+ }
. ]% O& k( g% I4 m5 bpopsize = 50 #种群的大小 `0 J0 N! h: D/ Q+ j6 I6 Y- `
#用遗传算法求函数最大值:
+ s5 X5 ]9 I* o3 H#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
/ k8 v* r6 b" G* y. t) d0 I9 y0 G2 t
chromlength = 10 #基因片段的长度
) l8 y) b5 r) M7 ^8 o' Rpc = 0.6 #两个个体交叉的概率
; q1 W' w0 |! f! \, k$ Spm = 0.001; #基因突变的概率 K3 a( M# l6 d2 Z
results = [[]]: P; G- y d1 |7 f$ ]& ~. r5 A
bestindividual = []
$ ^; I4 l( l: B: \; F# b, t7 u' qbestfit = 0
" e5 r) ]' ` N' C1 Zfitvalue = []
5 s" S, B( w& V+ u* H* Q/ Xtempop = [[]]
! r T3 \' K/ E7 c7 d4 @7 J+ i5 y4 Dpop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
, {1 e( \7 P/ |! Cfor i in range(100): #繁殖100代/ C' `8 t$ g9 x' Z- ]$ G6 d7 s2 M
objvalue = calobjvalue(pop) #计算目标函数值$ l7 @) S' K! |2 D
fitvalue = calfitvalue(objvalue); #计算个体的适应值
" A* ^; o: q: A" o0 E [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
( L5 k% f2 R$ H# p4 C results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来: T8 v9 G2 A1 b6 S9 I: D: C
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
3 P- h. ?5 Y# E- D9 u! P crossover(pop, pc) #交叉繁殖+ T. F! B: b$ y7 o2 m4 X5 |
mutation(pop, pc) #基因突变
& |7 u! ?' N) D' e! ?
$ z9 X7 I2 a7 I5 R l' w- k b1 E `3 P2 h
results.sort()
5 ?; v) s1 p/ eprint(results[-1]) #打印函数最大值和对应的
5 X! L8 G e) w4 l# S& }def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
# [! Y6 e+ F, k- H+ p x5 Q fitvalue = []
8 {' ?7 c) F& u6 h* Q6 u temp = 0.0
$ X6 K+ U q! c3 e1 e+ u Cmin = 0;
+ w' y# A+ a# F# S for i in range(len(objvalue)):! X7 l( r/ h# ^4 h7 R* Y
if(objvalue + Cmin > 0):
9 \) z. a( p* ]4 f+ F* q0 s8 }( o4 g temp = Cmin + objvalue
1 s. O% o! y( L+ e$ K# e else:
7 a! L9 X/ T2 U! H3 X/ N/ k) V5 ] temp = 0.0
% G- a) p: q, C6 I fitvalue.append(temp)8 ?! f' q( X* V, \+ d
return fitvalue( e" T7 o. U& [- e7 G% c* @7 g
import math
; ]4 ?4 p/ O0 P, W" D, M* o. x- B. V6 O) ~# N# } W
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
. k, R* |7 E- d" | temp = [];
& _1 K `8 O4 F4 }- m5 l* ]0 L for i in range(len(pop)):" \4 h" o* n4 C' S& u' s9 Y' v j* n
t = 0;
* l# y- i9 ]5 R7 P4 |' X for j in range(10):
' ]8 g4 V& M- | t += pop[j] * (math.pow(2, j))" v9 Y" P# E$ g2 X
temp.append(t)
4 N4 c, Z2 H3 r8 w9 W& ^ return temp3 i8 n6 o0 p3 M1 S% k( F1 U. e
+ ]; K$ j, ]& j* y* C6 R* x0 w
def calobjvalue(pop): #计算目标函数值
/ `& p, q- ~& a! ?' v temp1 = [];9 I9 } v2 Q. P- ^1 T' ?
objvalue = [];
. A( z6 h5 t) i. k# p temp1 = decodechrom(pop)
2 U" T. ]/ f G, N9 ` for i in range(len(temp1)):; w3 { a' U" b; W/ g& y8 Z$ h
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
. o% B R }' O% Y objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))0 K$ X& d4 X3 c) X% D5 } [9 D
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 6 j9 v# _3 ~. o1 s7 r% p
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
- R3 v6 c! ]7 s W3 w% y px = len(pop): R1 L5 K4 |2 D' y! S% x
bestindividual = []1 J! C1 ]* N9 X: ]' n7 P
bestfit = fitvalue[0]( p7 y8 q+ i3 }: o) C1 H
for i in range(1,px):
+ T, ]. L* i8 l A' d5 K* k if(fitvalue > bestfit): x/ J9 X# y+ S9 c7 r
bestfit = fitvalue
! w' W% U$ M) s) C5 }6 K bestindividual = pop, w8 c: y0 R, g; i
return [bestindividual, bestfit]
. r& t6 c4 Y1 h6 g himport random* P7 V. C% ]" K3 ~5 b
7 o: X: ]8 ^* y4 H% E; }* V- R% ]
def sum(fitvalue):- a1 d! k4 y2 c! s# g* n3 N2 ^& d
total = 0
3 Y2 h9 U/ T8 `& d) } g7 j# n8 y* M for i in range(len(fitvalue)):$ J8 f* B8 u4 T4 d. d
total += fitvalue
! f4 ~0 q& r+ e# H1 m3 O) Z7 ? return total
6 O5 a4 N6 F" `2 a1 k" Q, @' y, }' K- g; M* t
def cumsum(fitvalue):
1 s' t! D) E' t8 O" C for i in range(len(fitvalue)):
$ N K5 X: h7 J2 h t = 0;% u2 v: [! y+ Q
j = 0;
; I. c. r( O9 y while(j <= i):" t$ l$ h. \4 G1 H. y% d$ x8 ]
t += fitvalue[j]
( ~, y7 ?. G" q, b4 f j = j + 1. F9 ~8 N: j$ J; J0 s
fitvalue = t;
# V, }2 t5 N$ P8 l( U8 `8 H: q+ o4 Q" A# S
* q# m7 [- P4 `0 F/ E% Tdef selection(pop, fitvalue): #自然选择(轮盘赌算法)
7 w) Z9 ], S V, x# q: V9 G/ @ newfitvalue = []# Y( g, z. `* m2 o1 {
totalfit = sum(fitvalue)
$ J! h) S* |+ K% m- e6 L8 I7 C for i in range(len(fitvalue)):
4 V9 F, D$ r0 ~$ w- b4 a" g& W newfitvalue.append(fitvalue / totalfit)- D; g: J7 Y5 k5 }8 u& [3 l8 C% {9 s# _
cumsum(newfitvalue)
- x4 u. d" M. X ms = [];
/ `& ]+ V& r! u4 d" N poplen = len(pop)
' I1 k: {7 D( r. S/ T3 c2 Y( q6 j for i in range(poplen):2 j: {( n3 y; [& J, H+ r/ ]3 O
ms.append(random.random()) #random float list ms/ G/ P; q; L3 j! t1 W Y& {' y
ms.sort()
; s- Q( J# h' g0 ~1 S) x fitin = 03 i4 Z) z" z6 F0 ~
newin = 0
) r8 m- h- N2 Z& t3 ?: Z newpop = pop
) m- n& R5 \4 s( B while newin < poplen:
( n7 S1 |7 P) F9 p4 }% B m if(ms[newin] < newfitvalue[fitin]):3 S" g/ _1 Q0 N( a+ l
newpop[newin] = pop[fitin]
1 g: P* r" S# h( G newin = newin + 1* t7 @) w8 m: }5 e1 i6 c" O
else: {4 Z, k/ w( }- H" c
fitin = fitin + 1
1 w: n% y" O: b7 }6 N7 B# L pop = newpop
" T! D0 k2 f4 Q0 Rimport random: ^( F$ X' _1 T# h7 c* b [
8 Z% `4 S( _" E% Rdef crossover(pop, pc): #个体间交叉,实现基因交换
4 q' V/ _7 `; i. k poplen = len(pop)
: x5 E$ X# A2 }2 J! G for i in range(poplen - 1):
* a: V) g% l4 ^9 V; Y if(random.random() < pc):
9 A* |, \1 R' p9 ?% V4 t cpoint = random.randint(0,len(pop[0])), c; `2 S2 u8 @& [
temp1 = []7 Y' Q8 _ E$ l, K
temp2 = []
8 B4 }7 k* r! Z temp1.extend(pop[0 : cpoint])
8 B$ J* s% l3 n( V7 V temp1.extend(pop[i+1][cpoint : len(pop)])4 R( T( |3 Q2 W4 E0 g4 _# V
temp2.extend(pop[i+1][0 : cpoint])
. E/ A& J# j! k( F3 E( ^% D temp2.extend(pop[cpoint : len(pop)])
4 \: Q T7 ?2 o' J3 G" w; r pop = temp1
5 |5 u, p. g) a+ K0 g d- m+ p! j pop[i+1] = temp2
5 x5 Q3 R* M) g1 O( H7 simport random
- S* F: _; D' S% ?6 r& D* C: d7 @* T$ G& }$ i
def mutation(pop, pm): #基因突变
5 c& A* J6 R/ O, y px = len(pop)
! M3 F! v3 S* a3 w) W py = len(pop[0]); B. W( F' ~% H! ~0 l) V
& R% }1 s! i# }* ]& u
for i in range(px):: P! l6 W5 U$ o
if(random.random() < pm):
! K4 w( O( O( l: |) H mpoint = random.randint(0,py-1)# C8 A5 u5 q L" R
if(pop[mpoint] == 1):
3 o) m: Y) y" X6 q pop[mpoint] = 0
o" b+ u: `2 _ else:
) f- {! n/ q. U* ?+ k7 F pop[mpoint] = 1% m* G1 j0 f. \
" V( Q; l& b, u
' h+ H$ b' T& B0 r, A: u2 K" f
————————————————
( N7 O0 P. s3 u版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
3 H; b; y6 T, B1 s原文链接:https://blog.csdn.net/u010902721/article/details/23531359
! i6 A' K/ E2 _5 i5 A, q; c$ F& |; P$ a
3 \, n. l2 }4 N. O) p
|
zan
|