1 M( L& {: d. v! s/ I; e种群:多个个体即组成一个种群。GA算法中,一个问题的多组解即构成了问题的解的种群。3 t& q# S7 T7 \ t9 d/ G) j- p
" M: R) R5 ~! O, [+ }2、主要步骤, N/ G2 P0 F2 V( s r! A k
GA算法的基本步骤如下: ; P' I1 e% n* G9 C) w2 H ' z7 c1 c. p% I( D- MStep 1. 种群初始化。选择一种编码方案然后在解空间内通过随机生成的方式初始化一定数量的个体构成GA的种群。 2 Y* r, Q& W' | ; G9 u' Z% T! s! D# }7 {* Z* R2 bStep 2. 评估种群。利用启发式算法对种群中的个体(矩形件的排入顺序)生成排样图并依此计算个体的适应函数值(利用率),然后保存当前种群中的最优个体作为搜索到的最优解。 6 W9 A2 J, ~2 s9 X9 B" G8 G+ a1 g7 y; E
Step 3. 选择操作。根据种群中个体的适应度的大小,通过轮盘赌或者期望值方法,将适应度高的个体从当前种群中选择出来。6 s* `' p+ `- B$ \
, ?" g; g! @* w+ z _0 n" ^/ |/ h( JStep 4. 交叉操作。将上一步骤选择的个体,用一定的概率阀值Pc控制是否利用单点交叉、多点交叉或者其他交叉方式生成新的交叉个体。1 l/ _/ d' v$ S8 B8 ^
5 H- M0 i. p( f. n
Step 5. 变异操作。用一定的概率阀值Pm控制是否对个体的部分基因执行单点变异或多点变异。; U/ u; t- V k/ o$ v
8 T8 [ |, K+ N. V
Step 6. 终止判断。若满足终止条件,则终止算法,否则返回Step 2。) j/ \8 k. ]2 L5 Y. e# [: `/ b
: o; J" w k" X* |+ M4、Python代码 5 a' c7 A4 w' _" K1 C#-*- coding:utf-8 -*- 7 t x9 c! P+ ?" Y/ g& _ ! V+ V) V- t$ J: e# u) ~* ^! o5 [import random ! ^+ ^5 t- e- [: g/ R( D" ~2 l, Jimport math4 }+ f7 y! ^* p3 c$ _ I3 F
from operator import itemgetter. A0 I8 @" l$ W& o% u% Y
/ }% K4 f: G* d6 p9 P
class Gene: " q. q& h( q" a6 r' ~; B '''# P* I9 r; p' d( K$ O* k6 Q: y
This is a class to represent individual(Gene) in GA algorithom # ?" n5 ~: L8 j each object of this class have two attribute: data, size ! G$ ]- u, b3 y, S* D7 E% m- q '''0 m" ^3 V+ X. {, ?: ~: F- L4 v
def __init__(self,**data): . L: o V. b/ `7 f# n/ Q" b self.__dict__.update(data) / `. q T$ g* u
self.size = len(data['data'])#length of gene & @7 c% x& d9 l# Y" V [3 {% K8 p! ?2 q6 l1 b) ^$ @8 l
& D1 Y" g9 N7 I4 t( v6 Kclass GA:6 F. _$ a% t W$ T/ S Z
'''1 H( N7 O3 o: O2 K9 K
This is a class of GA algorithm. 2 D+ m( L. d# v, _& d ''' : g) o" z. y* w' ]1 I9 w5 G4 U def __init__(self,parameter):% W9 u# I7 ~% }
''' 0 o) \0 O u7 W P. w Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . $ K6 k9 @. {9 F1 a) H5 z The data structure of pop is composed of several individuals which has the form like that:) I. w) H. G) K9 K {
- S; @& f( M- U3 p- y# U" N
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} ) h1 y) X! @+ x/ f6 O: K$ q+ e/ s Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] 5 c# n! }( n7 I! N2 _$ B) g5 i" m5 g
'''- Q. ~! T- N% L4 t9 @, `8 K
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up]) L" a9 |1 f" D6 l) S8 y; P
self.parameter = parameter ' c3 M. v* X; k$ s9 o& ] 0 _2 J0 |' d7 V7 w, e3 V. Q low = self.parameter[4] + `8 Y' z8 G$ w+ x8 ~7 Z) ^- y up = self.parameter[5] ' N. ]. J" K+ f0 I1 @" w" q 4 S5 q, t) e% V- E/ H self.bound = []+ U0 ]- }; s" R& T. c: e- d
self.bound.append(low) 4 O; c1 y' W& T. u% C# |* I) q _ self.bound.append(up) 8 j6 d2 ]4 q& a' Q$ {5 K7 @& A0 V+ O) U, Y# s8 }1 W7 ]9 s+ T
pop = []9 W& E- x& @, r- I# E) Z' r
for i in range(self.parameter[3]):1 @# n. R. l1 {% M( Y$ a
geneinfo = [] ' u# @8 J& B* t7 s for pos in range(len(low)):! P! i( w0 ?& t1 Y% u4 L
geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation / {% Q) I# X+ H) u+ G " [. e; a$ o; T+ D6 B fitness = evaluate(geneinfo)#evaluate each chromosome / W w1 C1 n7 p( z4 z+ P pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness 4 ?, `- L8 e0 [, |2 B( |: l 1 x3 K# z- b. `4 z" D" n# b2 J. I self.pop = pop $ [5 |$ W9 e" x3 x: a; o" Z self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population' ?, r) }" ?* ] S( [
3 b, ^0 W$ R5 {2 f/ W% d
def selectBest(self, pop): % H$ k* k. c" t4 d) W. n '''* `* q2 y' u- o4 [- {; g
select the best individual from pop/ U. J1 `( r' I5 c6 U
'''! r: v3 ?& y- y8 h1 n2 T/ b% N( ?
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) 8 c( f" m) y6 p ^2 T2 a7 H return s_inds[0] 8 i0 w+ I, M. q% h, R) r$ s8 f) [3 d" G% ?# z) [' t( T
def selection(self, individuals, k):: |2 E5 `% s2 Y' A, I
'''' D7 U# c% x3 n: d6 @, l m, a
select two individuals from pop : x# P5 |8 C: p6 J2 c '''5 r" C9 [/ Q; y9 I% l$ U3 t
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness ( W1 Z1 m" X/ H7 W* K sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop ' ^+ R3 j! R; n, v. M: R; Y- G$ c' ^* ^
chosen = [] 7 [# T1 K5 {: k0 F4 w( c# l for i in xrange(k):5 j7 h! D! w3 o4 r
u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]* s l( H! p7 Q9 y
sum_ = 0" i4 c J8 z; G# r$ @4 P, E7 |
for ind in s_inds: $ `8 v0 P- Q9 l sum_ += 1/ind['fitness']#sum up the 1/fitness- A+ J. J4 `* X
if sum_ > u: ! L" V( p6 r9 W f; d" ~# E4 P8 e #when the sum of 1/fitness is bigger than u, choose the one, which means u is in the range of [sum(1,2,...,n-1),sum(1,2,...,n)] and is time to choose the one ,namely n-th individual in the pop W2 z) ?( R; e6 z
chosen.append(ind) 2 R+ J( f$ }$ p+ X4 D break m+ @" D6 J( G' H' R2 x
( D- ^3 i. \. W9 D) N return chosen " m% g$ M- k8 S- Q" z% ` % q" V3 H7 s9 D8 p0 F1 r& U, n3 H O2 C) Q" Z. N
def crossoperate(self, offspring):' P4 |" I' H) O R8 K# o0 U
''' 1 [6 V9 B- e! M r7 P* q) \ cross operation ( V6 v6 d/ O- _( E! \' y! o( ? ''' F- C) E7 V" }
dim = len(offspring[0]['Gene'].data) 3 f7 B) `- E" E/ L- D- Y " t+ r3 W5 a" b( Y: d geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop ; Q2 n5 z* t- C0 R: J% r geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop; v5 i: P8 E5 T ~0 j' k9 Q
6 q& e9 t0 P! y3 \ pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 2 W7 F7 E& n$ O
pos2 = random.randrange(1,dim): Q% Q/ s4 T* ?
# v% h/ H7 P# n2 O7 v# F5 ~
newoff = Gene(data = [])#offspring produced by cross operation ( p, t+ r) a8 q' H# r% F temp = []$ x* ?" w. [5 z# [
for i in range(dim): 7 Q0 y/ \/ C. t) K if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): U& y( f5 ?# W$ ^5 s6 h
temp.append(geninfo2) 9 P3 h3 p% M: @ #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] 3 L/ {1 e# [* r% r5 f5 W# S& z else:8 b3 Q, ^; J- m7 }
temp.append(geninfo1)- p- s; A/ ]* L6 C" t8 i
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]* j7 L3 R) a8 h. x- P
newoff.data = temp 1 ?8 O2 q B3 r7 q6 ?' c: Q" Z0 f2 |( m, s: _
return newoff # n$ Z' F1 Y$ O- v& `, \ , R/ e% O# `! X3 x& k ; W1 \" ~0 r' n# ~% w9 t5 S def mutation(self, crossoff, bound):& G7 C# W6 s0 K( s* u
'''' }* Y) M! f, _/ }
mutation operation ; p& o# T H7 H: ~; d" O( |! S- k' a ''' 9 F7 P' ]& d* q' ^3 [2 e( u : s; T) W; ?% j; g5 a dim = len(crossoff.data) ) V" e N/ H: u4 U1 x3 b1 D1 r& `' N: k) K0 c: l& t+ [
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation.+ ]3 }1 g2 \! _( a
5 W: P5 r$ N6 w/ _1 u
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) ) [1 l R. Z, @# |/ U9 p# ] return crossoff, d2 R9 r3 v9 `
# X+ [( ?" y: d5 Z: j Z def GA_main(self):$ r" d% M, S) a1 n: G
''' . [! a: B( n) U# U# T1 G- H3 q( ~ main frame work of GA5 w6 L7 g4 \2 o5 |2 u
'''+ C" F9 V9 {. o Z; ]" x7 J
+ J+ U2 j1 c" ]0 x
popsize = self.parameter[3] [# \" S# L9 S* B2 |3 z " s; V% t; k" T* b5 }8 l& t print("Start of evolution") , R2 T, ?; _% V7 ?! ~. ]* A" t) Q2 y6 u: d. I: @
# Begin the evolution 6 N( R& `5 i, Z6 F- b for g in range(NGEN):5 r, N3 s" Q6 r5 }7 W( M
- L5 J, C# l, M. J" O1 u print("-- Generation %i --" % g) ! x1 o& V; ` L- ]7 M* B: ?. i" j
#Apply selection based on their converted fitness ( S2 U2 F1 M1 I, j selectpop = self.selection(self.pop, popsize) 0 _! |% c# c$ [, r3 ?# d, [6 o" L: `& j2 S9 x: K
nextoff = [] ! J. y3 P# R [5 Y, {2 c2 ?
while len(nextoff) != popsize: 0 t7 z4 N0 o: W- d1 g
# Apply crossover and mutation on the offspring 0 [1 k9 |+ f: y; @: j2 \* ]9 n3 ]
8 ?4 e+ m' [0 r+ u. e # Select two individuals9 t5 U8 y: F1 Y
offspring = [random.choice(selectpop) for i in xrange(2)] / X. ^/ f+ {. R5 R; f1 N( y& h$ R) ?# U4 r s
if random.random() < CXPB: # cross two individuals with probability CXPB 5 m6 c6 e! l' h( G crossoff = self.crossoperate(offspring) `* _, {) F9 w( S' |9 u! ~ y7 Q
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals 3 K; Q- Q4 K4 M$ k 6 z) s8 i J+ h& J) V1 [ if random.random() < MUTPB: # mutate an individual with probability MUTPB + i2 z4 J7 P3 j0 e* u$ ^# j muteoff = self.mutation(crossoff,self.bound) ; T7 O0 M# s9 h1 E! `5 ^ fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals- O5 `+ K/ _- q: r) G# U3 ?
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) ( s; b0 x a% a8 |8 j+ A ' r0 C! U! q: b% k* O # The population is entirely replaced by the offspring - W$ V) {+ [8 |1 a. Y( S self.pop = nextoff5 i: ?2 R! j4 R( J4 M# E
& O& J K" t& h/ c+ x # Gather all the fitnesses in one list and print the stats ; |6 `* G$ J- o. {8 w4 b: n3 z fits = [ind['fitness'] for ind in self.pop] " N, {& E' X2 S5 L& z: e! \ D7 ]9 V4 ]
length = len(self.pop) : @. m; T: |6 ~1 v" d- o mean = sum(fits) / length ' k2 b) X) M/ F2 h- m sum2 = sum(x*x for x in fits) ) N: k/ n5 d$ ~) P5 Y std = abs(sum2 / length - mean**2)**0.5 & Y X' K& Q+ r2 i+ v best_ind = self.selectBest(self.pop)- ~3 _* `. {( ?! V, g% u
9 k) b, z) S# j( \9 t
if best_ind['fitness'] < self.bestindividual['fitness']: % n6 A, V7 F( s0 {- A# z# R3 [3 ]6 r self.bestindividual = best_ind , ~" t7 _3 ~0 \* v2 Q 6 s; [7 Q& r9 \" N5 D% M print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness']))) A% |! Y* k$ Z
print(" Min fitness of current pop: %s" % min(fits)) # s( ^% ~2 L! }5 a/ Z print(" Max fitness of current pop: %s" % max(fits))4 n- K) m. i8 D& ]' y5 g4 t# }
print(" Avg fitness of current pop: %s" % mean)! Z% N4 U6 a: Z1 c0 N
print(" Std of currrent pop: %s" % std)- `) J8 _, T6 J6 X$ Y- q* T
, u5 E7 P& H5 {' }. x: c( _ print("-- End of (successful) evolution --") / z6 y4 J2 K% J: @2 F0 `8 q6 G; T7 s& a+ D8 \1 U
if __name__ == "__main__":* S; E; X; M$ ]4 i$ \2 c; G
6 F: @5 `' k/ k/ }8 S
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters 9 I7 J/ J! [6 d7 V4 o* i' [; i 7 Y0 u" B# F1 q& j7 g1 f up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables/ U2 `' \8 D% o- B$ e- E# p. c7 h
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables4 L, \, M- m1 Q! X! R) ]0 Y( J- p
parameter = [CXPB, MUTPB, NGEN, popsize, low, up]+ Q8 C* D. a. R" c& [9 ^- X# ]
# w9 _8 h# u$ D; \6 P6 O run = GA(parameter)0 P1 G" R0 y- i+ B+ u3 l; w
run.GA_main() 1 J5 w7 ]( |5 m$ o. G1 j! `————————————————: S1 Q9 H: D( f/ m: ~
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. e* F4 X+ T# X6 y2 T
原文链接:https://blog.csdn.net/bible_reader/article/details/72782675( E3 c0 D8 v+ C5 K$ x( v+ X
. @) X/ o- ?6 m# H5 r; r. s9 e( C, s& F2 V6 u* _7 R3 K: i, _% Q2 C