& r4 J$ s9 Z# A: C E+ ^6 U1 D) G" y3 ?) T: z
4、Python代码# N( @3 y) y" p4 ~; j# W' i
#-*- coding:utf-8 -*-( }" v! c1 ?/ S; h+ a8 e
3 g4 y8 ~% {4 O5 \9 ?import random % m \4 k, [) n3 @" `& |import math + r, n5 s6 c$ r% q' Y- S( Sfrom operator import itemgetter( i; a \1 Z* J- g5 O- {0 D; s7 L* C) |
: Z; O4 o4 Z+ X3 P! @
class Gene:/ n% v/ k/ C8 P
'''& c' o- ~( m+ x! e; ^/ L
This is a class to represent individual(Gene) in GA algorithom* _ E% g/ o4 t' W/ Y2 i1 J
each object of this class have two attribute: data, size* g* J- b0 W9 ?! k
''' : p0 R- N) H7 K4 U a! h def __init__(self,**data): / i" @7 c; K) n" e* b/ i# y k self.__dict__.update(data) " f8 c; U. Z& ~3 r self.size = len(data['data'])#length of gene% S0 p9 u: a5 L, f
: \" Y- B. _3 c" y( J6 h
) {# \5 g; o: j+ w; H) ~class GA:$ b4 D% q. k# m/ [# N4 u
'''! n/ L3 e: e. Z9 x6 E4 J8 e2 {' X0 K
This is a class of GA algorithm. . H+ m9 q. R- ]! t1 D6 Z. o ''' 2 \5 g, i, K" f8 e8 }0 Q C def __init__(self,parameter):/ }+ G* M" G/ ~3 F; D3 p
''' ! B7 y6 ^9 |( O$ p5 d. Z6 G Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .' T% ? J2 V e8 _: F
The data structure of pop is composed of several individuals which has the form like that:! \9 R+ u' z, f7 m: t
& i* J% j4 {) B6 o, Q* h+ P0 { {'Gene':a object of class Gene, 'fitness': 1.02(for example)}# ~# G* H5 Q) Y# j
Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] - g: Z4 i# m5 B$ f - @. d% y, V, O '''3 x9 B& r4 n8 p! ^* Z9 u
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 3 P% {/ T- I% i& v" N self.parameter = parameter: s+ {- b6 |* X! y4 t
7 s, ~3 S: ]: m2 `0 e$ T. m low = self.parameter[4] ' a8 ~; o0 P$ K7 e+ Q up = self.parameter[5]0 D' H6 @7 n( Z& F; d* x c
0 T5 ]& h! l4 y% G, t7 o
self.bound = []% P, B s/ t/ Z% m. e% @
self.bound.append(low) % r ]9 |3 o% r- w( O' I self.bound.append(up)$ k- z5 i4 D6 ?. z& k& P( C
5 z! O0 r. D/ d V, w+ a- |
pop = [] $ X8 L# p: K! Q, K, R. b: r: \ for i in range(self.parameter[3]):- z8 d$ r& o$ i2 R0 B) \
geneinfo = []+ @+ u: a/ c! y3 _: u
for pos in range(len(low)): 3 t0 H' T5 c% W4 J! i6 A2 P: ? geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ; d8 {1 E- i% M O) ~- K1 m* O& d5 y' S/ n3 X$ u
fitness = evaluate(geneinfo)#evaluate each chromosome' E4 u4 ?1 L: ~
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness! n e, c. b0 A! a6 e8 V+ w
3 b; j6 ]# M! o& L: F self.pop = pop ! _9 i+ ?3 z1 A- C4 H self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population! w2 j: e/ ^" R( c! v
1 E, K% i3 \6 b8 h
def selectBest(self, pop):& r9 O- q/ c& {4 W3 i( A# R
''' ( o' c8 r% s8 r select the best individual from pop, _/ N2 g, x6 Z$ D% l0 ?6 [
'''# E" `( e0 d& l* ^
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) ' T! f9 x0 a6 g8 x5 I* ]# [ ~' N return s_inds[0] % k! O9 _8 G. w1 A* |6 O* G$ i9 @5 S4 a7 } v
def selection(self, individuals, k):2 Y2 V3 F* `" c
'''/ R& ~7 ]& Y: |! b* s# A4 F
select two individuals from pop4 ?& y- A4 l! f5 P6 m
''' , }- h" K* _: x. y6 v s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 1 M7 ^9 R; R3 c" O- a p1 E
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop9 h$ V2 ]" H |8 q1 R5 \+ G- k
! U# G) a; w2 n& S2 p( V3 F5 I# y% x chosen = []5 K5 g; k: e; g6 O7 J; A6 v1 }
for i in xrange(k):; F# n7 o, w3 q }! R: f$ o
u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] ! A" [$ P! `( c2 x( Y, e1 A sum_ = 0" c) Q' n, c B! O) s0 N+ i; d
for ind in s_inds: 4 q( E! u0 L3 ]8 w- w sum_ += 1/ind['fitness']#sum up the 1/fitness 3 \' t! M- d/ T, h2 f. p if sum_ > u: 7 i1 y) p2 l7 e r+ T; u #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 * q2 E9 S$ w! B6 ^( y! e chosen.append(ind) 3 q; v8 f& H) y! \# X4 A: Y break $ U. t0 i1 ?7 g9 C9 X! R* y/ o 3 Y/ ?+ k% r! r: o' y$ { return chosen ! w. j! a' o; t- b* J0 J 1 f# q" s* g2 o( h7 D) J( o. E% o( x% Y1 c; h
def crossoperate(self, offspring): ( b# H5 p& w. X. L: l! d! e6 {, W '''8 |1 X6 n9 h" ?+ ]
cross operation1 T" t6 G0 G2 @! E
'''& |5 l* X& G2 ~( E) n3 O
dim = len(offspring[0]['Gene'].data)6 {6 `9 f) o8 x( F" ?
- k1 T$ _# p6 B
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop% [5 c/ V( A q+ ? S* E
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop 9 ?$ f$ u! G6 K / x: v$ N. p# r: k) B: [( w0 ` pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 1 ~9 x9 ]- N+ F6 A" d" A1 k
pos2 = random.randrange(1,dim) ; J& C" K. }4 `/ n6 C4 ^5 G4 I# c h% @" X+ g
newoff = Gene(data = [])#offspring produced by cross operation& a) ^/ V' z/ n8 P
temp = []% ~0 c+ v2 R$ Z% I% s! d
for i in range(dim): 0 _6 Y7 @, {8 q: U/ K if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):0 L H/ U. h. b7 a! _
temp.append(geninfo2) : k5 L- c) [! o #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] % s7 [: _4 }" C' L& w- v else:/ u, |# ?2 y+ K; q$ \- ?! `' A# `: H
temp.append(geninfo1)' H% l+ i4 d$ Q4 d& r$ v# P
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]' o& I0 D4 O# ?% X f8 M( i: H
newoff.data = temp9 X" _9 p" a7 y( R
6 y. |" A' k7 \ }4 W
return newoff - E6 d, B) q& k; n 6 X0 P4 Y% i( O. ~ , S% @$ v/ w* m5 r. Z$ v. X def mutation(self, crossoff, bound):. y! ?3 \1 k0 a( u6 l0 g; w- l- @1 J
''' % ^2 |- n: n/ Z; Z$ ` mutation operation : v, A2 y! J. p '''. y& Z) w3 P5 U/ \: j. p
# B0 d; B: h3 y1 t" E8 j5 @
dim = len(crossoff.data) / t- G4 E! O; K" ]7 a1 V6 |5 o, K' S7 T2 G: Q
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. ) `' F' u# O6 V- z" q& {% f 7 v4 j0 y, a' T9 @) l9 S crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) 8 F4 O$ q3 D/ ^/ U; R; R [6 T return crossoff+ s! W/ y& E/ C6 j
7 Z* F" M' T& _& Z
def GA_main(self): 2 C3 r% T4 P2 a9 Y; G" J7 f5 { ''' 9 [& s) s5 v& p! | main frame work of GA ' y5 E8 T. }1 U- p% c; n ''' / J( t: V% Q9 [- e8 H6 @' M3 e1 e) g/ B' P' x9 z9 Y( c& R
popsize = self.parameter[3] $ t: ?. b- K& F6 J* D 6 B. j# i; r3 j W M# B9 K print("Start of evolution") + y; _$ w* x. c5 J$ Y4 J) `0 f( v- K6 U
# Begin the evolution q: L) S8 X; [5 v! g( k8 v
for g in range(NGEN): ) W) I+ o6 K" q) X4 g ( D6 i( x9 h8 M2 g! H5 Y' U* [, U print("-- Generation %i --" % g) ! A0 a; i/ n0 s, [: z. Z* w; ~# N% ~* k
#Apply selection based on their converted fitness - |) A, I& E' q* d selectpop = self.selection(self.pop, popsize) ( O8 ?& `. X5 I6 W5 A# Z9 k/ F) o, f$ E* P; J% c5 u
nextoff = [] # _. V: o- k5 r ~' ^# W! V0 l6 @; t while len(nextoff) != popsize: / C8 x5 D$ b( b# M( X
# Apply crossover and mutation on the offspring ' B6 r. \2 ]' w8 j* j$ X' E: ^ H
# Select two individuals5 g8 N* t% m, u3 i$ {
offspring = [random.choice(selectpop) for i in xrange(2)]% O; i+ ^5 L% `# d. [
7 l$ l3 z4 o! L1 o( e: K5 ? if random.random() < CXPB: # cross two individuals with probability CXPB ) k+ A( Y( l8 S crossoff = self.crossoperate(offspring) 3 s- |2 Y. r$ H9 Z" H$ | fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals % X- x/ B5 V# O
) h7 u( o2 W: E+ {
if random.random() < MUTPB: # mutate an individual with probability MUTPB* w: j. N$ q3 k
muteoff = self.mutation(crossoff,self.bound), F& A. w5 l8 T. C, o3 h T
fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals $ t4 M; h9 T$ J7 T nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}). Y8 I) q0 V2 V9 N# C. q
7 b# s; }3 L1 |4 Y # The population is entirely replaced by the offspring1 |$ j4 N9 ]4 C% \
self.pop = nextoff # @/ U) k0 f- J7 P1 q 5 O- R, a6 h) { # Gather all the fitnesses in one list and print the stats 6 _) k. w2 h( e1 y8 Q fits = [ind['fitness'] for ind in self.pop]* M0 r5 f* ]( Q! K$ ?/ T+ B; J
5 [4 i9 D* S, U7 e5 ~( ?' [+ [ length = len(self.pop), J' @/ T/ M: l2 Z' p
mean = sum(fits) / length4 u0 D4 a! p. q- ?4 f
sum2 = sum(x*x for x in fits). p2 t( [2 R! b4 V+ X, I, M; _
std = abs(sum2 / length - mean**2)**0.5 & I4 k7 @4 `$ |2 \6 X4 Y) } best_ind = self.selectBest(self.pop) % O" j2 b, v1 c& p- K 9 j# D# ?: U# T7 s& @( E- X& N: ` if best_ind['fitness'] < self.bestindividual['fitness']: 2 ~9 s: v- D1 y+ E5 Q/ @ self.bestindividual = best_ind 0 @3 k$ L7 o9 W$ z M! B) o( ^ {- A7 f7 m5 M2 G
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness']))/ i. [9 @& R" f
print(" Min fitness of current pop: %s" % min(fits)) 9 _1 x1 B' F( t' D- f print(" Max fitness of current pop: %s" % max(fits))! d) u/ n; P. J* u3 Y# V4 _7 v
print(" Avg fitness of current pop: %s" % mean). m$ Z+ X1 t ~! Y! g
print(" Std of currrent pop: %s" % std) 3 a, y2 S2 E' ^! {8 Y1 z5 r% v/ s2 ^( G# h( Y' E7 P* Y$ N2 d- A( E+ H
print("-- End of (successful) evolution --") ) {. N2 n, ?# I
2 s S& w2 q1 m; j% F# \* yif __name__ == "__main__": + p) |, f# {3 Y1 `- Y$ M9 l" [1 N# E4 v' T5 |0 m# X# y
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters ) p) V$ T# w# f7 b# c' }$ x ; E9 @' k, k8 y4 D6 C up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables& B& z V# b: u! m6 P8 b9 a) i
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables- f6 _* }2 S: \
parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 9 _9 ~* z9 t1 \9 X5 j @! r" U' ]2 R1 p+ I
run = GA(parameter) ) W, U: D6 Z: ?$ o2 K run.GA_main() $ X1 @) `1 l7 i% _———————————————— 0 [+ ~7 B' ?! E2 H版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 4 m5 Z4 P% B( [* |原文链接:https://blog.csdn.net/bible_reader/article/details/727826756 c% N; T) ^ x* N% b