0 Y! ]5 b" t' X& F1 k8 i4、Python代码! X) l% R' N7 |% S0 ~1 C2 ]1 L
#-*- coding:utf-8 -*-- q; S# @' {; f% H6 i; c2 u
: C) v( G% [/ ]+ Z% e* N
import random & U0 o! j J" J# i' }import math3 B G: V- \5 Z: [' s" R' `
from operator import itemgetter) e; g* k& ]/ Z: f( G1 b
( x+ P* ]! S0 c# N/ L" R- zclass Gene:4 b: J1 y+ P2 v* D# B9 }
''' , E) z3 f; {& r This is a class to represent individual(Gene) in GA algorithom 4 k, e$ h$ o) U+ R6 U each object of this class have two attribute: data, size 1 j" g! m$ D% r- F2 p ''', c, s8 J! n& l, |. q1 `6 C
def __init__(self,**data): * A9 Z2 m8 C) x3 @. V: k1 q s9 F( } self.__dict__.update(data) % V# ~# ]# F9 I( }) R7 ]
self.size = len(data['data'])#length of gene / l5 B; X* H4 ]4 y" B# i& U' e2 ^' M7 Q8 I: N
9 n% z' t8 o- q- V6 L
class GA:" [, h2 i; `9 l5 [4 \
''' q0 u7 o/ |9 r9 P5 X
This is a class of GA algorithm. 5 u! N3 C- U/ F7 ~( }8 R( Q& p ''' 7 G2 [3 p6 q: h( r: w def __init__(self,parameter):/ ^5 R; D% ]; k3 L9 h3 e% e
''' $ p! q. w+ v* v- c! z9 j Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . ; h3 c* @1 I! |! Q6 f e! _/ M The data structure of pop is composed of several individuals which has the form like that:0 k6 |3 @$ G3 m, t# N7 x
. ?" A' ~$ R: k8 Z- i( M
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} 2 Z6 Y7 w& M- g0 Q0 ^) P$ J1 v4 A g Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] 0 ^7 p' @* W% F6 n+ ^& Z: _3 j# y; G% {2 k- c. q2 m# }
''' # b# x y6 x' K& L8 H9 d6 W #parameter = [CXPB, MUTPB, NGEN, popsize, low, up]* M0 B" u* O, k
self.parameter = parameter ' s" @1 j8 i% m# L2 ~& @0 K i0 H# _2 O2 R
low = self.parameter[4]$ n6 E& C7 F( ^5 g9 Z9 I0 \6 ^
up = self.parameter[5] " i9 F r7 P. c6 N; V 1 g, i4 F/ P. t* ~) S& U self.bound = []1 o; K, V- ^: G3 F6 N* F5 c
self.bound.append(low)1 |- N6 r+ ?6 Z: E* q/ J4 C
self.bound.append(up): V9 v$ [7 \. e: ~8 y7 i/ Y" t R
+ R# H8 U# V- C: U" s$ \% K' J2 B
pop = []6 f K' Y1 j; t
for i in range(self.parameter[3]):& z2 K, c& F. h( x" e
geneinfo = [] - f, u& Y( k) q; w6 _6 W0 n+ ], ^ for pos in range(len(low)): / O, e% l3 x" W* B* C geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation* @) Q- n% D: N9 }1 k. S+ ^
/ L: A) S8 I3 u( H/ q
fitness = evaluate(geneinfo)#evaluate each chromosome& u( R( k6 L' }0 a! z
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness* A: {8 W1 z" J5 ?8 v. \
% T( O- x6 t8 v self.pop = pop' A$ J( j( }# W
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population ( S1 t0 y9 T E$ C0 N5 P$ i) Y4 @) H+ s" B1 r& L0 X& C e
def selectBest(self, pop):6 @5 o! K+ O' U
'''9 L b/ L, O9 ~* T }
select the best individual from pop ) |* Z$ g* v& ^. z; L7 m '''5 m" ~" D" x- |
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)& f4 B+ R8 O+ I. j2 R$ \
return s_inds[0] : e& H" f( w) j5 w0 X% I! A* O4 l$ F: |* ?
def selection(self, individuals, k): ( E* x/ |, T0 w: w: G ''' ' _3 Z8 W( _) ~" P' g select two individuals from pop8 X+ n- t( ~0 ]; k' e0 W2 J* g$ I
''' - k+ a$ @! M6 t8 n s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness - ?$ s1 g: d/ S4 ?4 N3 f sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop ) x. X" z, [8 g, O" G& r4 Y+ |' R: n6 Q+ r- A
chosen = [] ( e& \) w* K& }) x9 \ for i in xrange(k): / ~" n6 u$ R- }, Q o u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] u) K4 [4 s" { sum_ = 0 1 ~* ]; `' t: H2 h ` for ind in s_inds: 3 @' ?, f# @ [( p. B: ^5 | sum_ += 1/ind['fitness']#sum up the 1/fitness G+ n& ^) K/ q, V3 {- q if sum_ > u: - t2 v& q3 Q4 W% `2 w6 [; e I' } #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 ) d5 E# G$ c: _7 N chosen.append(ind) $ s$ D3 Q1 U; b `9 q4 ^. X break ' C# p Y- f6 b+ V * ~* Y- {6 {( O return chosen , H8 `* |( |( d+ `1 }% v9 Z0 q
0 X; p1 S, q/ L: x6 m* m9 e
" v/ I* `+ v4 O5 ^( Q# c U def crossoperate(self, offspring): 9 k, l- q9 E4 D7 L" K! Y4 P '''2 v7 }5 p2 p& n: ^1 j
cross operation! j4 c" _8 O: {
''' {8 b! R4 E. ?; L& G0 b
dim = len(offspring[0]['Gene'].data) 7 A4 n: m3 H2 o2 W4 A. d. [3 a% S% ]8 i4 I% k0 [4 u- Z
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop4 Q7 p, V0 `1 l0 }/ H$ ~% k, g
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop * H& Z' g+ g+ i/ @/ s8 Z+ k % ^% e0 r- Q; I1 Q- W+ U$ u pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, ( M4 I+ k1 { ]' b8 K& g% M! W pos2 = random.randrange(1,dim) $ ^ G; j6 \% ?7 {7 ~7 l6 [( M8 R, G: w. e0 K
newoff = Gene(data = [])#offspring produced by cross operation- w! d, @. k( F6 a
temp = [] 9 u+ M. u4 b3 M for i in range(dim):# K9 @/ ~$ t& U% L, l4 G/ G
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): ) Y9 ?' X- ?$ m f# N temp.append(geninfo2): n8 y8 U9 p. `. R
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] + d& S* O4 ^: o else:3 d$ g) I, c. ?6 W; e6 D) u: j# H
temp.append(geninfo1) 1 N* g. Y; s E+ d' E #the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] ' k: g8 C, O- f& Y0 N9 M1 ?( ~, @- }$ @ newoff.data = temp * }+ g( K; y& g1 `/ \ . |% ?. |/ @3 F: k: d/ X1 P return newoff - x/ H2 J; @7 w( C9 g5 c9 c0 X. Z% I. ?- _, |
* Z! G, J: H9 O# p, ? dim = len(crossoff.data) Z" ^. Q& d- v ) F0 z/ k. j0 } B+ }4 G pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation., G; _7 d' I0 e% b( O3 B/ I# K
, w# @- \: K1 `. H7 b crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]); \4 l \" H* ~' U, N. I/ H" J
return crossoff5 ?1 Y7 V2 r3 N$ [, k
& H/ k7 a0 K7 T* P5 [, Y9 \ def GA_main(self):- A H! ] h& Y: t: d0 B
''' i; l2 ?- ^( C) i main frame work of GA$ D" m$ E2 y6 E
'''% i% q" g. {1 i8 B* X+ w
6 @, d7 C4 o* A' W6 P. E4 n3 { popsize = self.parameter[3] ( t2 A/ C! V& y! r5 L( X& G* \0 s1 l1 o( l8 Z
print("Start of evolution") $ r( S" E" Q" B) c: B6 z9 k4 X/ r8 k3 i, R
# Begin the evolution- C, r$ q( O9 E& y1 a+ ?. l7 h# U
for g in range(NGEN): " R' w) I1 i/ Y6 J" ?* x/ J5 K9 H ; Y' s4 u0 [4 j* z8 l print("-- Generation %i --" % g) ! ^5 u6 k& `, X9 P! T9 j' A: h
" Z7 X6 ]3 o* ^
#Apply selection based on their converted fitness 4 @: O. K5 }3 ]& C( p selectpop = self.selection(self.pop, popsize) 2 p; m- f$ _; ^& r: A( S/ b- D" m
7 g8 e8 \! c0 B" P! x+ X nextoff = [] ! F$ P8 o6 @5 K while len(nextoff) != popsize: ; Q _9 W9 z# R; K( `
# Apply crossover and mutation on the offspring ; J: g1 a- R6 k4 L" N* ?" p , M# S/ y; J0 g6 L; z9 ] # Select two individuals8 o6 @( l* g1 O7 j
offspring = [random.choice(selectpop) for i in xrange(2)] ( N( Q5 y. T) J9 u7 A I 4 }9 M/ ?; u& m6 x! k5 j if random.random() < CXPB: # cross two individuals with probability CXPB # e/ f. t$ H- c& L* B0 M crossoff = self.crossoperate(offspring)8 }/ W; b& o/ e- w$ n8 Z8 E
fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals / |8 m9 N# {) `7 o. U0 N1 K) Y- y$ u4 r+ G
if random.random() < MUTPB: # mutate an individual with probability MUTPB ; S. T- H9 W! B- o muteoff = self.mutation(crossoff,self.bound)9 x6 W1 C: m$ B
fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals& Z, ~1 J' U7 V! E5 T5 |
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}). k i/ Q# z2 n7 {& @- Y p
* a3 c: S) _" j; _ # The population is entirely replaced by the offspring5 @. C2 S0 t9 M% o- q' u, Z
self.pop = nextoff $ v+ K4 M" I" x& K1 i1 V' l9 \" m4 I% G" w2 ]/ _+ U6 E1 K3 q
# Gather all the fitnesses in one list and print the stats6 q b7 g4 u$ \4 O
fits = [ind['fitness'] for ind in self.pop] 8 H2 x" j& q( C+ h# x" `) G4 M
length = len(self.pop)- J9 N# j# y. F, o) F7 ^5 [
mean = sum(fits) / length' V1 B& j+ F" V# z4 R
sum2 = sum(x*x for x in fits) B: f9 m' W) [5 t v3 m std = abs(sum2 / length - mean**2)**0.5# J1 O6 Y4 ~" s: ~3 S' Z6 x0 a( {6 M
best_ind = self.selectBest(self.pop)4 ~- X/ o, g$ q2 {
3 E/ ^8 g3 p9 g3 S- x
if best_ind['fitness'] < self.bestindividual['fitness']: , h: M4 w3 ~0 b+ m3 ` self.bestindividual = best_ind$ M. R h8 c8 e- @: n6 X) J7 O
$ V% _4 U: Q+ q8 R) n0 K
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) . W5 i, }1 X4 T- B' J7 Y print(" Min fitness of current pop: %s" % min(fits))# }: ]7 T8 a& L8 v$ I
print(" Max fitness of current pop: %s" % max(fits)) % C- |, L+ y( g6 ]- l) A2 E) \# I6 S print(" Avg fitness of current pop: %s" % mean) * r; ^" ]' B! w, A( s print(" Std of currrent pop: %s" % std) & y% p! a3 M N3 i/ I5 Z! u4 b* T/ U0 X
print("-- End of (successful) evolution --") - C5 y: E' Z( V7 O/ [ 9 ?) j- k; @3 }" a' M1 S# J: ]/ Rif __name__ == "__main__": ' e' t2 Y$ _# \* X! c1 A( B* C$ c; D6 f, p% \. d2 j' T
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters 3 U E" a" y: _9 ]3 ]6 s2 E & E+ a- K" T1 Z7 r; G ^ up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables 9 R4 t' @ f: G* h& S low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables " n/ s: b/ V M8 C4 f: A/ n/ l parameter = [CXPB, MUTPB, NGEN, popsize, low, up]" u' U2 Y% \' ?* K+ J2 ]
$ u2 |3 k4 Z, }: ~% `" {* A
run = GA(parameter)5 i _3 M7 |3 u- M4 \7 U2 I
run.GA_main()( b0 I" F- x* a. y! b, v, `2 s7 }
———————————————— + _- P1 b% U7 g5 g1 {: ~' ^版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 9 P0 D' c% T3 ^( e( M% w原文链接:https://blog.csdn.net/bible_reader/article/details/727826759 C3 v( g( |4 T. u: s1 \, Y, }