- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565423 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174850
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一). a4 l6 A% k! o3 B$ H
! @# a+ G. Y0 N6 o% V
一、遗传算法介绍
4 r4 V, t2 Y7 A
/ y0 X \! u6 ]* U 遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。/ D! W1 s4 d9 v. O
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10$ K+ T2 o8 Q4 `# J
" O4 _ E4 K% ^' ~9 F1、将自变量x进行编码
/ ^1 P' P! Q4 ^5 Q) X/ x* U$ j- x# s% y( X6 w1 u( }
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]* {* a: K! g) O: C
, C: c4 Z6 t- o: g3 b' F7 e2、计算目标函数值 j! Y4 p2 c5 b/ A
- F7 b2 ?# k( R: H 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
8 {. W* x% q7 D
# ]9 f) [/ @9 n) |# u- u3、适应度函数
5 V& U0 z0 V1 m, b+ ?6 T/ o4 [1 \% u# H# V8 {6 d! i
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。6 {2 A+ |- S9 Z. }2 l+ w
* L! {" \+ M* k4 V1 q4、自然选择
7 j: E4 J/ i/ _. C8 X1 Q$ m' F& R, I. M0 n$ B& u. Y
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:( M/ _- Z% s1 `' _
0 Q2 P* n0 @' V) z假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。; C7 d' V9 c4 J" A; w* p" ]$ B
3 _8 k! K7 @8 g" V) r7 L
5、繁殖: X r9 c# \6 b7 I2 ?$ a0 ?! f/ {
" x$ i& r u2 a假设个体a、b的基因是& _. b! K& d- T# {8 Z- a7 Q- l! A3 U
7 u! U, d; B( m# l
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
5 N6 s' O" h z* p) S+ \$ T: v+ w; k; P0 ]% e# Q
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]7 E: N; r( o1 J# U$ @, E
4 K# V& F' Q9 b; Z" ^1 E2 z# y5 f
这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:$ p1 o: s9 e* N1 E! d( ]( g
y" a0 ~3 r. n
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]9 B9 t5 C: J" n$ z& I- w/ N: I
9 L7 s, f. g; I; ~
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
3 i% g7 D4 P9 \* L0 a- E2 `5 U1 ]5 T1 _- y
交换后为:! o& d9 i6 k9 K0 D' N2 k
3 z3 M* [1 w- R' i3 o. M# d" ha = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
* W1 v- R1 I# s* O
, P! t& i6 `9 [( N. \# |. fb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
4 @5 K2 z* ]: r- S1 K6 l q! F f- X# z
6、突变
% V7 e; F, C( u! P, U/ l/ M" @, g9 A
$ A( _8 t8 |& r+ m# K3 p% Y遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
+ S5 Q* h2 u/ j& U) T% T! e4 j1 d
7 _* R$ E& N* }% P6 U; T) t0 v二、代码: O+ ~' M* ]$ C" C
def b2d(b): #将二进制转化为十进制 x∈[0,10]
$ `+ F# M; ~6 A t = 0% d. C- f+ y' _ f4 x0 S8 B" L
for j in range(len(b)):5 ~( E4 ?6 D( V7 V) T
t += b[j] * (math.pow(2, j)): ?4 P' d: [& e4 ]" u
t = t * 10 / 1023
% n0 u2 K2 E; `% O+ H return t
. p* P) x% c$ e6 h
& K2 x$ [/ y. ~, P0 _popsize = 50 #种群的大小* G: _8 Q, w0 N" ?; z5 @9 r
#用遗传算法求函数最大值:
* z- C F7 X0 O; o9 d#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]; _8 r' W9 |% D7 r' g
6 I" B7 H5 V& D7 V
chromlength = 10 #基因片段的长度
# I0 v" R. {! d5 r% Y# hpc = 0.6 #两个个体交叉的概率+ [9 g# Q% u# z, G
pm = 0.001; #基因突变的概率 n& b* c2 ?! C' n2 z; L, w/ F% |! R
results = [[]]' F5 P! |3 g0 m% N
bestindividual = []- R& I4 a" c9 d( D+ K& C, k
bestfit = 0) @6 ^4 j& M- s3 g) |5 q* L
fitvalue = []
3 a% M" M( ~& Z9 k, G, Rtempop = [[]]
! k6 S6 f7 N5 X* x/ Cpop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
' o7 l5 S& ^8 h& x7 S% lfor i in range(100): #繁殖100代2 Q: h1 P; m- T8 g! ^! O, W
objvalue = calobjvalue(pop) #计算目标函数值6 L/ H. b/ Y$ h' A
fitvalue = calfitvalue(objvalue); #计算个体的适应值' j5 T# S) L% D7 f6 C2 q
[bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
* P' Y. Z8 u$ D4 n6 j results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来7 L1 k) g2 ~/ K H7 O/ I
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体9 [9 Q5 i( N# Y8 g2 T& T9 g8 V
crossover(pop, pc) #交叉繁殖
/ D9 v, x/ W/ I% w mutation(pop, pc) #基因突变+ z+ u9 ]1 b. @' s; c
& i) g% N0 E( F) }
8 {* N, a9 \' \3 ], E% N/ uresults.sort() , i8 y8 F% g' }7 E
print(results[-1]) #打印函数最大值和对应的% l1 }$ _. S/ n" L4 [& Q0 c- f: t0 [
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
+ F7 _& N4 m, S, y fitvalue = []
" p/ b; d, D/ O+ ]. d temp = 0.0
: g P2 l# ~& K2 V Cmin = 0;1 ~! ?4 l3 Q9 z& {1 f" ^
for i in range(len(objvalue)):4 x+ @: a# \. G8 a6 w/ s, r! L3 e
if(objvalue + Cmin > 0):3 Z3 T. O5 Q: s* H
temp = Cmin + objvalue
6 c! T+ f9 b- K4 A t; v else:9 |9 \4 E1 N8 \/ c0 V
temp = 0.0# m, f* T1 d! P/ u$ t( }9 N
fitvalue.append(temp): B% o- c5 O. o3 Q. A- \
return fitvalue
* p- ?% v' a$ n; P+ i7 ximport math
" ]$ w, Q2 M6 ~8 N3 @5 ^- e A
8 {- g0 r% S! I7 \def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)0 S% G d0 `' J" \3 c
temp = [];; ]" E+ \8 w+ q# u) `
for i in range(len(pop)):; n0 E! F, }9 k$ {
t = 0;
) M! ]) |, f E5 S( t for j in range(10):( K6 \4 K% ^# o+ B9 `4 r
t += pop[j] * (math.pow(2, j))& b$ s) e, Y& X. s5 d! w
temp.append(t). X; R; j$ O; {5 W- \
return temp
/ K5 V: k( ]) O, p# i, l5 j+ }! G$ |# }
def calobjvalue(pop): #计算目标函数值) G' O( F8 o8 k' q: b
temp1 = [];
2 m. q0 u6 s9 O) i% b objvalue = [];
1 b$ p( i- m+ ~ p$ h temp1 = decodechrom(pop)
1 m/ H7 r: A% \( H+ ~; J) |+ l for i in range(len(temp1)):. j: |+ ~3 A6 M7 u$ p2 _7 D3 b
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)! p; J! X: F; @7 B$ t- k
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))# g- V( }" o8 w% B% G. A/ z
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 / P- W; F; @0 q9 _, J$ ^. l
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
, Z2 \) w- E2 s px = len(pop)
4 ~+ J2 B+ v# E bestindividual = []9 @: {4 D! d' @. e! w
bestfit = fitvalue[0]
1 R* c4 M4 S! \+ B/ X for i in range(1,px):. I/ V. ?9 K4 x" L1 z& [6 W$ ^6 n
if(fitvalue > bestfit):7 a6 M% a- N0 m7 p
bestfit = fitvalue; q" o( m0 l% O( s
bestindividual = pop0 P+ J, {7 V4 k
return [bestindividual, bestfit]8 X# B' t& {' A5 t: s! R
import random
7 `+ I: O: ^/ {! v/ Z: y/ ?3 m0 g7 C. | c* Z
def sum(fitvalue):' m( m- t- ^$ _; Q
total = 0) d" N' `5 k9 r( w- ~; m
for i in range(len(fitvalue)):( p! P4 {" a) S2 n6 f
total += fitvalue7 Y' d' I1 G' _) r! Z& X
return total
" i+ j. z# W' i6 X, H0 C
/ O/ \5 G4 y$ u1 D6 D% Y3 Hdef cumsum(fitvalue):
2 H3 n% s% n0 W$ d* e. i for i in range(len(fitvalue)):
# a5 K! j; @" X2 V# C' m" T t = 0;% A# x3 w! v: }/ R4 ^% B0 |
j = 0;
& a- X! W* o) g! o w b while(j <= i):3 G4 t/ f* e s" _$ x% H5 c C
t += fitvalue[j]
& F P" Y- ^3 Z/ R+ v7 g3 j9 V j = j + 1
* o$ [+ E. k! c% B9 y6 O( w fitvalue = t;0 E( v) T8 J9 G! V, A
0 S: F3 S2 ]" \; P; Adef selection(pop, fitvalue): #自然选择(轮盘赌算法)/ Q' V2 ~0 A0 w; f1 P
newfitvalue = []* @7 b- m: w. a3 L$ V& d
totalfit = sum(fitvalue)
) p5 d. Z: O% U1 g& W0 W for i in range(len(fitvalue)):
$ }) C! A. y" }2 V3 @6 T4 f, s newfitvalue.append(fitvalue / totalfit)
) N5 O% m& N/ l$ T, Q cumsum(newfitvalue)
$ M1 `5 M5 u- f" q ms = [];& H5 N( |" D! m* |9 p
poplen = len(pop). }1 I& K0 i/ J1 ^* @4 I
for i in range(poplen):
+ c* S+ D1 e7 ]; u* x ms.append(random.random()) #random float list ms4 e8 q0 ?1 Y9 \& }8 p
ms.sort()+ y/ m+ m5 R9 s' h9 k$ Q5 N
fitin = 0
& M8 e. k9 Y* ?1 O newin = 0
1 A% X% N$ l; S) ~ newpop = pop4 X& x4 {- s2 [5 o+ p5 I8 I9 @
while newin < poplen:
1 N2 Y" J! N P6 U if(ms[newin] < newfitvalue[fitin]):' W$ ]$ d/ h) Y9 x6 f" ]
newpop[newin] = pop[fitin]$ f( e5 N+ f! g
newin = newin + 1; n8 ~0 Z2 \& t. Y3 e" W1 D0 U
else:
7 u8 S. @% F8 E- e- C3 ~ fitin = fitin + 1
+ [8 S( K8 ?8 J: E pop = newpop
4 x. i3 h* `% t2 `# p1 B5 timport random9 `' \3 w, A* D6 u+ i8 @% t
, H1 e" f, Q* e- \def crossover(pop, pc): #个体间交叉,实现基因交换) x; w, ?; _4 N j3 Q, `" X- | i! ]
poplen = len(pop)5 w( [3 b4 k# j. \" g4 s
for i in range(poplen - 1):
q- u6 @( x5 x* v4 M0 y if(random.random() < pc):6 G9 g. h5 Y! f8 Z3 y
cpoint = random.randint(0,len(pop[0]))
, t1 B0 O2 X9 D. D1 s. F# w, v* R9 a temp1 = []
6 m U; s( }) S$ X: y: f temp2 = []( b+ ]% b [3 X+ U. a9 G. O
temp1.extend(pop[0 : cpoint])
7 J, x, G9 c2 K4 n/ u$ \; N temp1.extend(pop[i+1][cpoint : len(pop)])
) H. X5 n9 q4 {$ v temp2.extend(pop[i+1][0 : cpoint])2 M9 b) j" m5 B
temp2.extend(pop[cpoint : len(pop)]) _, @ s* A T) T, ~$ s5 u0 O4 q1 o
pop = temp1) Q c6 K' e6 R. F' M4 n) F
pop[i+1] = temp2
5 {$ r2 ?9 Z$ Gimport random3 p6 X3 X) K* r( L+ ?! A2 h
9 r! W; @) a0 k0 C, q' x7 Fdef mutation(pop, pm): #基因突变. h0 L9 n( U( P
px = len(pop)
. U- O: a: J) Z$ h. K py = len(pop[0])
( J( V* P* e7 C3 P3 @6 [! o
8 c- }6 \1 Y k) C for i in range(px):% ]* W* j) e7 P. {( t! _
if(random.random() < pm):
7 z1 w: s% }$ ^( O% J" i/ i mpoint = random.randint(0,py-1)
2 G: b- P& q# C: L% \ if(pop[mpoint] == 1):
# M4 R7 i# k2 m7 e5 Q# c pop[mpoint] = 0
+ z# ^7 T5 f. K2 V9 K else:
0 t! l) K3 ]. p% f pop[mpoint] = 18 n* [; S4 k2 a- ]9 O6 i6 k. R
3 r; u& p6 w9 D- _; b' }" H5 d2 t u. M
* j+ K* m( G) R% y
————————————————
! U. i& ` n- w0 c版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。$ s, l0 l+ M% @3 l) {% G. Z+ l
原文链接:https://blog.csdn.net/u010902721/article/details/23531359
3 W, K0 A% f% J0 ?6 U* p; w" W: x5 T
6 u, p- d" c1 [) z0 s$ {/ ~; G9 r9 k9 H% \3 [4 }( k* Y4 [& |1 w: l2 v
|
zan
|