7 {2 {: Z5 J) x" v1 A3 w2 g0 n pop = [] 6 Q8 y9 z+ R$ e4 O* L- M0 g# \; _% u5 E for i in range(self.parameter[3]): ; V. m( n* k5 p geneinfo = [] + M5 v: t4 [( b for pos in range(len(low)): ' u+ Z& \# T' t( K5 C3 B, g3 k geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation 7 k; Y3 B1 y2 N! y( g7 v/ U* a( G3 S+ A4 [
fitness = evaluate(geneinfo)#evaluate each chromosome, V1 g$ I; m) ?# Z! ~
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness $ e7 R6 G( F# } X- ~3 w! a* k8 u( ?) ?. s% P% n# Y z/ m& o
self.pop = pop 1 g/ Q3 G( I6 } self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population/ B" o; L& G& }+ V2 c
8 K4 S8 t o [% J' x# C
def selectBest(self, pop): : N0 y1 x; G# ? '''5 e$ ?+ h- l* ?8 E2 w8 y- L
select the best individual from pop" q0 `" M, Q! X" d( \* }
''' 9 `4 ]2 n' E( e" R% Y( e; j) _ s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) : {) }7 \; ~) d# @* K3 \3 s( J return s_inds[0] 0 s2 X5 }, Z1 U& l/ M3 o" g9 [2 L- k) T* A) }- W
def selection(self, individuals, k):$ w y# Z/ N: ~0 E
''' 2 r' s# k/ W3 r- V, M6 w9 ? select two individuals from pop1 d3 {2 V: G! r) O7 C7 m
''' / ?- d! i7 s1 @3 k6 v s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness ; n% T6 d8 N0 M7 p$ i
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop 2 b1 _+ y ^6 o+ ~# o3 K' p5 m1 u) s% [! N
chosen = [] , e/ g, v8 q" R. h0 h for i in xrange(k):6 H+ _6 C" P: K' k
u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]- P% a$ P6 L! i/ j# e1 w
sum_ = 0 3 A* w+ Z( R5 M! R7 O, Z for ind in s_inds: * M2 r5 }, i0 R6 ?& F- ^$ o sum_ += 1/ind['fitness']#sum up the 1/fitness 9 `4 F, @+ j( z) [ if sum_ > u: " X3 L9 e! \6 T4 C* ]" B) _ #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; m& S3 F4 t2 W5 n
chosen.append(ind)* t/ D F' z. ]3 D+ Q; B( l' K0 c
break4 o$ d. r% }4 m& Q
* G( F$ P% J8 O
return chosen 2 p& k7 p w, A' Z- Y. ~9 C- A. g2 {8 _6 H l
# _( ^. W# b/ Z! u
def crossoperate(self, offspring):6 H5 R! j6 c4 ^' ^( X
''' - u9 X e; u: Y$ W9 M% m" ` cross operation 6 S+ y) _ _, i4 Z# j7 d: |' h ''' 4 P$ R* Y3 g# z7 u& O9 o dim = len(offspring[0]['Gene'].data) ( M1 \& G# Q7 l" j5 G, L; p+ m % y& x8 J" V2 V& |( z& c( Y geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop ; _; l, d- Y, E& q geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop( f0 K% L( J- L! d. Q
8 G3 w) j( }$ {$ A( L pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 4 _* }/ t' f( b5 @ pos2 = random.randrange(1,dim) + b1 C* T6 E+ N7 w3 y1 y3 X3 V0 ]1 n- l1 h6 y) [0 h) u/ X, w
newoff = Gene(data = [])#offspring produced by cross operation2 ~& j5 C. e7 o+ ^
temp = [] E3 C# o$ @# n3 ?8 x for i in range(dim):1 W4 l8 d7 P( b! a& X- u7 J
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):" c( j! f/ q) @9 X8 l# l4 G8 x
temp.append(geninfo2) 3 I3 U7 ~$ u6 G #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] . D, M: e2 R' F0 d2 j! a else: 0 G$ w( f. }- M; O temp.append(geninfo1)6 M7 y1 n; z7 A0 S5 }# a" U
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]; i4 }: ~+ A2 ]6 Z, O
newoff.data = temp5 U) c; v4 q+ Z! N9 G
4 [/ z4 ^# a1 @4 Q; N0 s/ C% J9 v5 V& [
def mutation(self, crossoff, bound): / _+ b3 ^# _5 Q. w1 o '''* M2 t* z. x5 H6 z$ _+ }! p. T
mutation operation; M! H* J) q* `* Z# ^0 G, z
''' m: M1 \, A" A' z) @. Z' Q8 d& ?" G
dim = len(crossoff.data) 2 O' g4 h: r& R* b' n3 `( j% g1 G1 M# J3 j( t. e
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation.. f. o! A; m6 k {, X
. f1 x L" o+ J3 z* Q/ O5 ^: x& e
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])% j8 v# N, l; K4 R2 R
return crossoff ; r4 O; c1 y: P8 U : u4 Y: M6 n: T# F: B+ D6 e, O def GA_main(self): ) b4 P. B. L. i( ~ '''% }$ t* `& Z* s3 Y. b
main frame work of GA3 U+ B/ v0 U5 |4 V
'''/ ^* i6 t& N, S
0 G& R8 t- y d
popsize = self.parameter[3] 7 Z( l5 |% K5 _% P$ b& c% _" w + v( K$ f. N6 q4 C: y print("Start of evolution") - a3 f$ Y, d8 A& d% c6 _. r $ b5 j3 ?" M" R: l3 W% E1 Q # Begin the evolution a7 N1 K" u! I0 d% E
for g in range(NGEN): , {# [0 [3 I+ q3 \3 m( F$ X5 q( C* T9 V2 R3 o }5 _, L
print("-- Generation %i --" % g) ) |5 j0 C- D5 S. s8 ?( F
8 {6 u2 l5 |: f: v6 K: ` #Apply selection based on their converted fitness8 D6 S$ J+ N; K' O K9 l# |
selectpop = self.selection(self.pop, popsize) * P& s: K5 O2 X9 G6 j4 S) V
% c; I2 H9 |7 y( u nextoff = [] ! O5 D# B1 e" |% ?4 d while len(nextoff) != popsize: 2 t. E, c1 y Q+ E$ d9 r; h # Apply crossover and mutation on the offspring & m& }/ w3 F9 M 2 x* S5 C4 [. g$ Q' R # Select two individuals 3 A- V# ?. S; a% Z: i offspring = [random.choice(selectpop) for i in xrange(2)] ! v1 q0 J* L3 Q& q4 k : e* q5 u( ^9 X1 [" G; H if random.random() < CXPB: # cross two individuals with probability CXPB 0 Q% A: M3 [# A crossoff = self.crossoperate(offspring): m$ @! U. \) q) I& d
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals ) A" l& K% @* R. ~4 }9 e+ ` $ Y* i6 `# ]' ~ if random.random() < MUTPB: # mutate an individual with probability MUTPB ; ~& W1 J+ u3 r6 \1 J) Q& z muteoff = self.mutation(crossoff,self.bound) # i$ q3 q- N% P: M fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals % {+ G Q& Z. ?/ ]" r0 p w nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) * \8 L+ T( C' i u. n5 p, O7 C P 9 W/ z6 u6 K: k5 O: n7 P # The population is entirely replaced by the offspring0 d. Y3 J& b# {0 L" J" U
self.pop = nextoff $ S2 k; K8 m: s8 ^: [ # q/ C6 M" e* f3 ~/ P W- B+ w # Gather all the fitnesses in one list and print the stats ; Y! D3 O( \0 B% b. @0 J fits = [ind['fitness'] for ind in self.pop]) [3 ^' [- J2 [, b
& Z G, y! C8 l# n2 X! ` length = len(self.pop)/ v+ G- A# h' h5 C
mean = sum(fits) / length* B7 `& R" _+ w/ x
sum2 = sum(x*x for x in fits)# R/ M$ \3 ]' G% H$ w% L, ?
std = abs(sum2 / length - mean**2)**0.5$ {/ ^1 b6 ~9 M5 A
best_ind = self.selectBest(self.pop); p, i$ B1 b* U+ x+ F" I2 [