数学建模社区-数学中国
标题:
python实现的遗传算法实例(一)
[打印本页]
作者:
杨利霞
时间:
2020-5-9 14:48
标题:
python实现的遗传算法实例(一)
python实现的遗传算法实例(一)
& {* u( O6 Z) S/ i( x. u+ G5 O; l/ y
2 T, ]! ?+ T' y8 E! P
一、遗传算法介绍
: N# H0 |/ j5 E
% R7 B8 [- T- j6 \
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。
) Q" J5 Z8 G, r) x! r, K# ]
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 10
7 p/ l$ C: J8 E0 [" g5 v2 j, H1 A
3 ]% B+ Y% T9 ~" q" P# S, l
1、将自变量x进行编码
0 D8 m# l. D& ~
% k+ P8 o! S+ M8 T! Z% X
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
: k5 H% F2 [. q9 `# H
4 M( u9 S# L8 ^8 P# }3 o) \: f3 q
2、计算目标函数值
2 `7 s# g0 z! j5 m7 f% O
, E! x. O/ J- s/ G+ l( x6 X( f
根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
' t! M' [9 p: ?. U* Y" X
- C( Y- W U7 p
3、适应度函数
& W/ ~) j4 p! w+ c+ I
& c) b& [# k& \3 a" l1 K( _
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
7 Q; I% B) l8 L! Y- h. {1 Z
1 x* [9 k+ B$ n1 j: a6 v+ q
4、自然选择
( W3 M' G. I6 u8 }* l! u, A* h
% i& K& u( `% B* v/ M
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
, k5 c7 _7 J/ T2 ]2 |6 }1 v
4 l+ |/ Z5 |: O: R7 I* I
假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
; X7 H, @% t! j7 c, Q& I; w; I
$ C) l8 ?5 q V! ^: r
5、繁殖
8 X; e% P8 }$ v. A" H, V
7 ?# `0 S( t7 D3 U3 j
假设个体a、b的基因是
4 v# o; g4 }8 f" R5 o8 J
, ?% E; }- I& V; L A+ g" T% T
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
1 m8 R% Y; u: F- J3 S! B, \) x
4 b/ J6 E1 Q6 B i* B' h. w& y
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
1 H y4 ~. W* Y% u6 j
, R+ G6 J3 E8 Y, \
这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:
2 y& }1 m0 v1 a% C1 k
; S: F* K. D" F6 h3 v
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
7 r% ~, x# z' Q% \3 R9 N
0 ?2 R0 F6 g9 U* Y
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
+ Z- k" ^( \. H4 ^9 k
3 i) C* ] c4 m L2 V
交换后为:
$ [3 [" x5 K/ b1 A* ~
, _& m' }8 n& A6 m( w( t- l6 R
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
% B9 V' E* _& X; b9 ^
( w p& [& T# M/ S& k/ E2 b
b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
; l/ \" D, Y+ }
" A" Y' x+ d+ Q0 h# y
6、突变
9 d( Z4 T- A% J
( k$ q5 r5 p9 b, }. O! f8 N
遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
6 S. ~0 {4 z" g) o
* W5 |# f# _# c3 B1 v- W
二、代码
9 F& s) k$ j5 x; v4 K1 f
def b2d(b): #将二进制转化为十进制 x∈[0,10]
0 c; b7 x4 G( ~+ f# s
t = 0
+ H. Z( _7 j: e8 {7 W1 s0 A
for j in range(len(b)):
$ e& G1 Q# O# s$ D* ~. p7 f
t += b[j] * (math.pow(2, j))
. M c p! ^3 m9 m8 d
t = t * 10 / 1023
& B2 ^+ C) T; l3 x% y+ c% k
return t
$ ?8 i+ \( s4 f1 A4 F
9 {7 K9 i! O8 W3 X
popsize = 50 #种群的大小
9 x4 M. U; W y3 V
#用遗传算法求函数最大值:
9 d' u. H) P% S4 ?# Z
#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
/ r, Z# s* x) b3 Y: B' [# h
i# g) W+ E% O. l5 i- K- r0 x7 L
chromlength = 10 #基因片段的长度
8 U( x- i. }$ u4 |& f( {
pc = 0.6 #两个个体交叉的概率
# ?# k8 }' }9 ?! z) V/ {
pm = 0.001; #基因突变的概率
- `6 l9 o( o5 t
results = [[]]
+ e/ d3 ^; s$ L B
bestindividual = []
6 e8 [2 k6 E6 e& O: j* V
bestfit = 0
6 ? c2 d% l5 y, l3 q3 ]. L0 ]
fitvalue = []
- R3 r, |2 a6 ~# X4 L$ D
tempop = [[]]
1 C) @3 Z/ `, v5 x7 [; E3 K! Q
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
. U) z0 P' L8 j: e4 _1 b# V
for i in range(100): #繁殖100代
|8 E) F+ c4 s$ G0 A _
objvalue = calobjvalue(pop) #计算目标函数值
8 d9 ?& i+ i( [# M, s+ A, z
fitvalue = calfitvalue(objvalue); #计算个体的适应值
$ _7 ]$ w Y) G1 y; s
[bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
z' x; a, z* s5 |! \# z1 g0 a
results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来
( Z3 H0 `2 Z6 V4 Z5 x. g
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
2 d/ d2 Z8 `9 B' C
crossover(pop, pc) #交叉繁殖
. O q2 y0 s& Y2 A/ n
mutation(pop, pc) #基因突变
3 i/ m; L( f& O' w
9 v ?( M3 E) j5 q9 V) ^
7 T7 z* w8 ~" G) f9 ]/ }, p
results.sort()
: h2 x" c$ U; I" X' |" h8 N4 y
print(results[-1]) #打印函数最大值和对应的
0 F$ f; P! ^6 N1 @2 k% H' t
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。
- ^; K& [; k" Y% F( t
fitvalue = []
& |: y% E* e8 C: l; Z
temp = 0.0
0 m/ \2 y( N( D* o3 {
Cmin = 0;
2 r$ { {. H+ z9 c/ m
for i in range(len(objvalue)):
1 v5 w: Q6 _, \
if(objvalue
+ Cmin > 0):
0 Y+ G" M' I) @+ E+ X
temp = Cmin + objvalue
2 R* A2 K) n+ @2 b/ k0 I
else:
$ }& A" X+ a7 Y) Y* r. h4 T
temp = 0.0
& x- Z; I8 B/ H: Q
fitvalue.append(temp)
% u4 N4 O! e/ k& O5 d
return fitvalue
" ^# q6 f( J' z* y
import math
8 s+ x5 q+ X8 W7 t. n' `/ @
" Q( G; c6 [) a/ e) |
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
/ I, M) l2 d7 R8 s7 C% m3 _
temp = [];
; Z- @! Z+ J: M5 X8 e8 T0 P
for i in range(len(pop)):
' `+ C- g( a7 o" T
t = 0;
9 r: v& s; X Y( E! A$ u
for j in range(10):
6 Y" h$ C' X6 u1 k" \
t += pop
[j] * (math.pow(2, j))
/ C% P4 ~7 o/ c
temp.append(t)
% `& o& x3 L( b
return temp
. f4 H# B, g1 u9 D- T- K5 _
8 K/ a+ M% U9 q4 q( m3 F
def calobjvalue(pop): #计算目标函数值
% l# j g# L1 |1 N6 Q& J+ N; d
temp1 = [];
* e, F p) X3 G9 T
objvalue = [];
* v: a: j K G Z3 F+ a3 J
temp1 = decodechrom(pop)
1 J& s8 m: Z$ \% T
for i in range(len(temp1)):
! Q% L) I+ D% T4 u" l* B: r
x = temp1
* 10 / 1023 #(0,1023)转化为 (0,10)
, V) G! f B+ N2 W# ]* d5 Z* }
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x))
% J0 |" h$ _. o X& v
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应
5 i2 l3 X. L2 M# P) V- N
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
2 o; ?8 ^4 s, D
px = len(pop)
* N! Q: o0 ]- y$ x) N6 k. W' U
bestindividual = []
2 l- f/ _/ b5 P5 z5 e
bestfit = fitvalue[0]
9 p9 K! d0 A, g* C7 |' f* P
for i in range(1,px):
9 c9 v6 D/ u. @- y/ }" Y9 O
if(fitvalue
> bestfit):
! d% e9 I8 t# g+ @ x, v3 m
bestfit = fitvalue
7 L N; n. x5 X6 k
bestindividual = pop
& }% P& @& w; Z( L/ V. V
return [bestindividual, bestfit]
8 X# K/ C- i, I# j' k: y. i* j
import random
) }; G' b, I7 a$ i
6 d' b7 k$ e2 n# j2 r! R
def sum(fitvalue):
0 y/ }$ \5 D+ M/ z
total = 0
. Z- y t4 u: b+ ~: m$ O
for i in range(len(fitvalue)):
* A0 j; _! {/ g- j3 ~/ u( O
total += fitvalue
! _! Q* k* r4 p% L
return total
) ^: ^0 ^1 x- {. h$ T- S. j! B
4 N( T* X' @. ^) D% |" L
def cumsum(fitvalue):
0 v+ ~" }7 _$ ~% `2 e% f; G; V
for i in range(len(fitvalue)):
: ]7 Q: a* D( {$ g
t = 0;
+ [6 D. O, l& q) k* z+ \
j = 0;
) \: D! j+ Y$ R0 Z% U0 A
while(j <= i):
1 i) e; b6 w# O/ r: w
t += fitvalue[j]
8 D& p) p# `8 r1 H4 ?" D; V
j = j + 1
E) ~9 l4 \5 |8 r4 w
fitvalue
= t;
9 m/ ?; J% p: v( i) l
' e1 Y$ l1 E! s a
def selection(pop, fitvalue): #自然选择(轮盘赌算法)
! M" U, }2 X& R" g6 _7 m" ~
newfitvalue = []
+ r' Q. |$ R; C- i- f5 s7 a& G& F
totalfit = sum(fitvalue)
6 ?$ g0 J! k3 ~3 l( _
for i in range(len(fitvalue)):
5 i" n4 O8 A O: f7 l% e
newfitvalue.append(fitvalue
/ totalfit)
5 {7 J* c" r3 [, |
cumsum(newfitvalue)
* |$ V& U' u* L- V6 q
ms = [];
* \4 M; |4 x, V. P* U, B$ c# ~
poplen = len(pop)
+ |7 G' t7 z6 G/ T' o8 [5 b* k) R
for i in range(poplen):
, N- y7 }) Q2 X. o( G
ms.append(random.random()) #random float list ms
: v* z. ]/ ~7 T- d8 t Y/ Q
ms.sort()
W$ Z% t" U" c' t' h
fitin = 0
" S8 N6 f; G6 ~! N0 p7 j# J2 _
newin = 0
& U4 Q% y5 Y% F, A; N
newpop = pop
S0 H0 ~( c" W4 H5 @0 V) I: {
while newin < poplen:
4 q% p3 Y# b% w4 L R% u
if(ms[newin] < newfitvalue[fitin]):
: a. k8 y* `4 t- T2 R
newpop[newin] = pop[fitin]
0 p5 {3 v4 @/ W) R; G5 i) J
newin = newin + 1
3 @, u, W. w$ L. c% W
else:
" v3 s2 b* r8 z# C
fitin = fitin + 1
* f, q# E. e: L; a
pop = newpop
9 X' h( r& ]$ A Q. N6 u: \) {
import random
1 R& c3 s# e$ I8 [
8 w$ h' t3 _2 x
def crossover(pop, pc): #个体间交叉,实现基因交换
! ~+ _- J& D9 B% e0 w! G6 V- M
poplen = len(pop)
) s1 L/ r8 E5 I3 p @9 {1 W
for i in range(poplen - 1):
7 f/ G* E3 m9 Y! X/ A6 l9 T4 ]* f
if(random.random() < pc):
: L4 I. _, ^) T8 z& T
cpoint = random.randint(0,len(pop[0]))
9 F- g- V5 D3 {' P, I$ {
temp1 = []
1 V* Z3 R+ m' R/ {% b' P# j4 g* o4 a; ]
temp2 = []
2 J5 w) l6 z m+ [4 y: C$ K9 W7 x
temp1.extend(pop
[0 : cpoint])
0 G; k+ \9 w! d3 r
temp1.extend(pop[i+1][cpoint : len(pop
)])
5 t8 q0 ?( {% D+ s5 d. ^
temp2.extend(pop[i+1][0 : cpoint])
' q% o% q5 O* Q0 X
temp2.extend(pop
[cpoint : len(pop
)])
1 o( s5 t1 ~$ e0 r; Y& x
pop
= temp1
" |( o2 B2 K8 Q0 t Z7 ~
pop[i+1] = temp2
- i8 D1 m6 s! f! e
import random
, U/ _( k3 H- h# I w( M- U
" N: ~1 k8 ]: O* C! t1 h% a
def mutation(pop, pm): #基因突变
% Z6 r( ]! V; F0 u4 O( W/ t
px = len(pop)
; X. e" O( i r& ^( r
py = len(pop[0])
$ w% h! R q0 O. q$ M; K" j: n3 s
; k4 M: p: q/ F% ^1 d% u
for i in range(px):
: q* T2 [$ L( M- l
if(random.random() < pm):
0 w2 N( j- i) ]( O. R+ s1 P
mpoint = random.randint(0,py-1)
. A: `7 f: D7 d' ~" ~/ C i
if(pop
[mpoint] == 1):
$ r8 N1 ~+ e0 z4 c; Y% T) s
pop
[mpoint] = 0
* \: A8 D0 B! ~. ~. z% C4 V+ f1 u
else:
: W# C2 S: {8 P5 f' y- g
pop
[mpoint] = 1
* y7 u; ^" z8 `' |' r; J* A+ `0 K" {
: B" O( C4 W: w# N7 x) h
7 L5 R7 ~9 J& t* O* ]0 U6 M; u# Y
————————————————
- X5 d3 G( V4 W: L& y
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 U7 t' f6 Y$ W& y. ?2 i: C; ]! z, A
原文链接:https://blog.csdn.net/u010902721/article/details/23531359
* m2 D: d8 U0 D0 z6 P1 d
; a1 l+ i9 c# c9 m }: C4 i, ]4 C/ m
; |$ {' V& f$ g; L4 y
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5