' n6 M$ L1 S J遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好地诠释了生物进化的自然选择过程。遗传算法也是借鉴该基本法则,通过基于种群的思想,将问题的解通过编码的方式转化为种群中的个体,并让这些个体不断地通过选择、交叉和变异算子模拟生物的进化过程,然后利用“优胜劣汰”法则选择种群中适应性较强的个体构成子种群,然后让子种群重复类似的进化过程,直到找到问题的最优解或者到达一定的进化(运算)时间。9 t. _5 z6 ]# `) k R
3 M+ g9 }4 n+ A5 X3 p( j# KStep 1. 种群初始化。选择一种编码方案然后在解空间内通过随机生成的方式初始化一定数量的个体构成GA的种群。' v1 v d& ?8 ]- M& W
8 ?0 z- n a! T% `, c& Z, Z! _4 b6 D
Step 2. 评估种群。利用启发式算法对种群中的个体(矩形件的排入顺序)生成排样图并依此计算个体的适应函数值(利用率),然后保存当前种群中的最优个体作为搜索到的最优解。* N, A) u8 k i4 n: J# M, S
8 W @' _) a. t4、Python代码 2 I, G1 D. f& R#-*- coding:utf-8 -*- d- I. Q: j# f* ?3 b" {! S
+ R- z6 s# ?$ T" s) S: I4 V$ Limport random : q4 t* g% w* C+ D1 Kimport math " u- F% b* `# u! R' q4 ^from operator import itemgetter 4 o2 @. y+ ^. Y$ A% {! V % |8 j8 N. O" }1 Wclass Gene:6 w3 q' P+ O9 C
''' 5 ]. ?+ n( k; d3 n4 J This is a class to represent individual(Gene) in GA algorithom- P* d" m" v0 {* |! _+ n/ |0 o5 b
each object of this class have two attribute: data, size + d7 A8 d+ T( h! @& v, f '''$ y# s& J. H0 j" A6 Y |4 [8 v
def __init__(self,**data): 2 z' Z+ m) x2 }7 I8 R self.__dict__.update(data) - s3 D6 ]. W" c2 Q# j( t5 n$ m self.size = len(data['data'])#length of gene ! m, t) z2 l" g* ^ . o: |' P5 z. p6 x ! J1 }( @9 z x% Yclass GA:% n" ~& A; r; X& H: h- y
''' 8 ^" O+ N* `. C4 [ This is a class of GA algorithm. 6 ~% P9 `* r- }" ]$ c ''' / b/ V( \; G7 S$ u def __init__(self,parameter): & i3 \" c z% j. U '''1 S' X% v# t2 T g7 p* O! x% x
Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . 0 g$ O; V( D: I- Y5 V The data structure of pop is composed of several individuals which has the form like that: x! |7 r8 q3 X8 }2 P - p8 o( [. H7 J- x% P {'Gene':a object of class Gene, 'fitness': 1.02(for example)}3 C7 V7 y& H6 Z$ M _* B
Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]7 |1 z' J' w) U# Y$ @ h0 m3 D/ n
, \1 i0 L1 z+ g- v9 b; b' t
'''& D/ L5 D# z" e x! C, g$ v* k
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 5 n+ w( ^% w7 L- l7 m self.parameter = parameter$ Y, `5 q. c0 c2 W P4 s
3 r: c: x- U1 c3 ~! w0 B low = self.parameter[4]8 E+ n! e0 I9 K. `, d
up = self.parameter[5] 1 _* h" Z0 C M# V* }5 U1 ^+ ]0 @2 b9 J9 K% V( I; |! s7 a; T
self.bound = [] % \1 k9 B5 m/ K6 G2 c7 S self.bound.append(low)/ {5 Y3 E" h ]2 [+ L
self.bound.append(up)/ h; S- I2 Y, v( T4 t; g; Z
1 c; Q' a1 T5 O$ H# {6 O) U+ }0 [8 {
pop = [] . ?* a6 a9 C$ o1 ]( E for i in range(self.parameter[3]):# f8 w6 {+ a5 m4 \$ W
geneinfo = []- M" }# J- k( Q1 h
for pos in range(len(low)):; Y+ \$ v8 e( W, {( v; }/ e+ V! n: l
geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation& G( Y: k) j! e' k/ n: d( H
6 ]/ L; Q$ O! Z# k2 b1 Z' h
fitness = evaluate(geneinfo)#evaluate each chromosome4 x8 N/ W6 q( o* \( ^
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness# \ ?3 {4 ]9 I0 Z! W2 `4 h* u
3 r/ B$ F6 t. R, a- i self.pop = pop * v& j$ a; Z. m6 D6 _0 y- z: `: j self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population # v" m. n3 W. g# O* o T9 a6 i" z8 C: J$ {
def selectBest(self, pop):' W2 z, T) }/ ~0 {, ^6 D7 K
'''- ~! ^8 s. H, H; `
select the best individual from pop. E% q" A7 S' r
'''0 V7 d8 N; ]7 c y8 H& @: w
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)2 C! }8 b( h% w3 G! J
return s_inds[0]$ b: w2 O9 f7 }5 o3 ^( s* Q f2 j* w
, G* F5 {' c) F4 n+ g
def selection(self, individuals, k):( H, T/ W1 @* R/ `6 j( m, V" E" _# b. U
''' . K+ v& a4 ~% B% [, j select two individuals from pop: G- D. T+ C5 s+ ~0 v) v! F
'''9 D. `: ^# p* M$ `0 f
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness ' C7 z; O% y; D4 m0 ^+ D. T% I1 f sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop1 c/ ?8 x" b$ r% ?$ \" h
) O8 o' [+ D- z- ]8 U6 ?( M5 ` chosen = [] / ]( O# F3 N/ F ]; X+ Q) V for i in xrange(k): 6 W8 L5 o2 C$ f( W }% X2 U( h u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]# M5 Y3 l$ G2 k/ H6 I; C* m7 D( x
sum_ = 0 7 M% U+ z5 v. P( b for ind in s_inds: 9 ]+ O0 }: O# @0 b sum_ += 1/ind['fitness']#sum up the 1/fitness. ~2 V$ N' h' g/ w9 K3 k9 I' c6 O# x
if sum_ > u:* L( g/ U3 `/ t3 g
#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 * m7 j& F; N. p: |9 @; K; Z chosen.append(ind)0 Q% @9 l% r& {% B; }( Z
break 7 Y4 @- a t1 D+ A, Z* `$ @' T$ o/ j( ]
return chosen ; t" N! K0 @7 F% P& a
$ B- T9 p p) e
" ^" { D3 O6 S& h8 r; u2 o+ C def crossoperate(self, offspring):2 F* T; }' D1 d- ^' V) X; {% k$ W- q( C
''' * n S$ Q9 t5 Y9 Q- _! d c cross operation 0 E( x# E/ z, Y/ @% }/ I: [ '''1 H; c1 v: I% y/ M ] N/ m
dim = len(offspring[0]['Gene'].data) % j; H) ?/ l# v+ K + i) s# a% E' ^# y; `. c geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop ) \- f& w0 ^- Z" Z/ c geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop$ l Y' I M/ O; z6 p
[0 ?. M7 W6 g6 k/ ^. e8 q pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, " V0 P* a u8 v$ H pos2 = random.randrange(1,dim)+ }* i! c }4 t9 o$ |
: ]) {+ b) d8 A& [& I* @ newoff = Gene(data = [])#offspring produced by cross operation9 \- |8 D8 j1 _$ {$ U
temp = []( c% v+ v& E6 q
for i in range(dim):9 U, v+ {( v9 \& o' K
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):* k7 ?& D$ c+ w
temp.append(geninfo2) 7 Q: e* b8 s" @; Q4 J( S% A #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)]/ o$ [% x1 M5 p( U; E
else:( y9 d8 q/ a# o" r
temp.append(geninfo1)$ s( `' { v& H5 \
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] % x& T/ _; @8 j1 I8 O* J newoff.data = temp : h2 F/ P# w' @6 g0 g & U, Z) v1 y/ X8 P) U/ D$ v8 g+ r+ a return newoff 0 a5 _& U' e8 l5 n' [* d2 i 8 ]- y* U6 v q1 R. `; Q# W" w, G! g, l8 X- r; u# H% h+ ], k
def mutation(self, crossoff, bound): 7 q8 u# f, t3 {; h ''' * N$ |: s6 q' c. i mutation operation & e1 d3 Q3 m# w! `1 f6 j '''/ ], K7 V1 A$ k1 N/ g4 A" G
& i0 i9 O- |( T
dim = len(crossoff.data) 6 @, n( U& z! e1 O+ x8 i5 l. b
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation.1 u$ E! N4 O- a' t) W- X
0 ?* B+ q2 B% `" d crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])- m, o! A$ T9 I/ n; B ?2 g9 N/ a( ~" H
return crossoff : `1 @( Q7 J P9 f8 J' m" Q$ U + X7 a' R" _; J5 A+ r/ a- U: ]1 y def GA_main(self): E. y N$ \, H8 Q9 U$ D4 { '''* o' J# i) B" F/ [+ C) [) O; m1 k# ]3 w
main frame work of GA, s. y1 X% K0 `2 C! Y" ?
'''. Y' `9 e7 U8 a3 v3 K" k
9 d5 t+ V. J2 F0 q/ \, |/ m # Begin the evolution. p; P# f' c4 B& G! n
for g in range(NGEN):) Q" |; B8 \' J6 V
! F- o- l1 S! h& w print("-- Generation %i --" % g) - V+ F8 G! i$ J \- ?* `; y6 U 3 G$ @9 o* C9 h! ?1 O+ C" S #Apply selection based on their converted fitness % }7 ^# u" a4 @' J selectpop = self.selection(self.pop, popsize) : b& O: y/ ^, X p' F0 B
+ ~* h8 w* R7 C2 K
nextoff = [] ! y8 T) e6 E' k3 x4 Y& @
while len(nextoff) != popsize: & k+ f. p6 O8 z: ]3 t# s7 F # Apply crossover and mutation on the offspring * y$ \. D [- o$ D7 Z& L" t8 v0 ^% n7 C* q k
# Select two individuals5 T! \: @8 U0 q O
offspring = [random.choice(selectpop) for i in xrange(2)]. Q' Y+ I. p* I' P& p* Z% S
" @% w7 z+ T6 A! k& i- z/ ~" } if random.random() < CXPB: # cross two individuals with probability CXPB # b/ a) P- u( m; O4 N. q crossoff = self.crossoperate(offspring) 6 }" u& l, {5 o8 Q6 W fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals 5 S' o9 Z D5 w$ l1 P: C# Z
P7 F2 i# ?7 h5 a: T7 N. M$ V, Z; j' ~ if random.random() < MUTPB: # mutate an individual with probability MUTPB ; m" W8 o4 ]+ W# E4 X- X muteoff = self.mutation(crossoff,self.bound) 9 A; N4 g# E: T& Y5 @% R" x fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals W% v8 w, c0 d1 S2 V9 |
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) $ j1 {+ i' M) ~) T0 I0 Y& g! u' _, u- V6 X
# The population is entirely replaced by the offspring; y1 A1 P: g& ~* z& }% Z* a
self.pop = nextoff 4 o8 i A6 O* z! J* [& A; `1 n 2 E/ |' C! ]: K # Gather all the fitnesses in one list and print the stats ! D! o# W8 v6 m) g6 l* D) q( W fits = [ind['fitness'] for ind in self.pop] 9 N, `* y2 a- A 4 D$ J, s H$ l8 e3 n length = len(self.pop)/ I. o# Z7 R5 d; ~
mean = sum(fits) / length8 W, P" b4 ^ o# K
sum2 = sum(x*x for x in fits)0 I+ s* @, W% f w2 S- [6 ~
std = abs(sum2 / length - mean**2)**0.5 % r- U7 W, P# s/ X% Z best_ind = self.selectBest(self.pop)- ~- S0 B9 D* D
- A! j3 M' Q/ ~ M4 K1 F( | if best_ind['fitness'] < self.bestindividual['fitness']: ; M( z" ?2 q8 u: ^9 L self.bestindividual = best_ind) w' G4 @! V* V, D& x( k6 v& d
; }" b9 { ~) Q% a7 o
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) - V; p/ T4 _* m print(" Min fitness of current pop: %s" % min(fits))* S* `8 A9 f/ b# P" A& D
print(" Max fitness of current pop: %s" % max(fits)) ! e& Z( E' s; E% q/ z( R5 H1 g print(" Avg fitness of current pop: %s" % mean)( `, A( o7 S/ v: ?
print(" Std of currrent pop: %s" % std) / q# B' F9 Z% t% U3 ] 3 O/ o# `8 m7 h- S# \* p print("-- End of (successful) evolution --") $ C% z9 g! G! t8 ]9 k2 r 6 k, `# b7 m/ R8 L' X2 yif __name__ == "__main__": 2 {! u* O' y* B7 T+ ?+ {9 S5 d1 O
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters7 w9 W" s+ V. ^# W( f' V& Q+ g5 ?2 g
* A$ ~5 [ D. j2 M$ J! p- i G
up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables . J. G5 ^5 w0 H% B2 l' g% ^ low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables % k6 W& r1 a) `& `9 k/ U( z parameter = [CXPB, MUTPB, NGEN, popsize, low, up] - T& K& j/ @$ \, g" d1 r9 E ~: `6 g" R
run = GA(parameter)" f3 t/ L$ e" ]/ K! }
run.GA_main() v, w- ]% N3 O- F6 {! {, K8 d
————————————————1 ~8 d0 Q7 T6 g: F, |' @5 }
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 6 [0 \) V- e$ z: L原文链接:https://blog.csdn.net/bible_reader/article/details/72782675" a2 v- C7 T6 T% M