- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565407 点
- 威望
- 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实现的遗传算法实例(一)3 l. j" a8 D+ F8 @
* t' ?0 ^& e4 y2 j. u) o一、遗传算法介绍
. t. Y. }/ r! c3 p# D- A% d5 |6 q2 j5 v0 f, ^& Y7 Z; N
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。6 p- p) i0 _2 h5 l; r) u9 \
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10* d5 m, y& j0 F) L# @
3 w$ H/ Q+ A7 r& Q
1、将自变量x进行编码
3 F4 e. N3 b( }7 S% V# l% q6 \/ [1 w% [- A
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]3 M5 z9 } W b& H0 K9 n( Y) b
5 X7 X" g8 y8 }7 y. K. T- |% _
2、计算目标函数值1 ]. ]8 a5 s9 z$ {- F
2 P/ z8 t5 S+ s9 t9 f7 f
根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
" K8 h% Q/ k; G8 ~2 A4 ?4 N& F
/ s! M1 n, X2 _& z1 v3 T3、适应度函数
) a! l" o/ m% w# x! @5 C! ]. [* ]: w0 O( T: G
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。/ s3 d1 p% [* a% Q6 b
% U6 Q9 J9 v* z! ^3 Z* m v0 @4、自然选择7 M* `2 t4 N2 o9 U$ q$ Y
% i$ c/ |! A& D4 c8 t' r7 Y* e/ x自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
( |* r g: x3 n; g% i( y+ P/ a! Y" J# u
假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。7 E$ |3 V, Y& _: {0 p
: K, C2 l9 C7 W; z7 b5、繁殖' s: `& P% g: k% {
8 R8 `* ?9 I% E6 r& e. t5 c4 C假设个体a、b的基因是
3 ^# {3 [1 J5 i9 v& n
- s8 X. [4 b3 s" {7 A" |4 Pa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
) P8 F2 x' u; {* ^* N
/ }9 Q H: V, r8 D6 kb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
0 `, g0 y6 T) c, y3 S5 J' @) z
6 D- }: Q) ]7 z这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
, n& M x- z/ ?: l" `& r
w8 ~0 w. R( |a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]7 L8 {- s: g, Z& B
# k8 f7 M8 Z/ U: Z1 Nb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]$ Y7 d+ c7 I9 W+ s7 ~
4 O s5 a( @- ?
交换后为:
; {% h( W8 ~# R" Y* s L* a- }6 W" j ~) x
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
' F* [! |# z h: K" J+ E
! w; B* X' A4 m6 yb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
3 P/ q8 W' w0 H* u* s' u' Y: w4 _, c, x D% ~) }* d% L; b
6、突变
4 E! K% q- ~3 s1 U; z& @# h# Y: R, r/ w5 X- t F# l
遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
' m/ u5 d, s( f, K; ^3 F7 @0 o$ I. c$ G# j
二、代码
1 S- C* Z, q: c: k- A4 M( \% edef b2d(b): #将二进制转化为十进制 x∈[0,10]; T( s% ]( I9 g! j9 c, c
t = 0
- z5 [+ [. ^# m1 v2 C for j in range(len(b)):% k1 g- J0 j' Z8 n
t += b[j] * (math.pow(2, j))8 `" n4 ~- u' n9 x" y3 p3 y" r" S4 a
t = t * 10 / 1023
6 R& h6 x( y+ r" S, b* z return t
- G. ^8 m2 Q c0 l* o2 Z. f- I2 ?& p, o; C% @" c) r
popsize = 50 #种群的大小9 P6 a1 R" V0 X
#用遗传算法求函数最大值:, k3 o1 ~& b8 I4 B) E6 \
#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]3 u! m7 U: U7 x6 @, b+ L* M
0 \: U Q, r: {4 D0 T
chromlength = 10 #基因片段的长度) d7 e7 N2 x% J% a$ a
pc = 0.6 #两个个体交叉的概率) M8 _; f6 ~2 Q8 G
pm = 0.001; #基因突变的概率& _/ _7 y5 ]9 q3 ^: A! D
results = [[]]; i0 e6 h% O ?( z3 i. l9 X: K0 t
bestindividual = []
: f! r4 G: m* M0 y9 Gbestfit = 0
F& Z4 H6 V/ ?; {/ Q- rfitvalue = []
$ Y6 f8 l7 y3 Ftempop = [[]]
. n+ }! r/ @. J4 Z" {pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]- V+ i8 @0 m( {) t
for i in range(100): #繁殖100代& M* Y/ f& P! Y
objvalue = calobjvalue(pop) #计算目标函数值4 i1 t: O( l! ]- k
fitvalue = calfitvalue(objvalue); #计算个体的适应值
# r( o3 o G, I. P [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值1 l5 h. M! e' C# F' X
results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
5 w9 B7 |. P/ t$ ^ selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体9 X v9 f0 _) ^9 _6 f
crossover(pop, pc) #交叉繁殖' e1 f `$ l9 v) g8 ^8 t) z
mutation(pop, pc) #基因突变6 \" n- W5 y1 C2 l' d
; B% U* Q5 b+ r
) i# F. Z5 |2 D4 q' e& `
results.sort() & H3 T. \" y. ~
print(results[-1]) #打印函数最大值和对应的8 `6 B9 Q0 z. t" a
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。+ F- L5 D, c' o6 ]0 ]# r/ b
fitvalue = []: f4 K( J1 w4 P4 D# g
temp = 0.0
% }& U% h7 \8 k- t Cmin = 0;: s- F* z) R7 R" L1 ]9 @7 P# ^, \
for i in range(len(objvalue)):: V- X/ I! E$ Z: D9 q* N6 i% g
if(objvalue + Cmin > 0):
+ D9 @5 \+ ? P$ x) D% @ temp = Cmin + objvalue5 d# d% y* |$ `! l; o5 s; ^
else:5 u' D) r- ~' M- L, r- S
temp = 0.0
1 c3 Q8 z; ]5 V& P- q8 N fitvalue.append(temp)
9 F! |/ M: S: _6 y7 P" S2 ?7 K g6 g2 M return fitvalue
( a& y. G7 D# K1 s6 [9 Y! B+ Nimport math. c/ c% w& I& ]: k3 r- z
+ d& N% [7 ?* _7 U; F8 `( J1 ^
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)/ S5 i% ^! ]2 n$ t. ?: v
temp = [];5 W/ r1 B9 |/ V
for i in range(len(pop)):
; i n# \3 S7 G3 ~" J! i, U t = 0;
$ ]$ {6 l7 q% Q9 H9 C n for j in range(10):
* D! W1 H( b+ e5 h% K t += pop[j] * (math.pow(2, j))5 `- S w6 f0 h4 o3 E
temp.append(t): q: i7 y, q0 q
return temp
; D, Z* T. m& i6 q9 t4 ~" L% Q* B9 t# m8 u
def calobjvalue(pop): #计算目标函数值. h3 A- Y! V2 Y
temp1 = [];
* `3 @/ G# i. b: q2 E objvalue = [];/ f5 u6 x1 b5 {3 A2 z! K
temp1 = decodechrom(pop)
; E, ]) v3 i) G3 t0 j3 a for i in range(len(temp1)): z3 X) T3 o! A9 Y' |! s
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)
, U6 L( C9 e1 M, C objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
- @3 r; W' C7 q4 U2 n+ G return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
6 ]0 F4 p7 e) O3 Z- h+ \8 S" d. Udef best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体2 Z: E" \' X2 z
px = len(pop)+ Z/ X. [% E+ p4 D: w
bestindividual = []' @5 |6 w+ R/ X2 G! x9 P# j
bestfit = fitvalue[0]0 ~6 F) D' f6 E+ @, w" X: b
for i in range(1,px):
3 u1 A n1 x; f8 S if(fitvalue > bestfit):2 `6 b0 k0 ]" Q. `3 b2 p& ~0 @2 n
bestfit = fitvalue8 d) F5 N0 q* i0 k0 H
bestindividual = pop
, H2 {$ G+ e2 | return [bestindividual, bestfit]/ Y' \0 c2 X9 K9 K2 W
import random; ?+ d$ Y Z( a; q+ ]4 J, M
' j! l Y! U. ~: T+ Rdef sum(fitvalue):
0 ?3 h, b5 w1 F7 _5 j; n6 b total = 0
1 R% g* f( D# d1 H# W for i in range(len(fitvalue)):
6 ^' g- B; r& R% f, G, G* @ total += fitvalue
" A. `- r2 L) x( k+ O6 c1 { return total
. v7 E0 _9 `6 g9 [2 f% t7 V8 |( k& i, q! L5 a' F# D7 [7 M
def cumsum(fitvalue):
$ B, [+ S. C( S) z! T } for i in range(len(fitvalue)):% Q8 W, m8 P) p6 m7 R2 a
t = 0;7 v) O' P. Y" f* |/ D0 k
j = 0;
: w4 p2 D& k, J/ Y4 V while(j <= i):
, i/ d3 D0 b ~+ q, U8 o* y% T t += fitvalue[j]
. G! ~! G( j. }& Y* j j = j + 1
% g* y0 I: H4 L: g4 t( p6 a, ~3 @ fitvalue = t;
/ K7 E l) L# U
( I7 K/ D8 ^' b \def selection(pop, fitvalue): #自然选择(轮盘赌算法)
N& u# f4 l9 L8 p) o6 { newfitvalue = []
6 n0 J" R a. X$ e1 |4 N. y* E. Y totalfit = sum(fitvalue)& f t) k, s R
for i in range(len(fitvalue)):# q/ Y0 a' `& ^8 h
newfitvalue.append(fitvalue / totalfit)- f' f3 {: H& s2 p- Q' w* C8 a
cumsum(newfitvalue)
+ A9 F9 F) o/ j" {& c4 Y ms = [];
6 S7 J/ ^. V9 q8 z1 H" h) o& N4 N poplen = len(pop)$ A4 c. ~8 S' S0 g* ^# i7 R
for i in range(poplen):
+ T7 B1 J7 A8 R3 G6 P" B7 d" L1 j ms.append(random.random()) #random float list ms
8 R: U( J9 v8 n) @+ _2 V8 R ms.sort()
( q7 y H% X" x* a) O' s$ b: j fitin = 0
8 X1 }' W' i: c newin = 0
' E; a6 g/ K1 {: _" {- a newpop = pop: E2 f, q- U Y9 I
while newin < poplen:
! P# T6 l4 s9 a, B if(ms[newin] < newfitvalue[fitin]):/ R6 h) {9 O% V0 R! y" M) g
newpop[newin] = pop[fitin]: `9 {- V2 A' n4 a1 i# a" D4 J& ?
newin = newin + 1
3 g( y* N) V) I$ {8 s7 ?# O else:8 H/ U; a$ K" Y3 g: ~6 W6 ~
fitin = fitin + 1& N8 Z {& I( ^& U
pop = newpop
1 z( B# V2 s2 O- g/ @6 wimport random' d: P% R' C0 {9 k" l
; n- J/ p0 R% m3 v7 _" ^
def crossover(pop, pc): #个体间交叉,实现基因交换! ^6 x4 q) ]3 D* T8 p" ?! \0 L V
poplen = len(pop)
% i0 b1 g& z; A. w0 a0 P2 ]- L for i in range(poplen - 1):
7 w& E! K9 Y8 |: }1 [7 a) Q7 i if(random.random() < pc):5 P. P' w9 f% n" Y: N. }; F! q
cpoint = random.randint(0,len(pop[0]))% B* n4 P6 ?% B' d3 t& R/ A
temp1 = []
) @& c1 a- N% H* g7 ^. F& y temp2 = []1 Q8 r) x+ q" D- m8 ~) L% e) r6 [
temp1.extend(pop[0 : cpoint]). ?9 i2 B' m# v" X2 Y h
temp1.extend(pop[i+1][cpoint : len(pop)])
% h) w9 f7 d( V temp2.extend(pop[i+1][0 : cpoint])4 P' O8 `3 l6 }! O F1 t. v5 {4 S2 R, K( O
temp2.extend(pop[cpoint : len(pop)])) \- A* K* t: \; p0 }
pop = temp1/ L4 v9 H$ _5 g# g5 [$ `
pop[i+1] = temp2
9 u# _5 q+ T/ C5 {2 Bimport random& x7 {) H: ?0 }8 p4 m# j
' i% ]+ }5 n) S, X- A- r4 [
def mutation(pop, pm): #基因突变( o9 B$ G) {5 e j& ?1 L1 P
px = len(pop)
% ?' h* r! M1 |8 I+ V/ c py = len(pop[0])
- R+ P# l. ~5 X5 H" |
/ f! f) M9 ?' [7 e( h! D7 o for i in range(px):! v3 K4 K5 D, I ?1 p
if(random.random() < pm):
9 _5 m/ x, O, P" U* P) h mpoint = random.randint(0,py-1)8 d: @& D/ _" U+ i* V
if(pop[mpoint] == 1):) a K) n1 v9 A# W
pop[mpoint] = 09 ~5 j1 Y( i% q+ d+ ^8 H0 D8 _
else:* K! e. u# ^) o2 a
pop[mpoint] = 1) F0 k) j4 B( s; Y* R3 G
( O$ {6 J! X1 c# a. c4 ~* x$ J6 A2 D; b
————————————————
9 `8 V; O2 z) f7 z版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 A" J8 t, f" Y8 c. p$ N" w
原文链接:https://blog.csdn.net/u010902721/article/details/23531359. L, c6 H# W4 ]( m
% I8 s$ D2 A4 w
5 d6 ?& B+ d3 o |
zan
|