6 m' j$ e. D& t: h) s( s3 O4、Python代码. ~9 g g. U) Z" K6 T) m% k+ v; r
#-*- coding:utf-8 -*- % J, P# O; W! J6 \* Q+ V' K9 L0 j4 @1 |8 ~4 T
import random& M0 T# |1 L2 C4 h: ~8 n: p# n' h
import math. g2 W' g1 o8 l, L( n
from operator import itemgetter ' i, d1 V7 n% o/ r! O! U! d% r& X& F: Q; l8 J1 R
class Gene:3 h% c" U5 [0 a7 r3 G
'''$ t; |: }2 ?7 t# _, S; K4 {7 {
This is a class to represent individual(Gene) in GA algorithom & I% e5 Z' Q, G8 N1 V, Q" S each object of this class have two attribute: data, size p+ p* j$ A; \ ''' 0 {. v2 l3 _1 x; F: Y def __init__(self,**data): + U! I6 g6 T- P- _" q& G+ a self.__dict__.update(data) 5 t( E5 M4 O+ z3 n9 Y self.size = len(data['data'])#length of gene/ n" R- ~+ J( v( l3 h& z
# ^5 ? ^* j- U( Y/ h
" V/ F5 n0 @- Z& J$ H; I
class GA:5 g4 v I% u; [$ `3 W
''' - j" |: J1 X: K0 b4 ? This is a class of GA algorithm. k) E% t1 _# p- P. [/ J
''' }- x1 W$ M( p" r' u1 R7 _) J* } def __init__(self,parameter): 0 Y& i# S; m$ s) C5 L1 @4 a) J '''$ A; Z7 E4 V0 x% C/ C }
Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .. j( R2 q! ^2 h; x2 }
The data structure of pop is composed of several individuals which has the form like that:- W7 ?9 M% d0 \5 T0 W# d8 }; h8 T/ n
& z! W+ h* ~% s3 O8 l R1 }1 I {'Gene':a object of class Gene, 'fitness': 1.02(for example)} + {" x2 r% x4 {6 [ Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]& z: ~! A1 Y H) i
! P& u! m6 j3 o. x# ]- H2 V R" F4 M
'''7 Y h* m- c S4 A# b w- R
#parameter = [CXPB, MUTPB, NGEN, popsize, low, up]1 M3 e6 x$ b4 x8 u
self.parameter = parameter # Y0 b/ O$ V5 k, l/ q' G# x1 j# y4 t4 ~
low = self.parameter[4]- Y# E" [* L. K$ B: O6 Y
up = self.parameter[5] 0 a2 j" u/ a3 |3 E3 h3 L2 E4 g6 N9 s0 G. @0 H% j0 J c5 D
self.bound = []' S/ e8 j7 w4 u: \! H4 _
self.bound.append(low). f/ u! W; z; W
self.bound.append(up) 2 Z; g) o* `) X: _ " P4 Z+ e4 W: K: q/ E pop = [], J; F S+ z0 }$ j5 W' U( J
for i in range(self.parameter[3]):$ A$ ?' J6 o+ M* [
geneinfo = [] * X h" ~3 H$ B, t0 w1 ` for pos in range(len(low)):! u( n+ F9 s$ ~, {" d/ j, D
geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation ( ~( }& D& p3 S+ D! _/ A4 D! O$ i3 I$ L+ J
fitness = evaluate(geneinfo)#evaluate each chromosome* r: \! m8 ]. r$ |
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness% [( F+ R8 M6 ~! ]) a, {
]: M+ m% ~, \% w" C5 K4 x- F self.pop = pop1 p3 T$ a7 Z; i
self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population ; S; r( @9 C) Z; f$ |1 V5 U. m$ p+ w( i5 z( X1 P, S. p" F- x
def selectBest(self, pop): , `* a5 J5 f9 E% \4 J. F '''( N3 b( k& b0 l3 }+ S* M- r
select the best individual from pop9 U7 N6 W# X8 o' Y1 z
''') p) S+ U$ t8 K7 M; x8 u
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)3 i' c8 Y/ A9 U) b$ d
return s_inds[0]4 r& K3 h/ a2 g
+ ?; b$ O# K+ I; J5 p/ U& z
def selection(self, individuals, k):( {! L) P9 S+ s* |: g d
''' _' d. p1 X3 C! f# ^ select two individuals from pop% d9 N3 f' T& W% x. n
'''! N' J! N2 L5 [- H8 k
s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness # N4 `' f/ i' e) b* {, L+ s sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop ' H( [! r8 U( T5 b& N2 ~; S% w* Z& @% a- v
chosen = []0 A1 P6 P; Y5 u1 w8 k/ J
for i in xrange(k): v8 e# z% |8 S% ~6 C0 c u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] ; A* J* q! e8 u# ` sum_ = 00 I; T, A. k5 l
for ind in s_inds:- x$ ]) I* ?% J" Q
sum_ += 1/ind['fitness']#sum up the 1/fitness 1 Q( h0 `1 `7 S( p: L" W if sum_ > u:5 A/ Q i& x4 ~- ^" {- N/ _
#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% f* t. ?( `, g7 ]
chosen.append(ind)- d' V D; u' X$ w
break 1 v- ^; H" |+ p. i- w# m' K1 ] & H; k1 f3 h/ R0 s return chosen 4 B3 j* d2 ? T) w' u* ~$ z * b) K* O+ t7 \# Y5 M6 l$ _. `- W: ^8 @- `8 P
def crossoperate(self, offspring): & V- t) F% K: M" x% ~, B ''' ' w) ]' j6 y, s+ i cross operation6 U ?: z' y9 D! X
''' / I! i* f7 G w" u' H) Q/ B! S dim = len(offspring[0]['Gene'].data), z% N+ b- P- S* y* K( W' h
$ O+ N e, }. f) F$ z: H; D, _* p
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop4 A* j9 g0 N+ V, p
geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop H2 S k$ P: N, f T: ]2 j3 y6 U7 T/ Z7 j' d! N1 ~5 |- o' p+ L
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, # L2 m2 V P0 Y; ~" I. y" \ pos2 = random.randrange(1,dim) 5 }& B8 X* o% m9 \ : D6 e+ K; ^) | newoff = Gene(data = [])#offspring produced by cross operation I9 i @1 W+ j temp = [] . }- e- q: p! |1 C4 m$ m$ K" U for i in range(dim):0 p! ^! |1 W' Z2 r2 `5 l2 j
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)): 0 x- y6 p0 ^0 X; ~6 O. X9 w5 L4 W temp.append(geninfo2)8 k4 L. H# d- z K
#the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)]1 H6 i" @) t3 L* |' F9 _( @% K: Q
else: % [- m' O& D+ S Y! @ L temp.append(geninfo1) % N' O7 D3 H. V) f, z) W( h #the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] " c' P5 Y+ H3 z4 k, S8 n: W newoff.data = temp : ~4 l* Z! x3 m# F) ]3 b) _3 c$ G4 R* j y3 G
return newoff $ U3 q8 k. S" l9 E, c" B" m" I/ Z8 V' W" D) T. n( s
" F8 ^4 {3 `, [1 n @5 ?0 X
def mutation(self, crossoff, bound): 1 e- \4 M" @& g$ B* P2 S9 Z ''': p9 m- F+ p. U% F7 I8 L' Z
mutation operation [5 m0 o8 X- V2 M5 A '''3 n. Z/ v6 e! F5 n( N; x8 E+ c
0 X5 c) `4 U6 v; k. I dim = len(crossoff.data) , F; a5 t- \! i. m* r6 r K# `5 i
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation./ L) Y5 w t9 {& q
5 n$ K( L& Z4 ~6 S
crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])+ z9 y8 f- Y& w2 z5 z
return crossoff / q/ m o! m' _8 z4 Q* _0 [/ n2 X. u* W' T
def GA_main(self):$ w# l+ |( e" y
'''' o( \& b; Y: [0 A. A& E* i
main frame work of GA ( k) q1 f4 M& _! \9 c3 O ''' + X1 [& Y; t5 c! f2 W6 H * u6 R7 R5 j7 ]0 ^3 {. K6 ~ popsize = self.parameter[3]( o0 a6 }% ]% [ T
' t4 m* N9 h$ H6 a8 ? print("Start of evolution") , [- j$ p3 K2 W$ ^) D 4 {% C7 T5 {" n1 \# ]! I- n # Begin the evolution 3 T1 v, _! o& N; U* i8 U( e7 K for g in range(NGEN):$ I. {- `2 V+ g& d. x
- `7 a# C4 B" h6 z1 B% h
print("-- Generation %i --" % g) 5 F; t" J% ^1 N8 _. |4 J0 p6 e O 0 g( B, U4 T* C& g8 \% v7 @2 N( ] #Apply selection based on their converted fitness/ m$ K4 N2 q$ P, o9 n
selectpop = self.selection(self.pop, popsize) - G. j* h' Z/ n
$ p% a; _: ^+ U i4 G nextoff = [] 9 x9 y4 z/ T$ ~# q, y
while len(nextoff) != popsize: , Y+ M' w; y: ]. A
# Apply crossover and mutation on the offspring $ v0 ~# O% f8 o" `% a1 G 2 G p$ B% A% }% a, R1 ` # Select two individuals # O% \) A2 R8 _) I6 h offspring = [random.choice(selectpop) for i in xrange(2)] ! }# e7 _' M7 K + t' e. ~* u1 z if random.random() < CXPB: # cross two individuals with probability CXPB & o7 q4 r1 h1 |! V2 r: q' t crossoff = self.crossoperate(offspring) 3 s/ z1 B" x$ q1 ?. c' }( n8 k9 T3 g fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals , [& l# f9 e, Z % t, l3 q$ O ^8 z& y$ ?. L' l3 t! e! u! k if random.random() < MUTPB: # mutate an individual with probability MUTPB " k' R0 Y$ y% F. s muteoff = self.mutation(crossoff,self.bound)6 Z6 H' e* a; f2 R3 d
fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals5 `% F; v! W7 i0 e4 o2 d+ M7 {6 Q4 \
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) 8 z- ]1 b! p: L. E0 X# a% | k& l- o/ ?5 Y
# The population is entirely replaced by the offspring 1 D2 M- c+ a, o7 b1 R self.pop = nextoff/ b2 ^0 P# O8 z, U) ` ~
4 N$ v* l$ r/ w( ]& B( Y
# Gather all the fitnesses in one list and print the stats2 `7 D* H [( l. F
fits = [ind['fitness'] for ind in self.pop]% I; w; a9 n. N s5 {/ z% i4 M) a
% m5 C. P* Y" V' {: Q. O
length = len(self.pop)! j1 k3 R" C- L2 ?9 d4 c8 V
mean = sum(fits) / length 0 z8 Y0 H! G: j+ ^( q: e sum2 = sum(x*x for x in fits) ) Z# p; o8 p3 }6 `2 [ std = abs(sum2 / length - mean**2)**0.5 & k8 Y7 ^3 P( |4 B. O best_ind = self.selectBest(self.pop)9 {+ q' T6 C' N5 o# y& J
) I2 S" Q1 q+ n& Q if best_ind['fitness'] < self.bestindividual['fitness']:+ L: K6 g9 s7 x* T$ n/ {
self.bestindividual = best_ind : D# o! S1 o9 M" l9 g3 M) P% C) [1 |0 m
print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) ; F7 h$ d+ Z; f* D, l9 `4 h print(" Min fitness of current pop: %s" % min(fits))' k2 s7 t& n. r0 u
print(" Max fitness of current pop: %s" % max(fits))7 \- ]2 I4 q9 o }) q% [
print(" Avg fitness of current pop: %s" % mean). Q, D3 g; m, N8 l. q
print(" Std of currrent pop: %s" % std) - V7 m7 F; {+ t- Q2 Y5 f1 ^, n }# N: c& @+ I
print("-- End of (successful) evolution --") - A+ \' S6 B+ r8 j9 M ( Y- R) o5 \. G6 L/ _* O3 j9 gif __name__ == "__main__": f; g- X0 q: o/ P9 U
. S$ P ]3 U3 h0 n7 B8 @. c0 \) ]
CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters/ Q8 A0 l; h. s7 P$ I9 Y9 P6 A5 M
5 j2 F5 \# n% ?0 m, |8 x: P$ @
up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables% |+ q- w7 V* R" i8 r3 R$ U
low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables ; [ e1 L( e9 r2 o1 U2 d) D" ?! o parameter = [CXPB, MUTPB, NGEN, popsize, low, up] ' M9 G/ u$ M( z. F+ r' I p, y& K9 ` 7 U+ z- H3 |2 L( f! ~% \7 E run = GA(parameter)' |# N' R& H# o
run.GA_main()6 X9 G: d% e H- F( O1 h. j
————————————————& {1 T1 W0 }. Q
版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 5 _8 X2 z5 c0 G2 ]# J* G3 E原文链接:https://blog.csdn.net/bible_reader/article/details/72782675 K* S( v' _4 Q, o! P% Y
P" n- g5 T& p. G+ b* }7 g" r* w. {% K0 P& q8 F$ d& ^# \