1 K% |8 S: l* q9 k( l' ~
遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好地诠释了生物进化的自然选择过程。遗传算法也是借鉴该基本法则,通过基于种群的思想,将问题的解通过编码的方式转化为种群中的个体,并让这些个体不断地通过选择、交叉和变异算子模拟生物的进化过程,然后利用“优胜劣汰”法则选择种群中适应性较强的个体构成子种群,然后让子种群重复类似的进化过程,直到找到问题的最优解或者到达一定的进化(运算)时间。2 Y, d: C) L; r
9 a, r% W5 A' S4 rGa算法中的几个重要名词概念。 6 r5 v1 x5 }8 r6 v# ?' j # B, c- K W! \$ l个体(染色体):自然界中一个个体(染色体)代表一个生物,在GA算法中,个体(染色体)代表了具体问题的一个解。5 t8 ]4 k2 }/ Q
0 j1 {& I; s. U: `5 w& o- E8 y; [- e) v0 f0 O. }9 ]
4、Python代码9 O9 y7 E; ?% Z( `: N6 D9 t. o; [
#-*- coding:utf-8 -*- 9 ^3 g* v' r4 M# l4 k- \3 \2 `: V " ?: G. E/ K8 |import random. B. g8 N3 ] {9 n0 @1 B
import math: H/ @3 s& T+ S5 G
from operator import itemgetter( v" t2 E/ E1 r. Q) e
( l$ D, E) E) \$ X& {# Mclass Gene: ' x! \/ q- [' |0 W$ P3 c$ E) { '''3 {( ? m2 h% \! Y0 h2 d# P
This is a class to represent individual(Gene) in GA algorithom - }" y9 A. X' c7 U each object of this class have two attribute: data, size + e' ]1 D1 v6 u+ } _5 D$ r '''7 C4 F. p) ]+ v4 r
def __init__(self,**data):4 P: w3 P- \4 x3 ]8 w5 U! D2 ?+ w- }
self.__dict__.update(data) - S+ z4 m S- D: \4 Q# ?$ c
self.size = len(data['data'])#length of gene 0 q* \- F- f) _" H$ A4 N. J$ X4 G- A# i
. {- ?: W$ I* \, i& c l& l6 n
class GA: 9 J, K1 |9 H4 j: L, V) U6 U4 k8 D '''+ J2 r( c1 o. f0 W+ \7 \$ o
This is a class of GA algorithm. ' ^# d4 f& f4 l% ]% V
''' . Q# y' v v9 ^* i1 d0 d- E def __init__(self,parameter):7 h6 y+ n# C# U0 P/ }6 ]' _
''' 8 W% j# o. h" X% W- ^8 H% [3 o, q5 y( h Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .0 P6 E0 I) ~; X0 q
The data structure of pop is composed of several individuals which has the form like that: . V- A! R( @! o ( z! D3 j" Q7 r {'Gene':a object of class Gene, 'fitness': 1.02(for example)} 7 W% D6 t1 z n# u6 f3 x Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]6 C1 \' c7 `; Z$ I% J9 x( N1 |
6 K, N2 h& }" \' q% P& H. P '''3 l6 r) z: \' m4 R8 n- |, F) t. i( \5 y7 J! H
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 7 I5 `( @+ `! U: g- h [8 o& v self.parameter = parameter ) c+ X# w5 _1 `: k* L, ]# t0 L % @+ b1 e1 \6 m8 `+ ]8 \6 G$ q low = self.parameter[4] - v2 }# y+ y( K5 g up = self.parameter[5]" i Z, Z/ U/ r. B+ ~4 N g" \& |0 Y
2 z0 W4 l6 O7 e& l) X; a pop = [] J/ L$ t. E. Q! p( e9 w
for i in range(self.parameter[3]):* z! t7 x5 ^- N4 `) \
geneinfo = [] ) k( Z2 @! r; Y+ d for pos in range(len(low)): & }1 Q5 P# o) q8 c2 \/ ~) r geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ' T6 e9 U3 Z9 S( J$ a) N$ c S1 c& E8 J
fitness = evaluate(geneinfo)#evaluate each chromosome' \9 b+ P( ]# K9 y- h3 Z9 D
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness+ q0 Q4 w# |4 K
$ f7 _ u; D+ Y" x# A' A self.pop = pop8 m8 k$ P+ |0 p! C1 a% L- B
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population1 C; b% }$ X2 I5 U$ S
* b) Q& B+ I/ F+ W7 V0 _ def selectBest(self, pop): / y- U6 f9 r8 V8 M0 @2 }) d! { '''* ]4 Q, E5 @- U3 A9 O
select the best individual from pop# q3 F, J0 I4 o8 W
''' ( Z. M% X# z4 o! E* \1 H1 U s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) $ T) ^: l- j( F! g- H( p! f return s_inds[0]* B$ Q4 c0 q( J! _' X v% B
/ Y- Y6 N: Q. Y9 M# ~ def selection(self, individuals, k): $ I/ E: Q( W1 o7 I: X6 _ '''; @& l+ m1 C) F& |; A9 P; s. P
select two individuals from pop- N+ f7 {* S" D) L! ]
''' ; E( a9 o1 G3 C; N: d: y6 `6 k5 \3 U7 I s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness ; T+ g4 [8 P4 A
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop" u- p$ Y$ x w! L& K4 B
/ N& g8 G Q" H: k
chosen = [] J4 r' S( _. I; d, n for i in xrange(k): ( d8 R _& Y' B4 n! @( { u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] / l- s; k* d% B sum_ = 0! F7 {) k, P C# i' h; w
for ind in s_inds: 1 e5 w' Y: Y& |' B% ?0 N sum_ += 1/ind['fitness']#sum up the 1/fitness C7 ~) M9 |! G+ M) _" Z if sum_ > u:/ [) |6 w. R2 L
#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 pop2 C( X& B |6 N1 f8 ]) R( C) \$ @% M6 _# t
chosen.append(ind)1 A& n9 o7 h8 o
break # e6 E/ F4 E6 k P9 G$ i/ v" q# R- p7 m; [
return chosen * m1 s0 N8 B2 E7 ]1 P" q% ^* U
/ P a. j7 U6 K5 U
. {& N9 Q+ b9 S) K def crossoperate(self, offspring): 7 Z$ d) p( f, ~ '''! ^% ~% q( l$ \8 a8 q; ~
cross operation7 {& m- x" v5 ^+ \3 _) M# z$ ]: s& D
''' ; `; W* k$ d# h7 d dim = len(offspring[0]['Gene'].data)+ {0 o8 W% }. h7 d- I5 Z0 L0 e
# W* D3 c- `1 T
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop + ^* _0 L& Q5 p9 f geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop + N: C( D- X% V7 w9 d2 L! D" y& a8 g8 L4 ^
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, & c2 g5 U- P- ^. q pos2 = random.randrange(1,dim) I4 J3 f" T ~5 ^8 V7 c; @% ~8 ~& l+ P! F( J/ {
newoff = Gene(data = [])#offspring produced by cross operation# D8 U! h2 m, K* M# _- b0 X
temp = []0 g# ?' s; f. S6 V# X; [; F
for i in range(dim): % V6 C4 M* t$ u! g) Z9 H$ T- z if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):9 I6 m1 |- _& {( l e
temp.append(geninfo2)! b, u0 d: k% n& K( P) g
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)]* b9 E' M6 @5 n/ ^ v
else: 0 ]* S; v/ L5 a$ ?( j temp.append(geninfo1)9 n& q$ n3 E0 q2 C2 _1 R
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] 7 e5 T% ~( e2 _4 H$ `* F. e newoff.data = temp# x' L* x) @: ~. v3 y) C# h
% |7 ~$ d3 C- Z& E
return newoff& z- K6 s! H5 f+ @! d3 A
+ W$ R8 X" V2 T, y
' M* b7 U; M. A6 y
def mutation(self, crossoff, bound): 1 e& j2 \ c$ y$ A3 g ''' & d# w- n% z( q2 D( n# y# _! J6 B7 u mutation operation# E, }9 a" j( `* X+ X% M; n
''' 9 e3 q( ^9 {7 f0 i, o q b2 L" p % {. C6 T- N( O dim = len(crossoff.data)3 i! \6 c3 J5 k9 j$ h0 N: k
: K0 s$ b |" k. l
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. + h& d: q* a4 d) g5 F) _6 D8 X3 a8 B4 _. ?- y0 T u
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) 5 N f+ e* J |: u return crossoff & w2 K/ S7 d" j3 f# Y' B9 f! ]4 z( ^ y
def GA_main(self): 0 j0 [6 A) g7 d ''') f4 Z+ W( X. ^& ?3 |, M8 T+ D J
main frame work of GA 4 n7 [* [& j A5 ~( @. ?5 T ''' ) d/ {( q5 g8 `& v1 K b* Z$ O' v( m" {' u7 l# u" B" G
popsize = self.parameter[3]$ f) F+ P1 H+ e4 U y$ _+ o
) [# x7 [& |3 j1 ^1 \ print("Start of evolution") ; z9 b% K# S- N& B) m / c2 l. S1 g# O, W # Begin the evolution 7 u: t( X7 V7 m$ ?7 T for g in range(NGEN): L: v7 Q) n* \( M
$ D4 k7 D( g% k. P" a! P8 P2 l
print("-- Generation %i --" % g) + h2 G8 F" k3 b9 M 6 h' A% r2 T0 s1 Y8 e. z1 S #Apply selection based on their converted fitness 9 r& t, t7 k$ t! s0 B8 @ selectpop = self.selection(self.pop, popsize) & Z! t" F3 t* q7 g/ }% t: X: A/ v3 l. ^8 R; w: e; u& [7 y
nextoff = [] ( `$ S4 f, e% n while len(nextoff) != popsize: 7 g/ P W; x6 y" S& U8 {; e! a
# Apply crossover and mutation on the offspring 9 J* a( D& R3 j+ U7 U% J
. \$ ]* I; O5 d # Select two individuals , i1 c3 T9 @! l* v0 H: @9 B) D: L6 G. Y offspring = [random.choice(selectpop) for i in xrange(2)]7 y* y6 O& h5 u! V) S+ _
- w$ x+ }, G6 }- Z; h' p if random.random() < CXPB: # cross two individuals with probability CXPB6 W# }/ {1 b; M/ T! l0 e
crossoff = self.crossoperate(offspring)* v; A0 r1 l' h g2 _
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals ( M2 b9 a% h2 e z5 B' R0 z) O
( w! x. X0 c9 m; g+ W7 |: n' Z& f: U if random.random() < MUTPB: # mutate an individual with probability MUTPB4 x- p9 D, T$ o& C* \+ M
muteoff = self.mutation(crossoff,self.bound) & G3 i! Z. O7 j9 p fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals / \8 v- o3 w9 ~/ g' [ nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}), m5 f: X7 g9 P, x# U5 z% w2 |
' t8 x$ G6 `1 v5 l. f$ D # The population is entirely replaced by the offspring7 M/ M( y. i" A F9 T c
self.pop = nextoff + }* l+ j5 G$ R' W& f# u0 s0 v9 U 3 P# c* e, X) r+ Q # Gather all the fitnesses in one list and print the stats + k @3 v4 Y9 g$ _! G fits = [ind['fitness'] for ind in self.pop]' X0 q- D) W- v- Q, j
: g6 e6 p7 d3 c* y _ length = len(self.pop) n: _; G) k3 y, s3 J mean = sum(fits) / length) S8 b5 F# W" N J& R& n
sum2 = sum(x*x for x in fits) ) z( I8 s0 J7 ~ t6 @- Y std = abs(sum2 / length - mean**2)**0.5 6 r8 C2 g j9 i4 A: V2 |" C best_ind = self.selectBest(self.pop); ]( T. y7 P# W4 K0 \6 D
+ K. q1 q e5 c# X if best_ind['fitness'] < self.bestindividual['fitness']: 7 z2 V5 i: v9 h1 x7 B7 Q self.bestindividual = best_ind . J: K) C9 U4 L* ]" I2 w) S # J$ c3 r. R% P" M/ ^ print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) ; g1 P1 p: \: ]2 j$ O b print(" Min fitness of current pop: %s" % min(fits)). ?6 G4 Z C% l1 s
print(" Max fitness of current pop: %s" % max(fits))7 \* V A, M2 p4 {" }. ~. p
print(" Avg fitness of current pop: %s" % mean) % n# O% D+ @3 M4 } print(" Std of currrent pop: %s" % std) 7 u7 B2 s6 |' G6 @& |: {# d 1 B: q7 G0 r6 c1 N8 O9 ] print("-- End of (successful) evolution --") 0 @( I7 P6 |. O& B k4 _# d- R9 f
8 A& d0 |$ U7 g0 h2 _( dif __name__ == "__main__": J% j0 U( P2 D6 ~0 t" {8 v
; d( j/ Y) V* x3 o1 e
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters , O6 _7 z/ \- n' G: ~8 Z A3 [, V l4 u% b: \ up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables/ j, `2 z5 @ I
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables ' S4 U' Z. f! r' m3 k0 n2 d. v parameter = [CXPB, MUTPB, NGEN, popsize, low, up] 4 {: r" r+ v4 j! {0 v; g8 v x; U 6 c, I/ M# i- h9 D% ]0 u) M run = GA(parameter) 1 X& s- f; E9 |7 b% F$ ` run.GA_main()9 `$ ~% _; Y, e" I- J
———————————————— z$ ?" D, c; y版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 b: d, r, e% a8 J, q. R$ f
原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 ; P, u6 p8 c! \9 C8 { 5 G& l8 l" |' A, U- S7 j! ^1 }( k9 ~- R8 v