0 n& [8 ^- w6 ?4、Python代码 # n6 \6 a' r" j* ^8 o: ^- j+ A#-*- coding:utf-8 -*- - F1 E4 v' `. R/ {, c o* X$ o6 {9 C+ T5 @4 G9 eimport random; [6 X+ A' q% b; G* D4 R, ?# t
import math6 z$ e; _& S6 k& j! m8 i" v5 G0 C
from operator import itemgetter: r6 v! N! O v( i; [: ]* A8 y
* m# b% H" r5 \! ]' X" |
class Gene:5 ~5 X6 k$ x' D
''' 3 ~- F4 N0 B- \9 e; \ This is a class to represent individual(Gene) in GA algorithom" E! k D! J6 A$ E+ t. e, Q
each object of this class have two attribute: data, size . H2 b( c! ?5 j R) l7 q" F '''3 N0 S, C$ H/ D9 Z5 Y9 @
def __init__(self,**data): 8 l9 F% s; K. i# {) x% Y self.__dict__.update(data) ( N9 i5 Q+ _3 Y2 v0 n! N6 P9 z6 e self.size = len(data['data'])#length of gene* {- r$ D m8 W( E& {2 f3 l% v
* U9 n. \' W6 V5 I) ^9 w( i0 K' w- u/ g& q
class GA: S2 r$ K4 w2 r2 z3 M '''+ r2 O, G1 h- ~
This is a class of GA algorithm. 8 v, V/ O. D( n( t
''' % ?9 t' I% [/ y( k0 y9 v4 P1 Y, r def __init__(self,parameter):2 i. ^2 X" w! P! V/ C) b5 a
''' / E& g7 l) l/ ^! p W3 o$ U0 i Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . + @+ D4 P8 F6 T |" l `" [% M The data structure of pop is composed of several individuals which has the form like that: $ _% n; d% w, V6 W& W9 S4 K ' W& z5 u, ~1 \( ?) r7 t, O# u {'Gene':a object of class Gene, 'fitness': 1.02(for example)}$ l4 @& a, F- i& K
Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] ' Y3 b: O2 Z0 u# k" J' ?! c- d" q [3 m! @$ ]! F0 N
''' : o: U# F1 J0 p; z) n2 e4 W #parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 5 e, J% H; c* l1 p' l3 e self.parameter = parameter 5 Z* S% [$ y1 w5 B* i8 R/ U3 _! Z* `: B6 r, G1 R5 Q
low = self.parameter[4]1 H: C- d1 ?, P, m- n) n9 I, j1 t
up = self.parameter[5]; {# ]9 J6 Q+ N8 N
) M- l3 y4 {9 ^+ k+ f
self.bound = [] + N s9 u* Z7 T0 j; s% s self.bound.append(low); u* C0 P8 s o0 k7 {
self.bound.append(up)1 A c4 ?# N# C G( |
# w% V* M- a" R/ ?% _1 j* V pop = []/ T+ l! b7 |3 q% P% z1 q
for i in range(self.parameter[3]): K. P1 r# s) _( [6 q' h3 A2 K9 J
geneinfo = [] * W' Z) ^2 e, `; D* q! M for pos in range(len(low)): _; K0 N6 V2 A3 V' @
geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ! ~; p- K3 \3 [( n4 B/ a5 J9 u+ I$ q" ?4 w
fitness = evaluate(geneinfo)#evaluate each chromosome 4 s( n* Q- N( b1 K7 |& } X) ]& J- U pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness3 E2 E- j, _! D2 S
0 G+ {/ k4 F6 [2 v. I/ k3 Y self.pop = pop; U( w* k1 c$ Q/ @ F) U
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population. G% |: N a7 \8 J: W0 u
2 D4 w0 _' f2 W
def selectBest(self, pop):; N/ E7 B2 s& B
'''4 Q, @$ U. u+ p7 v- D
select the best individual from pop! p1 D% {6 d2 u7 C" M" c
'''' i) @7 L" x1 z7 N6 t
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) G% E- ^/ i7 \' _+ |9 @ return s_inds[0] : W3 U7 I( }8 t$ K ( i- D' j* Q. }; K( x# j$ U def selection(self, individuals, k):8 D+ \0 i ?! Z" X: d0 i
''' 6 K# I' g) U$ R. d& G select two individuals from pop( z! E2 }8 H* Q2 b% }2 [/ N
''' ' k5 K/ r- t+ Y+ b s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness `+ `" C7 k5 Q' `" J" f* b
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop9 O1 W. M, x9 D2 S
8 S/ g: c8 f6 |' V1 P/ h1 C
chosen = [] |' {2 i: a+ W1 ^8 X for i in xrange(k): ( E9 Z9 p3 [# n) y0 m6 N u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]9 w9 R; U" U0 j, b+ z. B
sum_ = 0! N& d4 ]& U" Y/ ^
for ind in s_inds: 8 G$ b3 ?3 o; U1 K L. X sum_ += 1/ind['fitness']#sum up the 1/fitness( D, q0 A" x+ I- _) Z5 ?
if sum_ > u:( x. `( {0 O" D
#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 : j2 t% i" M8 [' Z% ]# m d9 h chosen.append(ind) $ G7 m6 Z' g. b9 N6 x% E' q& @3 z break Z5 M' O" v" I& |& O) h
, E0 n6 x; n! h9 G return chosen 4 B: M1 |5 k1 ~' y7 q! K4 E
% ^( q2 h6 G+ A1 f# E; r
" s7 Z+ h% W. I' x/ ?
def crossoperate(self, offspring):4 P0 P& x; I/ g- _+ o1 ]9 g( z
'''2 J* O# M* U3 r8 ?+ G P! m' e4 R
cross operation 6 D7 [2 J8 V4 I0 w- P4 j ''' ; m. N; u! E: C1 c- c. `# b/ x( H dim = len(offspring[0]['Gene'].data) + o0 |' k5 ~! C( g U. p. P' v: F+ q7 M+ u
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop ! ]3 b! n% V7 Y5 n geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop% N3 C T" |( g) s' n5 s7 w
& I3 D- M9 T- f6 O: U
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, ' K7 B3 y5 I x# _4 b
pos2 = random.randrange(1,dim)) f. P6 |2 i& d4 X9 x; M
7 R3 G& @) a0 l+ p newoff = Gene(data = [])#offspring produced by cross operation & D: ~$ o( s" \; g! E1 r6 t* F temp = [] 6 N5 W1 Y8 x, N% n9 d, q for i in range(dim): 1 q! l: }; ^$ Y. T if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 5 f9 N" n( h5 ~- F' t5 T E2 t temp.append(geninfo2) v# u1 v2 W# S: \+ T0 {& ~/ t
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] 0 F# B7 D( V& ~4 ?2 V7 C else:( P- A. r9 p0 l0 p4 z
temp.append(geninfo1)/ G% b+ f- N7 g/ [4 F
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)], L" ^$ H4 c9 J( C! ~ ^8 {9 w
newoff.data = temp# I, [9 a/ r0 E' x
4 t# Z3 j! V$ C2 A* _
return newoff1 c* O, X0 @+ t' b* P6 [
, k6 e+ Y. t- S) I* W) N
7 t0 S) |& T. M& X+ z; s def mutation(self, crossoff, bound):- v3 r* d/ x1 M
''') L3 Y. X4 P. ^: s
mutation operation0 E" R" W# H7 {# e
'''+ S; }7 v2 U G h5 x
% A8 H7 v+ p+ z' p* h& i3 d dim = len(crossoff.data)) g9 `' h8 k [$ H) p8 a
* P# n! _( v: ] I1 `- [6 l pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. ' V: g3 p3 o4 b: `3 m @2 A$ w. x$ A! k* E' q& x
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) + x* c2 N% {& U, r return crossoff 7 E% N, b$ T' m3 E2 a& [& @( ^/ p5 u$ l i4 P
def GA_main(self):6 P9 V# T( X8 J0 b% q7 E1 J+ ~
'''7 X: w( l/ C+ l% K7 b3 S
main frame work of GA- ]' K7 ~8 {' ^( F" n2 f% ^, z
''' 1 ~1 c! h. d- ~: y0 Y, ?- O: J% ]+ e- J6 v
popsize = self.parameter[3]0 w& X7 b5 f7 \8 r+ p. u( Y* y
8 t% p2 w5 s# B7 i print("Start of evolution") : s1 _4 \" H& W z. e0 l+ V! }) a2 h. m3 N% p # Begin the evolution: j( B6 Q% Y5 |7 A8 n
for g in range(NGEN):0 f, b+ k k5 F! X9 f+ v+ |
1 L! K& T: J, w* r
print("-- Generation %i --" % g) # v$ E6 D0 s2 |0 b+ r) d
8 m% K/ Y# d3 ~
#Apply selection based on their converted fitness $ N& R. P: K J selectpop = self.selection(self.pop, popsize) / L* s( T9 ^ ` Z. @ # T% U Y; c K0 y' m/ I0 ~ nextoff = [] 9 y: \0 A8 |6 @% ^! X3 } while len(nextoff) != popsize: 2 I- {7 y% ?3 D/ A% f
# Apply crossover and mutation on the offspring ! d* B- J- @- F( Q) p2 P
2 q {5 v7 C- s. V8 D# d; {6 l # Select two individuals ?& A M) c5 T4 I& N offspring = [random.choice(selectpop) for i in xrange(2)]1 h6 t R% ^* |- t% ^
7 g" x# k9 u' z' j% N/ D
if random.random() < CXPB: # cross two individuals with probability CXPB ; x& z% `7 L; d3 q5 v crossoff = self.crossoperate(offspring) $ w$ c) q$ | U+ P& d fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals ' p# O& {% H* g) Y9 t3 G: M 5 _& G o. X5 `5 e6 O& h if random.random() < MUTPB: # mutate an individual with probability MUTPB, s( J3 T3 h4 @: Q
muteoff = self.mutation(crossoff,self.bound)( F6 E7 E. ~9 T/ @
fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals( c" {/ B6 D+ r' l# d8 W
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) 0 q8 p' ]- O! e, H, B$ I _. R) O+ p& g( z+ {$ {
# The population is entirely replaced by the offspring) E; m* u# I5 d; b" k8 L- d
self.pop = nextoff x1 r! z, i9 k% @3 M. ?8 m0 f! i0 z9 M3 A
# Gather all the fitnesses in one list and print the stats ! E3 d. Q Y& ~0 M7 S+ k8 ~ fits = [ind['fitness'] for ind in self.pop] _& Q% k% b* f6 \
* Y$ I$ O @0 n1 l8 g% h length = len(self.pop)) D2 z6 r( @/ k9 p* N! J# O
mean = sum(fits) / length4 n, u3 u. a/ `" g+ l4 f$ `; p
sum2 = sum(x*x for x in fits)% s' y. ?: `; N3 ~
std = abs(sum2 / length - mean**2)**0.5$ e5 d' v9 E/ m9 r
best_ind = self.selectBest(self.pop) 2 F/ t+ T+ D7 C& ` , Y+ i* ?$ K# O3 {; i* e if best_ind['fitness'] < self.bestindividual['fitness']: 7 i5 U8 |9 S/ I. l+ E self.bestindividual = best_ind8 m4 J# f$ I" a$ s6 Y* ?5 T
1 s2 H0 M; o. `. ] print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness']))/ X# P3 V5 l, e4 L3 ]# g: H: n
print(" Min fitness of current pop: %s" % min(fits))2 ~& e0 w' S% P; c3 {# x) Z9 C/ f" f
print(" Max fitness of current pop: %s" % max(fits)), i+ J+ }/ n, |, L. A' H3 q8 ?, F
print(" Avg fitness of current pop: %s" % mean)% Q2 n, C3 }6 I9 B3 X6 U! |
print(" Std of currrent pop: %s" % std)' h( F: r' _6 H( L. ^
- A6 V$ P( E: Z7 p0 Q1 o
print("-- End of (successful) evolution --") . J& T' ^- S9 B4 \2 Z/ d
; c% V: c7 |3 Z, a: {8 P) C
if __name__ == "__main__":; y; C0 v; g# h' U5 n1 l9 f8 Z& Y
" T/ }3 ~5 r0 Y9 B
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters- ^' n- \0 |, b& E
2 p x- C8 `* [8 o! v
up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables) C3 d( d7 m, V) L3 r
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables8 }. s' P: g f) {, l% x1 u$ |
parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 8 w7 h7 W6 C6 m& m: S v2 \+ }" G) X8 J
run = GA(parameter) / C. R( X- L3 Q run.GA_main() ! a- n% b' o$ {! [( c7 F1 {————————————————7 y2 v! K( ]4 J. F9 @
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 ' l1 U+ B' b7 [. y原文链接:https://blog.csdn.net/bible_reader/article/details/727826759 Y( N! m8 N* W7 J
0 \& l* i7 t2 t, Z9 t