( i/ j3 Y7 v6 u$ S, S: B0 E# T# x9 W5 [( a* p$ A
4、Python代码, A" j' U6 M7 p. ~. s
#-*- coding:utf-8 -*- 0 O$ F& ^- C% R1 z7 t9 Y2 p7 x# [& Q7 o" J3 {
import random9 H9 H3 v( h4 s; P) ~6 i9 ?& S
import math& _: T- M/ S4 c8 L
from operator import itemgetter$ R$ F! _! U2 B& t
, P. J, L! @/ T' E5 kclass Gene:! W2 h/ _6 Z; W6 m
''' $ A0 Q9 x' A/ Q: J1 F1 G0 H This is a class to represent individual(Gene) in GA algorithom 2 o$ H# [: j; a, x' b( ^+ i! t each object of this class have two attribute: data, size ) U7 {; k2 M P* L+ { ''' ~6 y( I+ F @/ Y' `9 S+ l
def __init__(self,**data):3 {! f+ v4 s& J j- e6 N/ F
self.__dict__.update(data) . H; x7 S0 W# T: @% |, P
self.size = len(data['data'])#length of gene; e3 K) m h* L6 P3 r0 ^8 L
8 k( c4 z N( c0 S0 U( L
& ]& _) B4 ]0 l1 R
class GA: 1 K6 \' K3 Y& e# J3 `& a% W '''! s4 ~& ]- S1 a6 e! m# t
This is a class of GA algorithm. " t. S* _5 r F$ u
''' / u1 N# Z3 W/ ^* U# B def __init__(self,parameter): . D# V( y; g% d ''' / E1 M# }+ w0 K& w, d Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .0 ^; H6 \6 m% a* l6 t
The data structure of pop is composed of several individuals which has the form like that: + ~ p0 \- {- q. j( v" y: N 4 l1 x. V- o/ w) `% c; L5 l. C {'Gene':a object of class Gene, 'fitness': 1.02(for example)}7 i% F) m1 Q( G g
Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] 4 }& R* M( ]7 o, E! e# K$ v3 `+ f3 U. _) z- L+ a
'''% ~, p1 s- ?6 k+ h. E
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up]3 b4 ?$ {; Y* p7 U
self.parameter = parameter # ]* i7 z0 u) M 0 p2 |3 K& R. v9 k0 Y& t: w6 h; R low = self.parameter[4]; q) p7 z( s$ D/ E( Q
up = self.parameter[5] % t; Y/ k( p$ V# s/ o! A3 ^# p! F8 @
self.bound = []+ m) c5 l8 S! @2 ~
self.bound.append(low)5 }5 Y" W; T0 m+ Q5 D
self.bound.append(up) - w( B T3 h; c- d, d* }; }1 w: X( i0 F% F. l* U
pop = [] 6 }- o- p3 n8 G$ B- p for i in range(self.parameter[3]):( c4 i; b3 {% u5 E5 T: Y
geneinfo = [], ^% J* I) [$ M% i2 M+ s* _- _
for pos in range(len(low)): # ^6 k3 G1 o3 s+ a, D) ` geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ; G; {' g5 j% S9 R3 b + x* O5 w- r: c fitness = evaluate(geneinfo)#evaluate each chromosome0 ]5 ]2 K0 K$ k& t* |$ ~
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness* W/ O7 E8 w! D8 h; q) Z
, `9 F( M& Y& S {4 f } E self.pop = pop 4 g3 ]. p j: X. n* h4 t* b/ \: v self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population 0 ?3 d) l5 w+ J2 U% U0 K) p5 q: } , h+ ?7 R% ` E2 I( y def selectBest(self, pop): " n1 y# q# z2 B9 n C. H# ~5 I. ` ''': a, f& ]; R# B* U) c7 J9 @
select the best individual from pop ' l7 c' t2 S( T+ {* B ''', u( p+ c. I" B: s) Q/ j1 a
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) ' x! L/ [ t0 ~- w3 M return s_inds[0] 3 \5 T: C% {% l2 z6 S! _2 i- H3 a! H* a4 k( c; m' [" u6 v i% b+ R" [
def selection(self, individuals, k): 5 W" | Q! `0 O ''' # o. S; d! m+ E: C" q select two individuals from pop0 O7 H. ^6 n9 I, `8 B( U
'''8 n) L {' ?( z; P
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness : A; @3 }- @$ |6 ?4 l# E q2 K
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop / c. p5 a9 u5 ]- |7 Y1 {% G; f# _9 y& M1 P
chosen = []! a" c0 H# y1 F, J5 h3 z& D3 ~# j
for i in xrange(k):/ F1 G- |+ P. Q* N
u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] # O w( X' P1 i6 t. ^ sum_ = 04 j3 x3 D4 k$ u: T/ u6 z1 P
for ind in s_inds: 6 y2 n8 M; h" W) Y4 d! j sum_ += 1/ind['fitness']#sum up the 1/fitness % H0 ? e0 v1 W$ G. h D if sum_ > u: 1 k+ ] O4 f1 @8 ]$ 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% _7 `* i5 e3 y+ A i
chosen.append(ind) ! F, h7 s1 r3 E" t break! K1 k# M, y; \ q/ Y; q
6 H+ h$ [$ c Q return chosen ; B* _3 @( n/ q7 z
2 D1 [- S9 A* N/ Q6 @+ D 3 |. `0 n& |( q3 K, h* E9 H3 _: g def crossoperate(self, offspring): & R4 k0 d+ n" }# c/ A+ k ''': D! G. ?( s. ` ~
cross operation& f! [9 x3 O, ]4 U+ }
''' x3 I% U+ O6 i6 Z dim = len(offspring[0]['Gene'].data) 3 D4 k+ `) Z0 D! u; X/ K g4 O- h+ w2 u9 |( h
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop( M& p, |: u q4 z$ i3 f
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop $ @8 a* B) ^, A0 r H5 m W) V4 J+ x+ G# N2 M- T$ H- q
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, $ e s% V6 F& c
pos2 = random.randrange(1,dim) ' T3 ^& X* K' x, N9 N( J 5 P; V" ~ t& K newoff = Gene(data = [])#offspring produced by cross operation , ^) u: m. h, ~. \% R% [3 R temp = [] 4 x$ U* {2 H1 d0 d6 J1 L, }+ K8 }8 Z for i in range(dim): n& e4 C: r; A. ] if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 0 e- j& T* C6 o1 }" y+ F0 T% n temp.append(geninfo2) 6 w- W: j5 n. B0 `0 \* R #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] . @0 s1 C$ j% e else:9 u7 ]" w6 ]) c9 ]
temp.append(geninfo1)! }/ i9 m7 [8 {1 K* c0 h
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]* F7 V) Y. `3 B1 b& e
newoff.data = temp - ~; x; `8 _% O: ~" ^" s' @ G" Q; i7 D+ R" n- R8 v
return newoff ' \+ { K9 K2 ? + {) O! E3 b6 J5 o. O5 V: z, C; _& C7 q0 I: c* H
def mutation(self, crossoff, bound):8 E& D5 q* r! N$ X3 d
''' / Q2 X0 @* I) S6 }) U, M& T mutation operation9 O" n, h! j9 _4 w& [' B3 e
'''" |" K' A/ t, @# h4 m4 o2 K
* [3 L) x- H8 C6 e& h& |: K: K! M
dim = len(crossoff.data), n {0 {% [" ]- r! E
% G! d4 ]: z: s# A: }& B pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation., Q$ R, I8 _( X4 D
! [8 U* d0 v: G crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) V5 G+ M9 a( J$ `
return crossoff4 p; Z' E7 S6 J: i4 n
* K$ D+ h( j) t$ R; }8 ~" a9 r) Z% K
def GA_main(self):" `; G" @7 \3 M) W
''': H" c+ J. P! ?" h3 y
main frame work of GA + J% U% B0 g( \* Y. F1 h ''' % V$ `$ p9 h- k& D m$ F3 J# C* J+ w) H
popsize = self.parameter[3]' \3 F) M1 T3 K9 q! a
8 J, N5 s7 {+ b: l7 e print("Start of evolution"): v+ k9 z3 \0 S* l. y1 ]1 H$ @
4 |, F) m# s0 f& r
# Begin the evolution # K6 B* [* g0 ?7 a8 Z7 R for g in range(NGEN): * L, U( }' O. |- l6 B* O" v* H3 n# _( ~/ X( G7 b
print("-- Generation %i --" % g) , S2 ^# e3 ~0 O3 [/ q' ~; M- n/ ]; B4 X. c$ d
#Apply selection based on their converted fitness 0 T# n5 H6 t1 T% T# D- \; R! H w selectpop = self.selection(self.pop, popsize) 2 c5 ^" j% e3 j4 F+ @
1 s& G9 Z" P1 N; m, |8 i nextoff = [] , h* x k% p2 X6 W
while len(nextoff) != popsize: ( `" |2 F, l" f+ U3 P; i
# Apply crossover and mutation on the offspring $ T* V' y1 \" I% q2 W ; R- U! X1 e6 p! ~ # Select two individuals " k! d: x) X" X offspring = [random.choice(selectpop) for i in xrange(2)] 2 q/ g" S& H9 ? 2 A ~) m+ |7 ~8 J if random.random() < CXPB: # cross two individuals with probability CXPB8 \7 b- a3 y5 ?. s" y5 X7 `' ~
crossoff = self.crossoperate(offspring)0 k' M- @" W& s# t3 N/ ?
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals ' b s; X' @( q& C1 v* J7 z" C5 h- v8 ~; [( ^( \$ S! b. R
if random.random() < MUTPB: # mutate an individual with probability MUTPB . Q2 W4 O$ \* ~8 J muteoff = self.mutation(crossoff,self.bound) 5 f8 Z$ N, r' G0 g1 y: g @ fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals/ h0 G; @8 E/ b$ a3 \4 E9 a
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff})! B, H5 R/ q) s% ~- a4 K. v3 h$ O
3 `. m- P& ~: l( Y( M1 c7 L6 ^ # The population is entirely replaced by the offspring. C( u2 L# s2 V( E1 m. H
self.pop = nextoff ; o& V+ }1 R" G( t 0 J5 r [; q: h # Gather all the fitnesses in one list and print the stats9 D# X# j0 n4 X5 M$ D1 D
fits = [ind['fitness'] for ind in self.pop] ! b `% P m/ m + e q$ _' s. m1 |; P length = len(self.pop) , @* O g- O2 t! C3 Z6 ^0 R) P1 f mean = sum(fits) / length ' A& x9 h- C7 z& U$ @# E4 {# t sum2 = sum(x*x for x in fits)4 w) N) W. A. p
std = abs(sum2 / length - mean**2)**0.5 + J9 i& b8 I. W+ b O7 Q best_ind = self.selectBest(self.pop)6 ~0 u8 u& ~( k4 M# E9 r5 g
) O7 m5 f9 y) J$ z; {0 y
if best_ind['fitness'] < self.bestindividual['fitness']:* p* r! m" e% f2 T, ~! l3 `
self.bestindividual = best_ind! q+ u+ s- e: \- X$ ]
/ D" d! e$ A: C9 E2 w2 h% I print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])): ~. c0 A0 }$ t6 [4 L
print(" Min fitness of current pop: %s" % min(fits))" n$ A, W! U+ m" {* e2 B$ W/ M6 N% a4 l
print(" Max fitness of current pop: %s" % max(fits)) ) y( z$ _. t4 k! t$ ~ print(" Avg fitness of current pop: %s" % mean)5 B- f& Y) a) ~& ~
print(" Std of currrent pop: %s" % std)% f: c0 p4 O: W, A
- v/ X& Q* ~, }. H0 s/ p- c$ _2 T print("-- End of (successful) evolution --") 1 J, W7 t6 Q( r6 Q$ r
: _+ d4 [. ?9 O7 _, ?
if __name__ == "__main__":* a) @' V! T; M8 G. R$ ]% v
1 r- ^3 M" d* o- {: u) M3 f- P' n
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters2 E" s: B9 @/ P3 _) `; j
, d5 x6 P* x7 X; [4 | up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables - D, J1 n6 F: p4 G) K Y low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables , H; Y$ `( Q9 m' C" s+ e parameter = [CXPB, MUTPB, NGEN, popsize, low, up]* e% _, f# t) j6 ?* c6 Y! C
) ^/ t) e2 |0 E; ]5 m0 m# b! h run = GA(parameter) : r# D5 V; g0 ~1 z run.GA_main()& ^- b! i* E! T/ z3 N5 j& p' ~
————————————————. ]+ c2 {( m) L+ }7 z5 H2 q
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: z/ M4 [4 E+ K2 O) I, r. g) g* I
原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 % i+ G9 X# M a& R9 V4 o0 O) d+ o8 Y8 ^2 x( J
- B R- E9 |2 V$ M& H) Y