- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563404 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174244
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
python实现的遗传算法实例(一)
7 r# n, S! Z. Y2 F9 z) _5 p0 N- Q- X# ?5 }& X- G' g: x
一、遗传算法介绍* A" Q! l" r+ ` l6 o. r
; n& A1 F/ d: [! V5 p: N! l
遗传算法是通过模拟大自然中生物进化的历程,来解决问题的。大自然中一个种群经历过若干代的自然选择后,剩下的种群必定是适应环境的。把一个问题所有的解看做一个种群,经历过若干次的自然选择以后,剩下的解中是有问题的最优解的。当然,只能说有最优解的概率很大。这里,我们用遗传算法求一个函数的最大值。( Z3 b' q, Y. {/ ^$ B$ }5 }
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 <= x <= 109 W. w0 z3 l1 I2 j
0 w, _- y4 e( e. c
1、将自变量x进行编码
& o2 Q4 L: j& t# `. O& T H; |5 x( F0 j+ c1 E: o: q
取基因片段的长度为10, 则10位二进制位可以表示的范围是0到1023。基因与自变量转变的公式是x = b2d(individual) * 10 / 1023。构造初始的种群pop。每个个体的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
. [! T: D$ ~5 s4 k1 r) x
- x7 V6 _+ n( t, k2、计算目标函数值
P) q, a& ^) T9 }
+ _8 z" V# K7 b5 v: @6 b3 n2 {; f 根据自变量与基因的转化关系式,求出每个个体的基因对应的自变量,然后将自变量代入函数f(x),求出每个个体的目标函数值。
. B9 l/ m; c0 |
' @6 j' q- ]3 y, t3、适应度函数, v) I8 d& N5 ?0 x8 k
6 X6 c; |( K' O0 k- h) [4 ]* t: h+ T9 S
适应度函数是用来评估个体适应环境的能力,是进行自然选择的依据。本题的适应度函数直接将目标函数值中的负值变成0. 因为我们求的是最大值,所以要使目标函数值是负数的个体不适应环境,使其繁殖后代的能力为0.适应度函数的作用将在自然选择中体现。
' }7 F! \, l) u
' O5 R2 d, C* i+ o8 m; \/ s4、自然选择
" ? `6 d7 }3 r/ B5 V) M# N: v/ ]5 ~" l
自然选择的思想不再赘述,操作使用轮盘赌算法。其具体步骤:
n9 ]' G* F. C9 D" W T9 d
- O, V+ K* @ o% w假设种群中共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号个体拷贝到新种群中。自然选择的结果使种群更符合条件了。
+ ?- e! c: N' J! Y6 B) C2 H
v: ~ [. a5 V( h! \) t5、繁殖
% C2 n3 s0 t3 `4 i3 S
2 N$ q K, Z; X$ q$ n* I" i) K2 [假设个体a、b的基因是
0 X, X0 t% ?( H' y( d% t' b0 U5 W2 Y* q' O* c- p
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
' ?" i& C5 S& L- K- B0 e4 y
9 }3 s) Q- J% i2 H4 C yb = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
- @9 l2 N- ^" y' ?
8 v b; _$ P; z5 q这两个个体发生基因交换的概率pc = 0.6.如果要发生基因交换,则产生一个随机数point表示基因交换的位置,假设point = 4,则:) x+ G Q7 C3 k" ~) ?
" y2 w/ X3 s! p% _0 [a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]2 G. N1 U% F& o0 c; l3 K! i
" Q: \1 f8 M6 t! P* \
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]) M% I& r$ j4 \7 O
U: h7 g# @/ B$ J3 ^交换后为:
# O/ t t. s n4 F, Q! G6 ]9 R
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
/ r! g5 }; {: R l; X' E2 R" s
& C0 n3 ?! `% b! U' nb = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
8 V+ O; S; _8 u% Y0 F$ q$ A3 }+ n6 r
6、突变7 k7 G2 ?/ H& w% a/ I4 G
$ q* D' k3 X" Z I0 Y
遍历每一个个体,基因的每一位发生突变(0变为1,1变为0)的概率为0.001.突变可以增加解空间
" T) n% h5 x: w7 V0 x2 j% d
1 {- q6 [! O* Z' A9 |5 Z0 u二、代码: c4 S9 L4 G2 r, f0 H! ~' ^2 ]0 |; T
def b2d(b): #将二进制转化为十进制 x∈[0,10]& b7 O9 ?/ q! E7 Q6 ^# |
t = 0. b6 w- i; H6 k/ z
for j in range(len(b)):
' A' \. A p/ {6 c t += b[j] * (math.pow(2, j))! s4 X" Q& x1 c% L5 `# G
t = t * 10 / 1023
9 o% B9 A; I* C" e3 p1 r5 L return t7 C; A) E4 X% o0 T! I) C; E8 N
, W% C; }+ p- y1 x7 A
popsize = 50 #种群的大小
3 e' S! f2 @" v2 a/ {: a#用遗传算法求函数最大值:" C2 m L3 X+ s+ ]- o. P
#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]
, l! b( j$ B0 _. {$ ?+ n1 u2 a1 W B( e: R* U4 y% d0 b t" I
chromlength = 10 #基因片段的长度& o' p* o- [8 B6 o e9 S. @# O+ N
pc = 0.6 #两个个体交叉的概率
' K" D+ c* y) p8 a( ipm = 0.001; #基因突变的概率0 y7 q' [' A# [1 C4 m
results = [[]]
* A; e4 \9 \; t8 sbestindividual = []
) K+ ^' O5 ^6 l% Y6 x4 V. T& }" obestfit = 0
& G/ ^7 q/ v% m p: T# Kfitvalue = []: i+ \( e) ~; U1 Z& O* @% J2 \
tempop = [[]], b8 a+ l2 g7 Q7 N. |; {9 V \
pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]
4 Y+ U* S" p5 r9 g' xfor i in range(100): #繁殖100代8 ] x) N; V- o9 u3 P j% h2 Z
objvalue = calobjvalue(pop) #计算目标函数值
6 f$ A( |2 l2 E" Z; o fitvalue = calfitvalue(objvalue); #计算个体的适应值
+ z& W% M( t# c! x [bestindividual, bestfit] = best(pop, fitvalue) #选出最好的个体和最好的函数值
8 S K' j; H/ D. e- f results.append([bestfit,b2d(bestindividual)]) #每次繁殖,将最好的结果记录下来- `$ a. V6 _4 j$ e$ b
selection(pop, fitvalue) #自然选择,淘汰掉一部分适应性低的个体
. C3 u4 j# X! A8 I) o3 u3 Z crossover(pop, pc) #交叉繁殖
+ x* c: j, A' i8 b4 Q mutation(pop, pc) #基因突变
, Y2 ~$ L5 ~% f5 q- v
5 o# w% L+ | G4 F% |5 V& Z d
% }2 E; s$ n2 ^results.sort()
* ?: I6 R% E& D N9 ^) `print(results[-1]) #打印函数最大值和对应的% x# H! |0 D$ m3 U1 a' h8 V( _
def calfitvalue(objvalue):#转化为适应值,目标函数值越大越好,负值淘汰。5 k# {( f/ L$ r
fitvalue = []: h; C; ^6 H3 S2 A' _
temp = 0.0. T5 Z# V4 z: J& x
Cmin = 0;, x: Y# n' G+ d& d q- d
for i in range(len(objvalue)):
, a. R: `: W) f6 m1 v H; \4 e- x$ [ if(objvalue + Cmin > 0):
5 f. ~1 h$ N- I* s temp = Cmin + objvalue% E' y8 V- l) g+ i3 r3 s/ s0 P. |
else:* S0 W0 K6 B/ {) y, D
temp = 0.0" S* |0 N' t, y1 S
fitvalue.append(temp)
8 I( Y+ k. n) v. S, ~ return fitvalue$ c2 L0 G7 [& u3 w8 v9 s8 s
import math
) C. E- Y0 i& v( y% x3 h; a6 Q* z7 p/ s1 u, ]3 v. c/ w3 E; y
def decodechrom(pop): #将种群的二进制基因转化为十进制(0,1023)
% j; Y$ S Y0 _0 B7 q) }9 W temp = [];7 m) D; N, p' V2 c5 ]
for i in range(len(pop)):( m2 h& U/ g1 M: g; b; N
t = 0;
$ z* Q: J5 l: w. i9 q+ Z for j in range(10):7 P+ U m+ F3 R6 n! N- D: t$ m2 l# |
t += pop[j] * (math.pow(2, j))
0 P7 }: {. q4 L7 e temp.append(t)
. p0 A7 G( g* c return temp
* K& e8 Q* X9 ^8 Q- x) l4 J( w7 D
def calobjvalue(pop): #计算目标函数值) K. |$ f8 e2 A( |
temp1 = [];
4 n; N) _; V/ e3 s$ K) e# V objvalue = [];
- c) ?; B# u6 y1 l: c; l0 x: j temp1 = decodechrom(pop)
4 e, B) l6 S: H$ r0 j- Z; _ for i in range(len(temp1)):
. e# L- t+ C4 Z6 v* @& z x = temp1 * 10 / 1023 #(0,1023)转化为 (0,10)5 w/ f( z) W: }' h" T
objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x)) z C5 e: s* [6 k! C6 _
return objvalue #目标函数值objvalue[m] 与个体基因 pop[m] 对应 1 [2 @1 i+ I6 p( S) S% t: a, Q
def best(pop, fitvalue): #找出适应函数值中最大值,和对应的个体
/ ?5 l' Q* k y* F& W. m px = len(pop)" `6 `+ ]" I8 E
bestindividual = []+ {. z$ s" O6 k6 K
bestfit = fitvalue[0]
9 a3 T# A; z( h' P for i in range(1,px):
* ]' o/ |) L4 r if(fitvalue > bestfit):0 u& V6 k( Z6 ?$ z- C
bestfit = fitvalue; H# K0 l* U$ {# F5 L5 ~6 N- p+ D) E
bestindividual = pop K6 }* P6 ?) _+ g0 `; D( E6 v
return [bestindividual, bestfit]7 [$ {6 ^: W* F$ Y( X) T
import random u/ `: S1 h( m9 P! Q
5 ~( P2 Q E" q1 Y" R: e
def sum(fitvalue):
# ^3 O$ ]% B% l+ m total = 0
( e& N- O3 |; p for i in range(len(fitvalue)):" j& k% _! P9 y/ k9 o/ Y
total += fitvalue0 ~* s7 n2 b5 |9 m0 }
return total6 |( }* Z! e7 o! ] E. a$ s$ d1 \) s
/ k5 f) W7 X7 A2 H* ]def cumsum(fitvalue):9 H9 t7 l9 x$ L/ [- |- P6 x' f( |
for i in range(len(fitvalue)):" \: p/ _# X1 G# V7 B
t = 0;
8 X @' @7 d' d j = 0;, t4 c8 V8 d" v/ u# ~, O- f
while(j <= i):
3 G' Q+ t& r5 t% p* r8 e t += fitvalue[j]
* J1 O+ g+ C+ K; S j = j + 1; N( {) o2 E4 j) c0 V" [4 Y
fitvalue = t;
4 R8 u4 Q( r' L2 B) y5 V8 F: w
# \6 A* l% x/ f8 X+ J8 Mdef selection(pop, fitvalue): #自然选择(轮盘赌算法)
" k8 O) i0 f' @. L newfitvalue = []1 o8 j) b: _7 ?. h- p5 ~0 H
totalfit = sum(fitvalue)& j8 o( O/ L% |" j. n2 e _
for i in range(len(fitvalue)):. x, r8 P* S0 o
newfitvalue.append(fitvalue / totalfit)9 [5 f8 a7 W, O; q0 O" a
cumsum(newfitvalue)
% a! F6 }" N* Q. _. F ms = [];# G I' Z: q- Q' O5 o- p# Z6 \
poplen = len(pop)- U$ J; U/ g, L( o' D; [
for i in range(poplen):
% g) b5 G3 m6 M1 h* r& l2 }# V5 \ ms.append(random.random()) #random float list ms
* n: u% B7 \# t% ?. r ms.sort()
7 C- E: R% B5 S' G9 t; s2 C fitin = 0
( {3 h: {8 O4 \% O3 P newin = 04 B# z5 V" I( T( _; c/ q: a; E5 H
newpop = pop# V# g1 ^' G a( t4 K, p: O$ [; m
while newin < poplen:
# Z9 {5 t- E$ x: C% ^ if(ms[newin] < newfitvalue[fitin]): G2 y' R3 `6 S$ Q0 S
newpop[newin] = pop[fitin]: ~, k) c) v# S' o* z) ?2 D: @/ {9 K
newin = newin + 1
, a: ^. ^6 A3 R* T5 L else: E: F2 w p2 D3 h) a
fitin = fitin + 1
' N# \# q" a* X& x5 W pop = newpop
! Z3 W8 o! O# w7 Himport random
( k% @8 u$ g! t8 j+ t$ v% @
7 \9 \. Q# ~% z- i+ P% T. ydef crossover(pop, pc): #个体间交叉,实现基因交换4 ^. g3 b5 T' a0 R. ~! `
poplen = len(pop)* B. r% h5 W; b1 p( e; Z3 Z/ ~
for i in range(poplen - 1):
, l- b5 d S5 @# L9 U" W9 h; }( b6 A if(random.random() < pc):
* x7 R7 N+ T1 S5 `: ^/ j cpoint = random.randint(0,len(pop[0]))+ \6 s/ C# d2 W0 n7 \, w
temp1 = []7 c, a: v: t p5 q" D* }
temp2 = []: {) D( x2 L- D( z. }# C3 Y
temp1.extend(pop[0 : cpoint])
0 E9 D! v, _! Z8 M: y( C+ a9 k% x% X temp1.extend(pop[i+1][cpoint : len(pop)])
! }( |2 ^" d' h$ {) z0 G temp2.extend(pop[i+1][0 : cpoint])7 A! h' @" Q7 r- d" \" W" e- `" ] H
temp2.extend(pop[cpoint : len(pop)])5 o' \/ v7 v3 g1 t" `2 H! T3 v
pop = temp10 S7 o, q2 v! `$ u9 `# c* A
pop[i+1] = temp23 ^6 G" f) o0 J6 j" Q
import random
/ H% _3 D3 N9 W' W' \: V6 Z) {) M7 U/ n: E/ h5 e. ^1 A4 M
def mutation(pop, pm): #基因突变2 t; ^: D- |& D/ w6 S+ H3 m% C
px = len(pop)
- j% A9 L& z2 ^4 h py = len(pop[0]). `; G i* P8 w, Z: |, r( ~+ F9 C* ~
* N# ?% [0 _* a3 w for i in range(px):2 ^! r4 c/ X+ H" ~
if(random.random() < pm):& {4 K% y5 [" g. w* ], [, X$ N
mpoint = random.randint(0,py-1). ]% ?# I2 z7 N! [+ w- k' w! o
if(pop[mpoint] == 1):# q* l- c1 e6 _+ x: O" C
pop[mpoint] = 04 T* m" Z7 Y$ b5 Y; @. y
else:1 N7 A8 _8 [& O( P% m+ {9 t" p! c" L0 v
pop[mpoint] = 1; S! F4 m7 Y( O% v& j5 ?0 ]
( {6 K% x {* ^6 h
9 i0 `% M0 ]9 R————————————————9 @( x) K4 h& {1 \2 l0 H4 k' `3 D: y
版权声明:本文为CSDN博主「simon-zhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
9 ]% U( M' `* u0 q9 C/ ~原文链接:https://blog.csdn.net/u010902721/article/details/23531359
5 K8 w. D) U, |1 t* [# L" k6 U$ q0 Z' @. V
; q4 ?0 O! R" b2 Y# _2 i! A* f |
zan
|