- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566434 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175153
- 相册
- 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! W/ E' B/ v1 \& _7 h, u0 U, |$ m6 e' `
一、遗传算法介绍
7 J o) ~$ I* ^. D$ i+ S: T" g, u" V' q' v; I" Y2 z6 v
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。7 q4 f3 z }/ V' M
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10
8 \- M6 b1 c2 k1 o, j
: v1 w9 Z' S3 |) F1、将自变量x进行编码) r4 D3 o2 O& @
1 B h7 u# \3 N1 d h' t/ l 取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
{& g2 @" k8 y; E3 b, Z9 s' C
2 r: `* Y% I% F. g+ W+ t2、计算目标函数值( S6 |8 _/ r( G4 m n+ E+ i5 d4 K
0 v3 J$ R- M: Q+ Z8 I/ u+ M 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
/ k9 k8 @- l+ ~; R$ k {( J3 Z' m! @9 }$ W
3、适应度函数
5 G) F( F, ]+ p5 F; I n+ p9 g/ x, ^: v8 T% C. D7 N- C- W
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。8 f2 A9 `$ X; X& v: d3 `) {
. M) ?3 F6 C& Q4 ?0 d7 b4、自然选择. r2 M. L! f. H/ G' v
0 G8 X0 z, _# r% i- b) H0 C
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:, N0 T3 W/ V2 n
( D( }" q' H% P" Y( K; C9 U* v假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。' l a* }5 ^5 y5 j2 d; V
" v5 |) L$ j: S; F1 q5、繁殖
" C/ w' K0 ]# s
" U4 F3 ^3 L; h& K假设个体a、b的基因是8 ~7 |0 h- U7 k# y8 V# ]- `4 g/ f3 W- x
1 Z" v8 V- P4 l I% y' I
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]- ]' H& _! E6 t8 X& d
% C6 R, S7 Z3 S2 C( v1 Z
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
X3 [& ~; `4 P* \; i8 ~, D( y- H, w9 M) R r+ ^5 l
这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:! z4 z4 o9 d% R, |9 f7 e
3 k$ m) u2 R& _7 f/ Wa = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
1 o1 l! N4 \) f; p- s8 _) R- g" b( u) g9 `6 q, }/ C6 _2 C2 H' x$ n4 S1 R
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]7 a# g0 H1 E$ ^) ^
) q/ u' }( b: x3 H4 a交换后为:9 ] ^# x& O- m1 j- h- O: p
; z' }3 ^$ h0 l: O6 N$ ?a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
: [- U% L0 ^) M' t% u. x0 U, d0 o3 ]2 v" k) B8 [% o6 k- m" W
b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]9 B x8 X3 k9 z
. N/ g( E. }( j2 q2 U6、突变. k$ C/ r) Y. _1 h
6 `- p( T3 J, b) [) n6 T1 R; s6 @遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间& z, ]2 i! }. f) P- F
; B9 @2 p& r& C$ G/ S, h. z
二、代码
7 c* f- @6 i5 I* g, w E) ddef b2d(b): #将二进制转化为十进制 x∈[0,10]
/ N+ ^3 R2 N& @7 ~9 C5 M; L6 V t = 0/ [! p) X! W/ ~" B" {6 a
for j in range(len(b)):
2 E% u+ @& P2 { B9 }- ~$ Q' R t += b[j] * (math.pow(2, j))- y) M5 q$ Q2 [! [$ p3 D. n
t = t * 10 / 1023$ n Y* |% _% `1 h6 }
return t# I) _$ g- x4 w# P1 O! y7 _7 h0 _
Y9 X5 {) q2 y5 I" Z
popsize = 50 #种群的大小/ Q) `' q* g+ l* T" O& g" N2 \
#用遗传算法求函数最大值:
3 W/ d2 Y. @! i* @1 f9 c#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]$ s- _: s3 ?0 \9 N7 w$ R
# O* P( I$ d) ichromlength = 10 #基因片段的长度# T9 P) s, n$ K. X, w
pc = 0.6 #两个个体交叉的概率
4 D1 S5 O6 D/ R' ~5 C3 ipm = 0.001; #基因突变的概率5 l/ _3 Z$ }, k
results = [[]]
, D2 Q" J* A. j8 d' ]+ \bestindividual = []) e, ~* \. b9 i- O; s
bestfit = 0
' [+ ~* c/ E' [$ G: p9 p" {4 ufitvalue = []
& Q0 q$ [ X% R9 o% V, u! V9 ptempop = [[]]6 o5 Z! e5 r2 c* s" u' _7 ~
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]3 p. x4 o# N% u Y3 l
for i in range(100): #繁殖100代
: k: b/ ?' u7 W- [" Z objvalue = calobjvalue(pop) #计算目标函数值& \ d! Y* S" [ @: q/ u
fitvalue = calfitvalue(objvalue); #计算个体的适应值
% I# E! r( \/ w2 e0 E) T8 @2 H [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值: d- h; j/ y ?. n6 v
results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
( g; [9 `3 }( U! u5 H7 V selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
7 y z, K1 X! Q crossover(pop, pc) #交叉繁殖
, H7 t. {, O! k/ y, X4 X# B7 A mutation(pop, pc) #基因突变
/ k! ~' A% d) N0 f) S7 {
* V$ @2 r) Z. @4 K' u; w- u0 I+ _* ~5 A. d3 {2 O; c
results.sort()
9 B$ p1 D" w" U& F! k) ?2 bprint(results[-1]) #打印函数最大值和对应的0 t9 x3 k6 L I0 ~! [
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
- S1 q, P ?+ p+ r( R3 F6 Z fitvalue = []5 T% c" T- }8 r# r1 H2 I) }8 E
temp = 0.0
5 x. j. W8 N8 A/ g( T+ H Cmin = 0;
$ _. F& D) c9 D: {, P for i in range(len(objvalue)):
: ~- ]1 V* s b0 h+ S [ if(objvalue + Cmin > 0):- N- N6 S6 h. o2 K$ H& a3 i2 M& D
temp = Cmin + objvalue
6 \; N2 m7 k( i; X- @4 `+ o& W else:! i8 N$ O+ o3 |4 Y# d$ O6 u: U
temp = 0.0
B' n7 {, |% D' _7 |1 a( ?+ k fitvalue.append(temp)& u1 ^9 b, a1 Q* S+ p, V/ E
return fitvalue
$ S$ O- o. U" }* E/ w1 Aimport math; x6 i, ^/ \) _3 j, f' m. s4 B d
; H' u# g8 ^5 b; Q. Q. o' t
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
' ]' B& A ^7 h8 U" s: R temp = [];7 z! V' i; M& n: W: [
for i in range(len(pop)):+ N( K1 J! N9 {) P7 d& w# p
t = 0;
: [1 U5 q& M: X1 G- ^ for j in range(10):
3 J5 H* s L: t9 D! ?* G' p* C t += pop[j] * (math.pow(2, j)), M2 P3 j4 }" ~) v
temp.append(t)- c7 g! k. k$ R# W' u2 `
return temp9 Q& R3 q- q$ t7 I9 d9 h$ R; N5 k
1 u0 P/ y) _1 }# i, m, ?- m! j, Xdef calobjvalue(pop): #计算目标函数值5 [: ~- z" |, u5 g- F/ e
temp1 = [];
/ E, `; I0 R- M, ~ objvalue = [];% {6 t) f. n; s. a' s
temp1 = decodechrom(pop) F5 d. r8 }: o1 v9 A) c# R
for i in range(len(temp1)):4 n+ x: g( G3 | I, E2 H4 W _- V6 E
x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10); R0 t. _5 ~% d0 K$ r: X4 @
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))& p1 b0 ~* i4 d6 W6 h' a% b/ |
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 6 k9 T" y6 I; p o/ I/ a! P
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体( F% \* l. A0 z) G3 B
px = len(pop)
) K2 z$ H$ V' ?; x! t bestindividual = []
3 i5 O$ [4 d8 v bestfit = fitvalue[0]: r- V& _& S+ k- ~3 V
for i in range(1,px):- I u! z. Z& D# ]2 @
if(fitvalue > bestfit):4 L& a2 Q I5 Q# b; r
bestfit = fitvalue
5 I4 O, K$ f' Z* @* r bestindividual = pop# B9 v! A- J5 k& @# f
return [bestindividual, bestfit]
! R1 R' j) V8 L4 c4 ]import random# u9 r+ M3 X6 }+ Q9 `2 l
& s1 y5 Q. Y2 R# ~4 h- ~
def sum(fitvalue):
) m- S, g( Z: Q9 C. K total = 0
w" g& g {8 u# e; U for i in range(len(fitvalue)):* D* E6 U! m0 E+ X: h: a
total += fitvalue3 S8 q1 |' a }) Y9 t/ }. x9 g
return total
7 b! o& {5 p* T8 o; H5 E R
6 z8 T# L2 b- N' ` n2 kdef cumsum(fitvalue):# S4 B8 B6 I# {# h
for i in range(len(fitvalue)):
) r! E& G/ ?( p0 g7 p) A( K# P t = 0;6 C! {" v" u; E0 u0 r
j = 0;2 V+ H1 l) p% C2 c
while(j <= i):
% z3 g" [# E) A2 m7 o3 G6 T% a t += fitvalue[j]+ A5 [/ m% K0 ?" Y$ Z7 a5 Y6 h( ]
j = j + 1! g2 ^5 X4 L& {) l9 U, k- M
fitvalue = t;( w- L8 @6 h9 O, n6 E) |0 q
9 u. l' c- u8 r3 M: q' K
def selection(pop, fitvalue): #自然选择(轮盘赌算法)
/ p8 s& r% B8 |/ \5 O$ E; g newfitvalue = []* ?& c4 Q' p9 u" o
totalfit = sum(fitvalue)' W5 l6 V* T u/ Q, B
for i in range(len(fitvalue)):9 K& n" I- @% P& ]' F$ K9 y# y, ~! K& I
newfitvalue.append(fitvalue / totalfit)' k' v+ w5 v- W* G; B
cumsum(newfitvalue)
) i7 u& L4 n3 u2 z n* Q ms = []; ], Y* {* }1 C
poplen = len(pop)
+ Z8 J+ o& w" X& m4 T! e" g for i in range(poplen):
. ]7 k; V! i7 t: ]$ @( P. s9 t: Y ms.append(random.random()) #random float list ms# v& ^$ F1 Z" a' _3 A
ms.sort()
1 o2 P7 G$ J2 @( T fitin = 0+ M& f" K$ G: i W! f
newin = 0& d6 [5 b/ b5 b
newpop = pop+ G, I+ F* e; }2 `, ~/ L
while newin < poplen:2 f1 [* L7 `: J
if(ms[newin] < newfitvalue[fitin]):' Z! K2 l3 p {0 u
newpop[newin] = pop[fitin]5 a6 K5 u, l: Q; |# w
newin = newin + 1
# Q) T! A( u* ]2 F: a8 _ else:
& M1 |/ {' [0 C fitin = fitin + 1! y! W/ ?8 ?1 w: W7 c) M
pop = newpop
2 ]5 H* u5 V _( `7 [0 [0 ~import random
: e3 ^) m+ k5 T2 L9 Y8 k2 r
8 W: v% \& p! e" Y9 I2 B* R4 Rdef crossover(pop, pc): #个体间交叉,实现基因交换4 C, R8 q+ s( s" S
poplen = len(pop)
% V5 L3 n, |( Q* W2 n+ D0 i5 F for i in range(poplen - 1):9 @5 I' q7 c8 \' L4 {6 o
if(random.random() < pc):( y! L( d" ~& T7 b
cpoint = random.randint(0,len(pop[0]))
* h: G5 e! {; w' H temp1 = []
9 ^1 J( ^, o- r! ~" s' ~5 U4 z temp2 = [] @' c& {, M6 H1 \
temp1.extend(pop[0 : cpoint])
3 M* ^: q& @3 V3 K, x* @1 R$ O temp1.extend(pop[i+1][cpoint : len(pop)])# }; C; B0 H. M3 s B+ o4 l) o
temp2.extend(pop[i+1][0 : cpoint])
* K: J5 n- F" T( ~" F temp2.extend(pop[cpoint : len(pop)])9 _! I. J+ L1 v W
pop = temp1
! P" F3 ~: ^* r9 T pop[i+1] = temp26 v$ E9 J7 S2 U% d
import random
9 y# Y6 a# M; x' K/ G! e9 K% {( ]; M
def mutation(pop, pm): #基因突变
) Q" U# b0 P: x7 i) | px = len(pop)4 J' a8 a" u: R5 K
py = len(pop[0])
& q7 u2 @0 e% [ T+ p, F6 @# ^2 l, D" \3 h" r
for i in range(px):/ @% E, E2 r* t7 Q; A5 Z
if(random.random() < pm):, G9 v2 a' h- l/ d+ X) W3 {) W
mpoint = random.randint(0,py-1)
, Y: O& s* x: f if(pop[mpoint] == 1):
. D- m( L9 y/ h1 @& [* F& W pop[mpoint] = 0
# e- Z( U/ o/ v8 i2 t else:
5 z H( i7 c1 U1 t- [ pop[mpoint] = 1
% N9 V) P3 T( o
( r# d) W" | a& t8 A: r
$ u8 l7 K/ _7 x; m# J————————————————7 J8 ]6 W6 A$ q6 q- U
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。4 d5 m+ c, I6 H; ^ J' ]
原文链接:https://blog.csdn.net/u010902721/article/details/23531359
+ \2 B9 p" U) F5 u( W }
+ x# x# R" x! d9 L5 [3 S5 }# e6 k) C: o1 f
|
zan
|