- O G0 q! l! r" N+ h% e9 ?0 ? 9 @: u% S5 _" e! U. p5 m: f& J" h4、Python代码 i" B5 |( i9 Z#-*- coding:utf-8 -*- & x' U3 X6 H( A* U0 @8 z1 n6 y1 W+ j. x( E, o! ?
import random1 c6 z9 s1 |+ E
import math7 z: K, ~! j# E. S$ n5 o' @
from operator import itemgetter 3 K9 m9 h/ P' V& Q" \ 2 D b$ R$ l C( W' Q9 gclass Gene:; h2 z1 W7 g) W$ O0 m ~! s; Y
'''! \ L$ L" E, Y& ~
This is a class to represent individual(Gene) in GA algorithom$ s: r* E7 O; Q$ @$ d
each object of this class have two attribute: data, size4 r" Q! A. e4 l! z
'''1 B' P- \9 H7 v8 j
def __init__(self,**data): : f' N% h/ y$ p4 ~$ j% f5 U self.__dict__.update(data) ; Y( ^0 ~/ l$ h$ k2 q! K5 ~9 C3 S
self.size = len(data['data'])#length of gene' M# T- j, P; T& G8 C3 y
' f, z" O8 T5 P
" W& ^; c9 Y3 |( T4 n" Eclass GA: 8 p/ s8 A& w9 b- s. M; d' q& k7 ` ''' M1 ~6 X p( q w This is a class of GA algorithm. / T/ Y! c9 _$ \# j ''', Y' R+ v$ I3 i3 X7 V( A
def __init__(self,parameter):& ]4 H1 h8 Z6 J
'''2 z u2 [! R" |0 R) ^) r' k
Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . / i/ c) W7 e+ i! f( e The data structure of pop is composed of several individuals which has the form like that:. l( \6 x' u( G) F8 _6 p
' _" K s; H: s; s7 Z# Z* F# z: w
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} - Z0 W' S) ^4 F# s2 x1 [ Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]# F6 `/ p, m r2 [9 K
+ a$ r7 ]" |& B ^. t+ T+ W# P
''' ! T) O6 m! \! T #parameter = [CXPB, MUTPB, NGEN, popsize, low, up]( s5 z% k0 Y5 `1 M8 D
self.parameter = parameter H' _) P" v( G* } H5 u k8 ?, M( [& c, I; ?7 M
low = self.parameter[4]4 r' U$ W7 \' D, J: h
up = self.parameter[5] + ~6 \7 G$ R3 }9 j; f2 ?9 U5 |) }% F v% y: [" `
self.bound = []% _! ^/ ~2 R1 q4 ^ {
self.bound.append(low)+ I1 n, l/ `& M5 y1 f
self.bound.append(up)7 T, ^6 {* l3 S2 r
$ K6 ], g- l2 |* M6 q& m+ ~* P- O
pop = []! t. z& R5 T, ?2 C0 d2 Z0 k
for i in range(self.parameter[3]):, j* P2 h* k( r- V# {7 j( U, b
geneinfo = []( H1 m5 O( t7 L7 C% p2 h' i& b$ [! k; B. f
for pos in range(len(low)):+ J/ ^) I- I C
geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation 7 s4 x$ ?3 {. I$ s1 P3 e % W; q: X) O- E8 A fitness = evaluate(geneinfo)#evaluate each chromosome3 u/ s2 w0 W9 L* {% Z0 h
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness m# O; ^7 T2 k' _0 w4 {
2 F `; K6 ?- w+ Z self.pop = pop o0 l4 A. R6 D) Z8 O3 S' W
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population ! V. w% ~! b3 j# y2 F2 k5 y5 Y9 }% w
def selectBest(self, pop): , I) N: \% E5 d# N4 J '''3 i5 K r: A- w) n# A9 D- U0 j" X
select the best individual from pop ) Z, O4 x. U) W* f ''' 0 J) O) w& f5 k" C) N" V$ f# I1 j s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)# v% d! t* K2 D: c
return s_inds[0]3 i( O) ~0 l5 w! m# P
$ P. e1 G$ z/ n! d2 G( [
def selection(self, individuals, k):, G! x- K' k' d. E8 T4 ]
''' * @1 w$ T5 v6 X select two individuals from pop; Y1 l9 }: e, p/ g" O5 @
''' & `4 B8 E, R- w$ y9 i s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness ' n% S& y6 x) F& o0 w u sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop . Z( N3 F) U; P " P$ g$ Y7 g. c# ?7 q7 U2 \9 w chosen = []* X5 K9 E$ d8 |5 b/ C' J
for i in xrange(k): : }0 @6 T4 J. G6 B u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]; {; _& E4 q2 O* `, a
sum_ = 0 6 V% ]; D: `4 F7 Q for ind in s_inds: 3 k/ k' y& c' Q' ?" z, R3 \ f! D sum_ += 1/ind['fitness']#sum up the 1/fitness ) v* y. Y' q# M5 }& u if sum_ > u:3 O( n5 W, f& c+ l4 m
#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 # B( o; D' X5 o- S, V& H chosen.append(ind) - p ^) h& f- Y break S3 w( B; x9 I" K
4 N; t% T: i8 T! k* j
return chosen $ }* f6 |+ C8 i% Y, [- l* ~
2 h9 F) k% {2 o1 k3 x2 k
- a+ C( W( o" y7 C+ v
def crossoperate(self, offspring):2 I' \) J6 D' I6 F1 p# r# t9 k3 K
'''- Z9 a/ q: `8 y8 B. p1 P
cross operation) v! }& W! ?) Y) h
'''1 f0 j5 s6 O* f1 g4 `
dim = len(offspring[0]['Gene'].data) N) Y; T" l3 ?+ }) i+ d2 q * p/ z% M# F: x. R. ^; q geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop . z2 I! i! Q( d ^ geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop0 U( [, E6 a; _4 u
3 Y- S' ?0 X7 k% R# J8 O, s3 H" Q pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 0 z8 w7 p5 M+ R
pos2 = random.randrange(1,dim). X9 \( E8 V" J5 X! H7 u! n2 O- {
- U2 Z/ u# K) s- k7 M
newoff = Gene(data = [])#offspring produced by cross operation % v. R! x8 T) i/ x! J# G& ?0 t temp = [] 7 X8 W: C; S; b5 k% Y for i in range(dim): 2 ^# n, F3 | x1 p, Z if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 8 m G: ^# q# F% X8 {8 _. D temp.append(geninfo2)6 d) K: o# K V3 _ a; S; ]& q
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] ) h. ^& x' g% E: f else: 8 T3 \0 d- o9 h5 ^ temp.append(geninfo1)8 V N N4 X S- I
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] * ~$ @& q3 e& c8 v: o6 C newoff.data = temp 4 x9 v, e2 [9 y( U1 u+ D4 ~2 t 6 g4 Z. ~" @" [% a5 J, E return newoff9 y+ p% |7 p$ c& i' ?# D
! E% j/ _, w5 c' ?8 I( f: w/ |* x3 i2 _/ K5 Q, A. b' e) B+ ^" c
def mutation(self, crossoff, bound):: Z! [9 K* R5 r: B8 k4 b! V" x
''' & A! a2 i. z* u3 Z mutation operation8 N9 m3 ?% o& ?; t; C X( Y" e
'''9 u4 U! t0 d( k: Z" Z# @4 H
! J# g% V+ n! f- ~& Y' | dim = len(crossoff.data) # J* S3 D: W8 i/ k$ r9 V 1 L- U1 ^ p" X; q2 Y. L$ }' \; E pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. m- z- ^( F2 {6 ]/ D& }* ` n' |6 d1 l7 V2 j% F' F, P n crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) 3 \4 X8 z; R7 J return crossoff 5 C4 m: V6 E$ T# u- D, n" k5 ^/ S0 ^( ^3 L E- X0 `) |! ]
def GA_main(self): - ?, \! t3 Y5 z5 P8 c ''' 4 f% G$ F; r7 h) y2 L9 T main frame work of GA + k& [: P2 E) D! o# J2 {4 H- O/ R8 O ''' 3 a# J7 n" c% }# l4 i6 ]; K $ b0 h& B2 }4 A- U( L6 C$ d: m popsize = self.parameter[3]' B' d m. g, P
! n: i( j7 { h, j2 F
print("Start of evolution") 7 t; c; q: U# X% J& Y0 r 9 U7 q1 |0 m1 p6 t& }9 {# k l: W # Begin the evolution' K" N: `) r3 M& p. G L- D$ U4 D) T
for g in range(NGEN): a) w1 B6 N2 W: H8 v* }
. C% F+ Y6 [9 Q$ }* H
print("-- Generation %i --" % g) 3 ^4 D: w P& `. H
; K6 T( d4 o' k6 U# U
#Apply selection based on their converted fitness. k, `- p+ p) t$ x& }
selectpop = self.selection(self.pop, popsize) 4 W3 M$ C( n- v2 t 6 M4 x% s6 A2 X8 D( l nextoff = [] + a" D9 _1 @* w+ w while len(nextoff) != popsize: : J4 p0 e/ k! V+ e; { # Apply crossover and mutation on the offspring " ~# B: Z/ c4 \, u
5 S' g% P' a: l' H, E
# Select two individuals ( P w+ i% Q; b' |! j. {* G offspring = [random.choice(selectpop) for i in xrange(2)] 4 |! E: C# h1 l: _" I. P3 y n7 w# L" ~4 N
if random.random() < CXPB: # cross two individuals with probability CXPB T* G) E3 }6 M! {) S' g, ^: l- K5 ]
crossoff = self.crossoperate(offspring)% u* I. T l. G
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals $ d* ^, ?2 u/ u9 I2 O ! `- N1 a$ ]6 f' v R: U! c; h if random.random() < MUTPB: # mutate an individual with probability MUTPB 9 g: _ S" Y5 p5 E- L2 b! O muteoff = self.mutation(crossoff,self.bound) . x3 S* H% y/ x fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals 4 z. u' F! `2 u0 r nextoff.append({'Gene':muteoff,'fitness':fit_muteoff})$ X- f* x: @; b2 Q* P5 M; R
@7 t, R% J& z* s( A # The population is entirely replaced by the offspring* R9 o& H: |) k3 ?/ Z' W% _( C
self.pop = nextoff% s; b$ F& `0 h' R% y4 Q8 L: U+ Y/ B, Z
! c" @" e% O+ E
# Gather all the fitnesses in one list and print the stats- t$ _) b# r5 z5 Y! [
fits = [ind['fitness'] for ind in self.pop] 9 O* D3 c1 T8 |+ ^1 o# M, y6 ~& h1 H2 ^! @, R
length = len(self.pop)/ ?" h x% N" _. W, ~
mean = sum(fits) / length1 x3 H Q# U3 X' |, L: G
sum2 = sum(x*x for x in fits)2 D( J" _* r6 e& d2 P* z( x' S
std = abs(sum2 / length - mean**2)**0.5 6 H) l$ n8 L+ E* Q best_ind = self.selectBest(self.pop) 8 h' E t7 `8 q% @. P/ |- ~: o# m n& R. L) S- Z
if best_ind['fitness'] < self.bestindividual['fitness']: 6 i: h1 U2 F5 E" I1 Y self.bestindividual = best_ind # e! S" t5 P# m0 C1 K2 d! z 7 m- {( s' I2 _7 ? print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness']))1 x5 y- t: S+ i$ f* a; x: g4 v( J
print(" Min fitness of current pop: %s" % min(fits))6 y3 @# r4 v! ^7 A5 @& N, v% j$ w
print(" Max fitness of current pop: %s" % max(fits))/ H: S' Q& ?) m
print(" Avg fitness of current pop: %s" % mean) 4 n6 z/ ^, C5 x+ V. E* K print(" Std of currrent pop: %s" % std) / n7 ^. _5 U. m% m& ^4 O. I0 C0 ]6 r7 f, Q
print("-- End of (successful) evolution --") 9 V; n N+ J+ |" X: c
* b y( x5 h' e7 E4 ^, K. Vif __name__ == "__main__":; s4 X/ r# O6 @: D/ P& k* G
1 S6 m8 x+ g" R/ B8 F5 O& E CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters J% _! U0 t& U- q5 `& }6 O0 s
up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables 0 q/ E- @. k) B3 f) ` low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables 1 I+ V8 }) |4 R3 o. _, d parameter = [CXPB, MUTPB, NGEN, popsize, low, up]: r1 D5 i; }' S' Z
+ h* C7 r0 K! Z run = GA(parameter); i& A# J ]3 m/ P" l v% k
run.GA_main() 0 D' i+ t6 N7 X: T$ s0 j———————————————— u- q0 g; M4 D" X5 d3 s版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 / W4 P8 l# h# C9 _* e( o) E! U. R原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 + h) t) q1 R/ T$ X( N3 E& n A# Y0 q5 \: w' r+ I/ x& W3 g, E' g+ F9 e# Q! W9 e3 ~