: K* c) M5 A1 \4、Python代码 % q7 q5 ?3 i7 F: K#-*- coding:utf-8 -*- ' k* N, x# `9 @7 b- x9 x9 p: S( K% y, p
import random ( q, a. B/ R" i% {, dimport math4 Z7 m$ z% ]1 {, t9 h
from operator import itemgetter " {' ^* N- J1 f# j 1 c, t0 m: h" ^3 N/ qclass Gene:, I" f. `) `5 S$ T! T
'''$ e; y8 J k) |( R7 j3 ~ e, N
This is a class to represent individual(Gene) in GA algorithom ( q; c R* P- B4 O each object of this class have two attribute: data, size2 \* W: s+ e" a, v& b; ~+ k
'''4 b0 \5 V; n" u. g: I. `# @
def __init__(self,**data):/ p2 h( z- X; ~+ `% `" Z7 m) M0 I
self.__dict__.update(data) 4 W, {8 A2 Q& \) V! K* l+ o; s; a self.size = len(data['data'])#length of gene( x9 _$ F1 j" C/ ?" T! \
7 H1 P% m( k' W) N! L& v6 X, c# ^
class GA: 9 L2 ~; `! m8 w1 e ''' ! k E1 h2 N( M) i' t9 h This is a class of GA algorithm. - Y7 U0 Y% Q8 ^2 c ''' 6 f2 ~7 g1 n5 ~( G def __init__(self,parameter):# R. x! Z l6 M6 C# \; A0 f1 O+ o ]
''' 0 C; S! a8 ~$ U Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . . X, U8 O/ r+ J The data structure of pop is composed of several individuals which has the form like that: 9 T/ P* E+ c" X6 W# P, m K- p8 A. f& p& j
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} 1 |# B; _" X2 S Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] , l& S" E$ r q2 S5 c6 e ; F" A: O& S( t" W5 \1 W, ~ ''' ( W) l2 U0 K# i& d8 Q #parameter = [CXPB, MUTPB, NGEN, popsize, low, up] " T7 a, R/ ^0 q self.parameter = parameter5 p4 f! b2 C& V! Z' A, S
& c' S& w+ C1 X. [' u low = self.parameter[4] 6 ~/ @! N" R" H0 `& @ up = self.parameter[5] , G' B# o4 @# j h% r6 p5 Q6 m # Q- C7 v, N! W8 M1 Y self.bound = []$ K8 [& \1 a: H! v
self.bound.append(low)6 I! X c _6 l4 |& n& ?
self.bound.append(up)* N2 F$ I+ b, ]* d: S' Z$ s* S
+ Z; f- P! T; Q- N
pop = [] ( Y3 V/ ~& N2 n1 J% q for i in range(self.parameter[3]): / h8 g5 J. i( j8 z7 W! C% r1 m4 s$ d: p geneinfo = []" x0 N6 L) p' L ^2 q7 `
for pos in range(len(low)): ) ~; e! ?1 X' G2 _2 `4 u3 A geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ( |2 e2 S( l H. z8 g7 j: ]0 t' s- d) J, X
fitness = evaluate(geneinfo)#evaluate each chromosome, p, u7 V# {( @) n* A ~
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness! _' L$ \$ Z: f3 u! A: z4 R
! z3 I8 B: d/ U" N
self.pop = pop : _( e% q$ ~! a! P9 b! I self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population- @1 h' g9 N' ]9 ]( u9 m5 |" v
- a7 f: t8 P5 N* x def selectBest(self, pop):+ h/ n4 G# G) I+ l$ E1 f& C
'''& w$ X8 v" `; n7 b
select the best individual from pop# a# v: f" u8 c# J# w3 B# b' G
'''" Y! a- v$ _" Z7 C! _3 G
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) 8 M4 n" f' j* u" _$ l return s_inds[0]0 ^' e* A& G! U; X# v
0 u& Q. M J" q8 M
def selection(self, individuals, k): : B+ t+ R: f" C; N4 ] '''/ M3 a& U2 n2 P
select two individuals from pop 2 F7 H5 H s$ ?4 E; Q# ? '''4 t8 H; s/ N2 `2 t/ r) y% l' ?) L( d
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 1 I# x" S R: C5 Q
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop - V$ z3 q0 V) v0 b8 j8 G3 Z% z , `* T9 k. s/ ]2 \ M chosen = []$ I0 v4 i( X" c( E7 u! W2 F% m
for i in xrange(k):5 m% b- y+ e4 S/ C$ i9 W: @
u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] ) r3 M" P* r" P$ L6 Z! _( ~6 @ sum_ = 04 ^; H! Y. z: Q- X9 V4 v0 b
for ind in s_inds: 5 w3 o" K4 |. {0 X% O5 T: _ sum_ += 1/ind['fitness']#sum up the 1/fitness5 q+ C) b; |, \; O* ?, s
if sum_ > u:3 L x; Q. z$ {8 b- Y
#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/ N; ~7 D! T6 H# ~
chosen.append(ind) ' p9 N& Z6 E1 c( I r9 z break 9 m$ l2 E9 j1 w5 I7 B8 m5 @ 5 ]# ~4 |5 h% l1 ~' s7 \( \ return chosen 1 y" s& ]/ Z7 [" k" U9 Y+ m* {' N8 `
! n2 \! d) p z: C, t def crossoperate(self, offspring):3 T; q6 L P' ?
''' _ o: Z9 l, w( P @ cross operation- Z1 H" a1 f9 f
''' ! _( |! t x( Z: C a7 } dim = len(offspring[0]['Gene'].data) 1 m* W4 B1 g1 a1 Z+ Z& W. @; x6 h6 l0 m6 b& N7 X1 j. C( |5 {
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop . {; j# ^" E' t- E7 B7 W& b geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop ) A+ @% x# C. S- u, g; I% r0 _) {, t3 E( g6 q" z
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, / [) z: I$ ^. q7 l, ~" x; Q
pos2 = random.randrange(1,dim)9 O0 i1 t A8 _) p
a) b$ p; v' z2 w3 a; c( N* m newoff = Gene(data = [])#offspring produced by cross operation8 ~5 }6 A/ K8 m1 ?0 Y
temp = [] 8 W5 z( Z# P: Z& {1 d ] for i in range(dim):. S3 ?* `: q' H* M
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 2 A% F& I; z2 y6 e( w8 n! ] temp.append(geninfo2) 4 V- g- @" F- v( s/ t: ~ Z% J #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] - p! {6 Z* R! I* s' @0 C else: $ ?+ x3 ?& z# q. {6 [9 Z2 Q temp.append(geninfo1)" J# T! B: F. _% X8 U
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]( q% S* ?+ \3 c; ~5 E- t
newoff.data = temp ( G% j% e# n) I+ h9 `* _ # [4 Z- f% k) S1 E2 j return newoff9 @" y! Q4 o) G
; f: I O0 o1 t& ~8 d
8 u$ l) o$ V& V dim = len(crossoff.data) 0 Q" r& d- H, J6 z$ l - a. b! u+ l7 c% X pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. J3 m7 M- H- t0 Z. I. y
' x% A, _; V" C/ | crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) ; h9 g9 w2 N# M, U$ W. J return crossoff ; O5 D/ l5 A. x0 ~& }' O: o8 \: `, F3 E
def GA_main(self): / r% t# ?* _) Q5 q/ Z9 I9 v ''' 8 r$ E: |0 G4 ~ main frame work of GA ) c- |; _' X3 s+ I, h ''' 1 n" W( E p4 O4 B ; k% _% J/ y- W popsize = self.parameter[3] 5 ^- q, ?: O' H0 k2 \: v 3 f5 E5 w0 c/ _' Y+ p) ?# w print("Start of evolution")2 ^0 c) z0 O4 @# W* a8 j" F/ I& R
7 s" B! h3 z5 T( I4 z1 q # Begin the evolution8 ~5 V+ A0 G' s% _; w
for g in range(NGEN):) {$ }6 ]7 V, h7 ?- K
7 ~5 z4 D( i- v" k6 n9 ]8 a1 A #Apply selection based on their converted fitness n2 i, ~& w: F$ k# I' m+ V9 R
selectpop = self.selection(self.pop, popsize) ) P: D. Z) x# y3 c
7 v, z/ i4 U# p6 s% }8 I2 a nextoff = [] 4 X* L/ q9 ]3 z8 a while len(nextoff) != popsize: # c% ?. ~; G6 o6 l% ^0 i3 q; l* ? # Apply crossover and mutation on the offspring . L: r8 a c2 y" @
8 _% P' l7 l! Y3 S& o) X0 [- z
# Select two individuals( B0 W$ g2 s( B: ?. X
offspring = [random.choice(selectpop) for i in xrange(2)]$ v' v* C' B+ P2 W* J" R( ^
/ u, r. B0 w9 M7 Z if random.random() < CXPB: # cross two individuals with probability CXPB 1 A7 a- f$ A) I/ N) G crossoff = self.crossoperate(offspring)* d+ G5 c+ m5 v0 y, u
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals " j7 h {( i5 O) k0 _5 u4 a! c " D+ O5 H4 N- X5 }3 `! ^. Q- q, ] if random.random() < MUTPB: # mutate an individual with probability MUTPB ( Y$ ] V: {6 j/ j& c0 M) `. k; [ muteoff = self.mutation(crossoff,self.bound) ( C1 Y; ]& A2 ?& M- x fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals / |7 z% F5 K; D% r) ?/ J- E* | nextoff.append({'Gene':muteoff,'fitness':fit_muteoff})( u/ t/ L5 r' q) q7 R3 f
: W4 p5 N$ P6 K% C6 ^
# The population is entirely replaced by the offspring ( h0 v0 O0 ]9 i }/ N- Z( f self.pop = nextoff! t3 ^6 G! \# Y; o8 e5 T" G$ ~1 }
5 M" k9 O' i& S1 @) I% y! t2 J
# Gather all the fitnesses in one list and print the stats $ q& g/ g$ ?; j( S fits = [ind['fitness'] for ind in self.pop]) F, g8 j& }. D/ f8 A; H
$ g0 u$ o" e$ m$ W2 Y
length = len(self.pop) 9 O& J% \! X0 j$ b( p9 Z mean = sum(fits) / length) W7 S- {4 |, K, j
sum2 = sum(x*x for x in fits)0 q5 x9 O! ~ q- g8 ~4 i+ _# S* _+ N
std = abs(sum2 / length - mean**2)**0.5! f; H/ y6 G A x' l
best_ind = self.selectBest(self.pop)7 a' H, J% A) |' M( d
: `) c1 s W1 K' B4 `( z8 k if best_ind['fitness'] < self.bestindividual['fitness']:: \# n) v( u# P) f7 U
self.bestindividual = best_ind ; o7 j( S5 u' C* B x) G% s+ r2 Z& b) F3 E
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) 6 E2 ?2 l- O2 T# j g C5 m4 b print(" Min fitness of current pop: %s" % min(fits))' ^* Y6 ^8 Q+ J; q9 J! D0 R/ y. K1 T: C
print(" Max fitness of current pop: %s" % max(fits))$ h u" {' B, D3 b/ I) \# x+ e" I
print(" Avg fitness of current pop: %s" % mean)6 Q# w: C2 A9 r$ y$ f m
print(" Std of currrent pop: %s" % std) $ @, c6 Z9 C# @9 u% ^7 z5 A N- u5 s
print("-- End of (successful) evolution --") : {* y! ]; H, y
6 J) T: L- n/ O% E) }. R; }
if __name__ == "__main__":7 B0 w" f9 ?5 Y5 O+ _% g6 p
$ `- H* u6 h! v9 S! w( f
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters 9 x1 C% g; r1 J8 h; P: `* O2 Q % G' T$ f; k( u; l up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables" G) H* d/ d0 o/ c. N# M+ N& [3 p$ B0 W
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables& j+ k2 `: S$ {+ K. Y6 g! _, H
parameter = [CXPB, MUTPB, NGEN, popsize, low, up] % }& X7 a5 d! N3 } 4 ]; j5 x/ M' Z" A run = GA(parameter) ! `! x# Q- h8 p& r/ m run.GA_main() " [( @: h8 j. x; Q————————————————1 S2 I! O8 u: [) n) I) Y5 q1 }
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: i; L# j! ?: z3 x7 \5 J
原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 5 Q7 x2 P: J" E3 }8 C* X$ h# Y* [: Z' n- U& {: I