4 @3 w3 J+ X0 H9 n, S3 x$ I6 Q, O6 b
4、Python代码 + t' e2 t6 R7 [' ^" y#-*- coding:utf-8 -*-9 a5 Z% T7 ^) ~, x% s$ A
* R6 h) z( n; I; h; H2 H4 N
import random; O' d; h. H% y( N2 t8 c9 X/ Z3 m
import math * T8 F" d# H; q& a) x: F* u; ^+ Rfrom operator import itemgetter * y9 u4 r- s$ f$ S; r; }: |! R; d4 l' H4 ]7 b3 r. ^
class Gene:, z7 T% a+ f+ F$ l) t. a
''': c5 n: [' j) Q. c" N3 c
This is a class to represent individual(Gene) in GA algorithom $ d! o- I/ ^5 B- d( \$ a each object of this class have two attribute: data, size2 ]1 s0 Q7 o9 b. n& }9 ^
'''+ p, ~2 K! n1 D9 ]" R
def __init__(self,**data):& I# w7 {+ R6 _8 G
self.__dict__.update(data) 5 r) ]8 F5 n( w6 l6 s0 x7 z
self.size = len(data['data'])#length of gene 9 _6 W7 `/ t% P2 Z2 I c m/ n$ K2 p, M& c$ V
7 F( [+ c' Y7 W$ [ \+ nclass GA: * j1 \* H) x; G& f '''; a: O$ I- i/ a' h4 ^
This is a class of GA algorithm. 2 N% i( s' l$ t$ s% m$ E8 ` Y7 ^
''' 4 ?$ m. r* m" u9 v. N def __init__(self,parameter):2 Z- H$ d: U T" D4 l' }
''' * c9 w' D n+ u$ k: o Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . % d3 o& L" P7 @9 `- d3 P. F/ C, b4 q The data structure of pop is composed of several individuals which has the form like that:0 d/ \/ f/ D* `9 t) f
$ Q; V2 ]& Q: }* Z: G {'Gene':a object of class Gene, 'fitness': 1.02(for example)} % r! C- a" n4 F. N3 C Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] 3 ~) _0 J+ A( X( ~" m5 r/ r& E& x: D- f6 Y, t! }! f
'''2 W( K9 E8 f6 h# z
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up]. U0 ]- C# o, N0 C F4 n' f
self.parameter = parameter 5 F& [! ^& v- `5 m9 a, l0 y: ~* w; q) P; P/ s
low = self.parameter[4] 2 ?# s" L; ~& v% @ w* l5 E2 ] up = self.parameter[5] * n( O9 |0 O5 h ( x) {" y6 N0 K F5 R self.bound = [] 4 @0 @% U$ L u* ]* a/ q0 G self.bound.append(low) - C) V& p( n v self.bound.append(up); p4 p8 B# H& Y
' v7 K# y9 G% O+ S0 V pop = []1 H" w6 L# x1 R/ w) ~% ^3 u
for i in range(self.parameter[3]):( T+ K6 a" e4 Q7 Z/ m- I' E* T
geneinfo = [] 3 U% k8 K# j6 @5 e for pos in range(len(low)): 0 ~% r( f# R8 {& h geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation8 [( w9 L$ \' A
1 s z/ J$ t% Z& p. W3 [
fitness = evaluate(geneinfo)#evaluate each chromosome ~3 m# l9 C7 X4 w) ^8 S
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness) v2 _/ ^, e% j% I6 X1 w+ r6 I" S2 o
3 }; I/ X Y+ [" h! a0 C& N
self.pop = pop ( ~7 l t* o7 }$ R1 { self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population ; L+ _" y: H/ Y: c n9 P - r- r" |3 K+ q. O: u def selectBest(self, pop): r% L6 X; @ ?; c# n '''$ ^. s/ L k/ T
select the best individual from pop T/ j8 x* K1 I& O6 h2 S7 m
'''# h. J* P/ R$ z, v
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)" r! r. c/ C+ G- j4 s
return s_inds[0] 2 y- a9 f0 r( q4 `' v2 t$ Z3 A' u% J# H6 L K
def selection(self, individuals, k): , ^+ _7 [, e5 P. F) R, S, G& _% o. t ''' ( e1 M+ S# k+ t4 L; @ select two individuals from pop1 T6 [1 \+ l! S( u
''' 0 E3 I/ O) m0 H- \, r6 D. e2 @& } s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness , X8 n4 Z4 [- T" Q) _ U+ ^ sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop7 Q7 C o+ H. a
$ m$ }, ]# V/ |) s( R3 R" P, N0 V
chosen = []# K: U+ w5 C' _, @9 C
for i in xrange(k): & u" H) t# Z W0 i( b/ r u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]: S' b* X! ~3 W$ |/ r* h2 ?
sum_ = 0! }& A5 _8 B3 S( c i! S
for ind in s_inds: 4 i( {7 ?/ r& l. ~* L- | sum_ += 1/ind['fitness']#sum up the 1/fitness ( U: b7 v$ }8 m* z: @# C/ X j if sum_ > u: 8 o0 h. ]( S1 }' u) L4 \" ^ #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 1 d( n! \5 K9 g3 X; ?) I chosen.append(ind)2 \! H1 L/ E V6 V! I0 k: h
break + M; h, O( z$ u: a, S1 @ 8 m/ Y O0 E5 e2 d% h, ^, X return chosen : _1 K" u. R: _/ ~3 e) |- g. V3 t& p7 Q+ ~' X/ s& l A( ~4 u# J
7 [( P5 ?% i9 `' Y3 x6 U: U def crossoperate(self, offspring): . U5 }5 Z M$ g3 ^2 O2 Z9 ` '''$ J8 J2 p+ [2 ~
cross operation B3 m. e0 J: {" [1 y
'''- m f# X0 c8 S% {6 [0 i8 ^0 K
dim = len(offspring[0]['Gene'].data), m7 M9 i8 ~8 L7 r) V' J, g5 A/ A' u
* b6 M- |, A. n$ v# T; f" |5 } geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop) x# O/ \& O; G5 C; T- l
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop ! d5 g& @* W; E" e& k4 f% x0 d' ~* _" O4 J9 O- p# C- z
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, * k0 i$ p$ T+ a) E/ H. H
pos2 = random.randrange(1,dim)9 C" U1 Y3 W' Y; f# @3 F
0 p9 X/ N3 c( z* W W4 ]2 r' \- p newoff = Gene(data = [])#offspring produced by cross operation 9 Z. |) [$ O) \ temp = [] N Q$ `; b/ b4 n5 m: ~, O for i in range(dim):- l5 D7 l' x4 y) B: E
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):; z* X0 f; U. B+ l; @! E+ p7 B. L
temp.append(geninfo2) ; \$ u$ E' U( F& b #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] 6 a1 o! C& h' i4 X' K: O# ? T) z0 H else: / ~5 e* p& _6 Y3 ?7 F- ? temp.append(geninfo1). @: C7 ?/ ]4 @& x/ x" }5 y
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]# E3 n9 |4 I4 c, ]4 A
newoff.data = temp- |) \4 W, o+ {' F4 Q
) @0 R, }9 Q) l; ^4 E return newoff & L5 a' f! o9 a' U% ^$ P2 S; n4 F! D. f! w( \' L- c4 x
$ B) g0 i' O2 x! t def mutation(self, crossoff, bound):, T( |: }( Z7 P+ w# o: @
''' - {1 A7 c# w# F& p& r# q$ T mutation operation1 @% V! y" C' P
''' ( V% L2 }/ Z* n2 `. u 8 _3 D/ | P% @* X dim = len(crossoff.data) - G6 F) N0 G. ?7 }$ X/ Z1 t$ K9 ?, }/ D" z9 {2 V' ~$ s$ D `6 Z o8 t
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. v1 Q" y" \' \9 d3 h6 b1 V+ k7 o
& a. J e. I$ L
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])7 j. \) Y6 G; @$ p; \
return crossoff & i/ a) `. i/ q6 t6 ^ F7 u! k# d7 {* y- \' S2 ^. M/ R; p+ b
def GA_main(self): * b0 R+ G% ]% k! E/ } ''' 3 L, W6 Z3 c- H/ M# ~1 b main frame work of GA1 }. ?1 {0 g! j& Y: m& Y( P
''' * H" Y" q- {7 F. m. }! M* x ) x, T4 c/ m: t$ C% _ T popsize = self.parameter[3] # ^; J' U( g1 d1 Y* w3 J# ^+ e+ P8 x 0 T o+ u* m6 V E) w print("Start of evolution")# L {5 q- C9 R
/ y8 T& E) h7 S2 r5 I # Begin the evolution; A4 j0 M+ _1 K4 a. _6 H
for g in range(NGEN):. t8 j7 t1 H+ x/ ~3 R2 O, V