0 L d. f4 k* T' z2 [. o% h+ A遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好地诠释了生物进化的自然选择过程。遗传算法也是借鉴该基本法则,通过基于种群的思想,将问题的解通过编码的方式转化为种群中的个体,并让这些个体不断地通过选择、交叉和变异算子模拟生物的进化过程,然后利用“优胜劣汰”法则选择种群中适应性较强的个体构成子种群,然后让子种群重复类似的进化过程,直到找到问题的最优解或者到达一定的进化(运算)时间。" g, u. ?5 U2 c2 e* N8 Y* Y c
7 S" b/ s) u8 L+ }: o( u0 yGa算法中的几个重要名词概念。+ K' q8 [ ]( W3 Q7 I6 b8 c1 v
+ n$ O$ T; |( {, g
个体(染色体):自然界中一个个体(染色体)代表一个生物,在GA算法中,个体(染色体)代表了具体问题的一个解。 ( O) _. M- z' W- P! p& M: T
9 Z* D% L& \5 ] 7 Y. T6 T( b M/ y4 L4、Python代码 o! {+ ?' _4 @. ?9 y; M% }
#-*- coding:utf-8 -*-/ L. m3 L2 F L: W
( s8 _/ W. y# B
import random- v# U8 S, d3 w! R
import math$ `+ t$ o3 M+ q/ z# v
from operator import itemgetter - Q c/ D5 W3 ^' @/ ]" S* H i5 t* J+ W0 i; X
class Gene: 7 |% v2 Y" x5 s2 q '''( j; j4 v2 P4 h3 }
This is a class to represent individual(Gene) in GA algorithom $ m3 F% N6 \# M. D, |) j+ i each object of this class have two attribute: data, size1 a* c$ ^' V) F9 g: q% t
''' 0 V( }# x7 G% {' A def __init__(self,**data):* [' R* g N' C# F- a' c+ B' c$ U
self.__dict__.update(data) 0 ?2 K; j: M/ M, U. R3 {6 ~3 i
self.size = len(data['data'])#length of gene7 l0 @7 G) d7 y3 Z% `
1 { B3 d. i3 g, n' Q8 {7 D+ J7 z: q6 k
class GA: % y4 Z& N0 `8 [. [, Q ''' , ^" G8 f( U1 n. ? This is a class of GA algorithm. ) i# ?$ w! `6 ~3 \1 W4 `; h ''' & j6 w0 d# J3 t- g, B& z( z3 m" b def __init__(self,parameter):! m6 i8 M) K p
''' 9 U4 {3 |- H5 b; x Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .6 _/ \# Q" s0 J0 S6 z7 S
The data structure of pop is composed of several individuals which has the form like that:/ Z$ r2 v) X0 i- ^4 \" ?
X' g. n: s# N) o' w. @7 g
{'Gene':a object of class Gene, 'fitness': 1.02(for example)}. `+ H7 Q4 _% O0 \$ S
Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] 9 T$ [) x I& i: @4 Z % [+ T) k9 K+ g ''' - e. ~% i! g" f4 g% b #parameter = [CXPB, MUTPB, NGEN, popsize, low, up] s( I4 O* n4 ~ H& K
self.parameter = parameter$ B# w1 z1 x9 S! U, x& F3 p! {' x% ?
Q+ T ?. ^/ p9 h# V m
low = self.parameter[4] 3 p- o: m$ u4 k. H" Q' b/ E up = self.parameter[5]" ~( z7 }8 a! C& h% S+ U8 z
2 \; [, W' G6 z" T, n self.bound = [] # m3 O( N; `* w$ r self.bound.append(low)4 d \7 h! d9 w( J
self.bound.append(up) % G" I- d( n9 M8 N8 l% i8 K7 E) G6 B+ \7 v, W
pop = [] 1 N4 ]3 L, Q! r3 V# B for i in range(self.parameter[3]): 5 q6 l' d3 b5 ?* n geneinfo = [] 8 w7 T3 D7 E, f3 m! ~ for pos in range(len(low)): : w/ ~! m5 a' @5 Q) q# E geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation / H7 l: R. B/ [& p! w/ G ( w/ }7 h) ]+ G+ d, P! l fitness = evaluate(geneinfo)#evaluate each chromosome # h2 x, z7 A9 e+ Z$ e% j/ g pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness/ v; {. }! d, o4 b5 L
3 X6 ?% R2 q$ ?$ t f' V
self.pop = pop 3 z% q+ g' R9 t/ @8 x self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population $ L4 L N9 s* X7 z& c& u2 b) S( Q. O
def selectBest(self, pop):3 f. k1 p9 T5 H* d. H1 S6 P8 X
''' 6 S8 k6 U4 f/ |- V& | select the best individual from pop : z: o* u/ Q0 ^( c, B ''' 4 Z3 p G* V* S7 i o- ^ s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) 6 k7 c- w' ]1 W$ M. I+ i5 F return s_inds[0] ( q1 y+ \+ J E! D- b9 h % o& F& k6 d& P0 l! y5 B+ { def selection(self, individuals, k): : v$ C( r6 j# O4 @ ''' / N( j) [: [4 Z; j2 d- J select two individuals from pop / d: ~1 A# c" M& U ''' 9 r4 U% J5 y7 q9 H' h- p5 ^$ I s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 9 R" n4 c8 E3 O: M
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop: V( P4 P- d+ M" a6 Y' v
# y$ V" p+ l4 {, B chosen = []7 g1 B6 f; a7 X$ i1 Y3 X
for i in xrange(k): , p% p, ?+ S8 j8 m u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]. z2 S- B. p8 M7 A
sum_ = 05 v; P, c; z' J7 C8 h+ o* V' A
for ind in s_inds: 7 f9 I& \! a( f7 K2 e sum_ += 1/ind['fitness']#sum up the 1/fitness 3 m# r) S/ o/ F1 K& c if sum_ > u:1 |/ {0 v; f- u* o" e& t, G4 m
#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) G! D: e& a2 R" e# i3 ~0 t
chosen.append(ind) : x# v9 T& q6 \3 f7 y1 \ break 3 G! H( X& F# i& `+ ~0 D / q; ]) e* V1 }: Q- H return chosen % q3 a) j: w& t+ s+ [/ c6 [ : X5 y5 K" |4 _4 P/ ~. B+ Z" z8 m; }) {! U
def crossoperate(self, offspring): ) Z- h/ w2 |3 c7 ^+ e '''3 e0 C, P# S; q7 ?# t( F. @0 m
cross operation, W& P6 H, y1 M$ L& U
'''( e# a u) f- c0 ]- _# U
dim = len(offspring[0]['Gene'].data): l* t8 H2 i2 X Y2 h
' v' m5 G4 `5 _2 f" S geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop: Y, ]+ I- H$ y B) j
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop 8 f# e1 S5 I* ^, Z 1 H% \! ]* L( m- Y1 t; r pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, , h& y' l2 S+ H% ]1 O- T4 V pos2 = random.randrange(1,dim)0 f& B# P) e5 z, w( H; Q; Z
( ]- F) B1 _9 c8 Y! w
newoff = Gene(data = [])#offspring produced by cross operation9 W. q, h( B2 a) i3 L; U
temp = [] ) V+ n3 e6 j( E4 a% n' K for i in range(dim): * n, ~' v/ @) Q4 T if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): $ E. ?9 i Y- q' Z+ f9 L temp.append(geninfo2): c* M' ]6 m7 {
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] 1 g# e' G5 u9 F: ]( { else: + V% o' z+ s4 ?7 }3 m temp.append(geninfo1)' K, c& L- N* g, u+ w! [' p
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]: V' c7 j9 e! Z! Y
newoff.data = temp T; E# |+ i/ E( A2 z * n. O$ h J _( v) E0 ?. [9 ^ return newoff. j- K+ P( [- w5 p9 z
' _4 H7 ?% u8 Z. t* v+ G% ]
" t: [$ a/ l+ ]
def mutation(self, crossoff, bound): * R4 E5 x+ l* _/ p# M8 U ''' : J1 M5 q b* z/ c* X: T mutation operation% c6 Y o; a/ S
'''; c$ v- v- z) Z5 I N. l
1 d# K: O$ z' C% Z' \ dim = len(crossoff.data)8 b1 |+ ^; w8 W% M6 ?6 ]2 M
/ I9 |9 ]' Y" t
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation.- \/ |# t' W$ ]3 V+ i
. N# z* p5 `+ I( n1 n: t" q
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])# f) v) E% C" {% \9 z6 \
return crossoff + M* {2 w; c0 j+ ? ! x8 d' q+ t6 {7 G def GA_main(self):: _: G6 @/ V( p! _1 l: v" C
'''6 ]- G/ z) L! c! Y- \
main frame work of GA. u) e$ O6 y0 i0 q( D- V
''' ( _/ X6 i6 w5 ~& M6 H c; H' @" y0 K' T o# _$ I- }) n' L5 x
popsize = self.parameter[3]% f3 j9 N4 d; H/ ~2 [( a2 w# O0 Z
. O# |: j; N# U5 R% x print("Start of evolution") 3 P9 \" z/ V M$ p" ]) d( E0 c; P7 o u- y+ Z* }
# Begin the evolution 5 D: n b# l$ @& b for g in range(NGEN): - W7 u8 M9 m6 f- @( O / n! P4 m( ]: `* ^+ ]5 ^0 x print("-- Generation %i --" % g) % x4 O$ Z! P( e& x) D/ D/ ?' S* ^" F, U/ \" n; n
#Apply selection based on their converted fitness# A4 y- J1 q+ t4 g( |. K
selectpop = self.selection(self.pop, popsize) ! A- p3 w2 w* \2 ]: D$ P ( T, b: a |5 e; H nextoff = [] # P+ o/ X2 Z: D2 E( g1 f3 o9 J" T
while len(nextoff) != popsize: 6 H" O' p3 @" i$ [
# Apply crossover and mutation on the offspring . c; D: v+ }5 P. `9 U
" g. T. A5 W( w6 \2 G4 J # Select two individuals : c. e/ ]" B3 X1 H/ q- h) q& S offspring = [random.choice(selectpop) for i in xrange(2)] # V1 s9 Y5 l& m' d" R! L 7 v+ H! [ q0 `% ~0 B if random.random() < CXPB: # cross two individuals with probability CXPB # G' G8 M. B2 G/ E2 x* P4 ^ crossoff = self.crossoperate(offspring): z$ M5 \! g& f. r* y( R1 H# o
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals + U2 N D6 O; h+ G @ ' ?% B! M+ Z; f3 Z- d/ z, `, N( R if random.random() < MUTPB: # mutate an individual with probability MUTPB7 O4 F/ L3 v4 A. G a& G# P( u
muteoff = self.mutation(crossoff,self.bound)9 d8 s( b" a" W4 \+ F
fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals ( B2 `' C; o7 h+ \% V5 Y nextoff.append({'Gene':muteoff,'fitness':fit_muteoff})1 {3 b0 t3 }) S- \4 S+ E* r
8 c+ r5 V0 {. e& a # The population is entirely replaced by the offspring , r. Y, h' f. N& n3 l5 C self.pop = nextoff0 C: S, Y2 |% O
6 T( W v* d7 e: v9 n # Gather all the fitnesses in one list and print the stats' @9 h2 k. V3 T8 J, F& {+ ]
fits = [ind['fitness'] for ind in self.pop] 2 z/ ^+ r4 ]! @ l7 b0 m) n5 h2 b1 q: q length = len(self.pop) - [; W: V- N7 ?- a3 c' V9 D mean = sum(fits) / length" B9 C [5 k$ u
sum2 = sum(x*x for x in fits) & l% {; I# R6 ~3 U, e+ n. `3 Z std = abs(sum2 / length - mean**2)**0.5 7 f9 f7 L0 {9 f% ?% A. N best_ind = self.selectBest(self.pop) 6 {4 h- J! b: |6 R; I4 J5 `4 x ; ?1 i' u8 }: E2 f; w$ { if best_ind['fitness'] < self.bestindividual['fitness']: * e, H: y# A9 D/ H) e self.bestindividual = best_ind 1 ^1 v6 x& b( n M6 Y* [/ G" {' q+ _2 D% B+ K/ J7 N6 z
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) $ |* u4 Q: X: K }' m0 N: T9 V: y print(" Min fitness of current pop: %s" % min(fits)) 3 s5 K1 x" P, c } print(" Max fitness of current pop: %s" % max(fits)) 2 T: o2 |0 q8 B9 ~: M print(" Avg fitness of current pop: %s" % mean) : f9 V3 L* T- x6 M print(" Std of currrent pop: %s" % std) , E3 N$ K2 `2 ~# {+ L, ?; H ' D4 X" M- e* J- o print("-- End of (successful) evolution --") - {# B3 f, _6 s$ l6 z" [
}0 |+ u4 `1 s" Z1 x
if __name__ == "__main__": . X) x, |. z9 w% D( q2 t* x, j! i! P) L/ H4 B
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters5 l* \6 R" G% `4 ^) V
6 ~; x2 u( }' h: n5 U* @0 N' ~ up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables# w9 I8 `& q- V
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables _* b2 U. Z/ m$ Y+ T
parameter = [CXPB, MUTPB, NGEN, popsize, low, up] # a9 m' p/ i4 ]& I0 S" u; M% e0 P9 Q* u3 ?( Q2 x
run = GA(parameter)0 @9 W! Z% D5 M. p4 w. j7 a& q3 i
run.GA_main() & |% F( B7 ~; n6 S0 A————————————————1 N/ V; ]* ]7 J- h' K
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。% l; e9 C; C$ `- I5 I: W4 w
原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 ) p) k+ L7 y5 b; G! U! I8 V 1 M8 b6 B3 g4 w4 d8 U7 O- F |# y$ ~1 ^* ?