; ~7 U# C1 Y J4 T5 G0 M" Z! p
遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好地诠释了生物进化的自然选择过程。遗传算法也是借鉴该基本法则,通过基于种群的思想,将问题的解通过编码的方式转化为种群中的个体,并让这些个体不断地通过选择、交叉和变异算子模拟生物的进化过程,然后利用“优胜劣汰”法则选择种群中适应性较强的个体构成子种群,然后让子种群重复类似的进化过程,直到找到问题的最优解或者到达一定的进化(运算)时间。2 e* {, s. G; b5 D
. R i0 s0 ~! L* K+ G Y
Ga算法中的几个重要名词概念。6 e k2 E* H/ H
D6 C- K ~# | @个体(染色体):自然界中一个个体(染色体)代表一个生物,在GA算法中,个体(染色体)代表了具体问题的一个解。 7 ]# N3 E3 N3 D( l
7 i$ K3 e) {- }8 x: K# ?& i% o/ w1 r $ ~- Z+ Y5 D& G. k6 f4、Python代码 : Y( U) L& ]4 F- z( k3 @% W#-*- coding:utf-8 -*- . }2 r: @+ f/ | s7 Y' f # B# r. G6 X+ b2 @' c$ t5 Rimport random " }% R/ Y* l9 U* Yimport math 3 e; F1 C2 W; i0 Y$ U: \from operator import itemgetter% o, K: W' t- C, C- k
( c3 \& M& q# O5 \9 F0 U3 K$ F
class Gene: # Z ^% R; r3 {' E3 n. \% ~ ''' ( v5 ~- {2 T' { This is a class to represent individual(Gene) in GA algorithom 0 y( N* D: {. E) }1 X2 N each object of this class have two attribute: data, size( ^: b2 w, W v1 \3 o
'''8 m4 D/ D1 D8 ^+ R
def __init__(self,**data): 4 I- z/ h8 s* ^$ Y6 n( J9 b self.__dict__.update(data) 3 T/ x0 Q1 h M. k self.size = len(data['data'])#length of gene h' ?( M6 f# z4 F3 s) p6 _; P7 f- ~& A( p
' U/ ] q' R- z, {
class GA: 8 t4 f7 F. m6 W9 G9 g7 O- S ''' 6 v9 O- {7 ? J! M; M# i. _8 _. o3 u( g This is a class of GA algorithm. 4 n+ e, M3 \' S+ L6 X8 E5 t! L1 A
''' , t* `7 Q+ M* F% w: A def __init__(self,parameter):6 s, |5 o. I" L) K. Y6 v7 q( U
''' 0 y$ L8 X% J+ ?& c, } Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . / \+ {" R' V1 ^ The data structure of pop is composed of several individuals which has the form like that:9 S% }2 k+ p! V2 f# Z
, _0 I I# k2 t7 \, M$ A! c1 v8 a
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} * B4 T4 \0 v9 x' F$ b7 F Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]) k v' z; V7 X& _0 I
' B; ~* X) c. L
''': G `. U U0 Q; V! U( Q
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 4 ]5 P2 s+ z5 }1 k self.parameter = parameter3 z0 u3 l/ t" n/ T! f9 m
) m5 \- y8 ]3 Y. `/ @! k; F' K
low = self.parameter[4]7 Y3 @# O r: _. _
up = self.parameter[5]5 l7 G( w# G% q3 {! s4 d
$ M- ~6 z+ V: C, Y
self.bound = []) x3 `. |% g! Z+ P& n0 }# x
self.bound.append(low) / \4 U, P# W. ?0 F# d; B* q8 y- K self.bound.append(up) / a- J3 A: U$ p; ~: W' w3 o # N1 p5 T8 M! H3 d4 t) P pop = [] + k4 V: l% w0 q w* r' T6 V1 y for i in range(self.parameter[3]):. |1 I0 u5 u/ w% C5 G
geneinfo = []- A6 Z. A) X3 @5 Q* H: v
for pos in range(len(low)): ' S; R9 P, f0 V7 E5 f5 z, N% o( @2 o geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation 1 j: j2 b. ?1 }# e' C+ M' t" N$ ^+ L* S: @+ ?, a. F+ U
fitness = evaluate(geneinfo)#evaluate each chromosome 7 D! M2 `! p3 q9 C+ ~3 w pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness $ V- w5 d* n# s / ]4 N3 |. T0 d `$ B self.pop = pop- X0 ~4 ^1 D8 [+ _$ y
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population; ~; Q4 U$ l, n c
3 E, ~" n* D8 Z0 K! Z" b8 i def selectBest(self, pop):% i4 l$ M4 ~# v& m. n3 ]
''' ! T+ j1 \8 c1 a3 C) \9 i7 n select the best individual from pop # k" e4 {- S6 ^( a ''' - {1 b& Q6 j" t+ L s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)- s5 h: v9 j* b' ^) Z: a4 _% ]
return s_inds[0] 1 { ]( M; d3 p* x+ s& f5 g4 S ! ]- q) |8 Z* ? def selection(self, individuals, k):5 ~0 ]" r4 y, c+ F" Y$ n
'''* E2 L3 b' _) F0 H* e
select two individuals from pop # c1 D# s$ E) g0 g ''' m9 {/ g, _, @# Q6 Z$ P
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 3 i. I2 Q& o+ k! s4 D1 E sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop( `/ x7 z9 c6 N
- N( S' ~2 j9 ?
chosen = [] # y& d! G6 x% P; n for i in xrange(k): ! V* L2 S- ~6 u* K0 d, F) o9 g u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]/ V2 }' z, B( H/ g) ?: j# i( Y' [1 J
sum_ = 0 4 ]# O! e& O3 A7 ^* n for ind in s_inds:; ]& ]! [* w% O
sum_ += 1/ind['fitness']#sum up the 1/fitness - {. I/ A6 X O7 b0 f' e h2 j if sum_ > u: 0 n0 F- Y- C/ s1 J! a #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 pop7 p' k# X0 j$ x' Q- R
chosen.append(ind) & i8 [7 \5 `# N5 ^% { break/ C6 i" ]4 ~1 @4 g k* ]' \; Z) a
- q, `' ~0 l4 Y
return chosen F7 f: Y* Y9 e5 }) p4 W
. Q, O) j* _2 R. c8 g# p/ N% i
' f1 h) S2 v+ y5 \: }" }$ F def crossoperate(self, offspring):* z5 `/ p1 _4 b* ?) a, |' Y
''' 6 P% x x" o. J- i/ k cross operation 5 K4 x7 U+ f1 \$ S1 }. P* w/ Q' D ''' 5 ~8 o# q$ i5 @* {3 m dim = len(offspring[0]['Gene'].data) : {0 }5 _; E9 O1 w3 O1 ]' }. e* j6 k N
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop 5 n! V& r% M) v4 Y: ~: S. L0 Y geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop 7 k9 h. A# h% V" a% P. Z9 _+ q ! j! @0 w4 [. R+ J, F pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, # E+ e% K$ x0 \+ V" h$ I0 w7 W, S# Q
pos2 = random.randrange(1,dim) d7 A0 E0 T' [; z 0 ~& ]; [; j, ]' D newoff = Gene(data = [])#offspring produced by cross operation. r! F0 F2 g1 Z) E8 e5 i" G
temp = []3 ?" F9 j% b' e% v, N6 L! ^
for i in range(dim):5 O. P* H) Z. K D6 e- }" b
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 0 R" j- ^2 \" S, D0 |$ {$ N temp.append(geninfo2) 9 g' ^ E' E9 V #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)]3 H, C& j2 [, X! o7 N- A; ?
else: & P. p* P/ [! W( S' P7 N temp.append(geninfo1) 2 K; J6 `% o8 a( u #the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] u1 Y0 a+ W) V r n
newoff.data = temp- e6 ^7 ?* K5 ^* @( _' @
) Y1 U& r, h0 o% _0 H
return newoff6 n B6 S( d2 P, ~ K
( y' M* W; C- h