3 D* @3 `0 ~' l7 j4、Python代码$ f! `9 a5 J' S. ^- I
#-*- coding:utf-8 -*-. o3 g; y7 i; b% p; |2 B
: X1 v+ Q' Y) H Z3 W
import random x7 A( c0 a6 Q- g
import math: c4 g# ^' v2 N8 b/ F+ j s
from operator import itemgetter( [) X3 M, b1 |* ~
A! A: q, p1 F0 P# e# _. M4 G
class Gene: - }; [8 I% ~% A" D8 f; ] '''0 j7 a4 |, i5 O" ?
This is a class to represent individual(Gene) in GA algorithom ! r; e- Q1 f2 r5 C each object of this class have two attribute: data, size" D6 z i5 L1 F" j
''' : O' |1 ]9 A' @; J3 v def __init__(self,**data): 2 O; s6 K3 G5 h$ U* O self.__dict__.update(data) 1 H7 {% U- J% h" N+ \& ^" K4 c self.size = len(data['data'])#length of gene & l9 a# G$ `* k+ e$ O . q. ^" r% y8 R) a# n3 F4 m, d) d3 _
class GA: / c6 m: I+ e# F- A k* _. ^4 k5 E ''' + A& ?! j! i; w This is a class of GA algorithm. 6 T. ~$ t6 ?; L: m '''; x6 @1 s- Q4 E/ i$ c8 f, C5 d
def __init__(self,parameter): 1 w. e' `3 i7 E, K4 C9 W1 s8 e ''' ) L8 C( m2 A% g* g/ f: K3 e8 \ Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value . 1 C& V7 a& x. B: Y4 y The data structure of pop is composed of several individuals which has the form like that: $ m& Q6 t# h+ j1 X3 y! o' m& c0 |. h: \4 F
{'Gene':a object of class Gene, 'fitness': 1.02(for example)} 5 ]8 X" F7 {; R' N8 w2 K Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2] ( W5 K; B5 K! Y+ o1 x3 }4 y D! z+ _! y1 S, w; J. h% O y
''' % }; k/ d- U4 Y; e5 X0 N #parameter = [CXPB, MUTPB, NGEN, popsize, low, up]. P& e' R8 O3 x' m& k
self.parameter = parameter 8 l+ N2 X# ?, w/ c( X T/ s7 @" t: W; F" n+ J0 }% P
low = self.parameter[4]3 b( u: k' m7 k0 `! g( D2 j
up = self.parameter[5] . Q/ O6 @6 @0 q6 n$ M$ u5 I9 [3 c* ]$ M" B) o
self.bound = [] , p4 G9 ~4 \( |# L) \0 U- k/ d! o: o self.bound.append(low) + U0 t" `* {& p7 \5 I1 U self.bound.append(up) * \7 O/ Y/ O# O3 J! U2 y$ h$ K! `7 u * R9 m3 i a5 S5 T" F% P' d0 a& [, T7 { pop = []/ x) Q% v6 ~, L/ H3 i: {
for i in range(self.parameter[3]):) N5 a$ c( m/ ?$ u3 l+ K: U
geneinfo = []' L" O0 I8 ^5 A- S# e
for pos in range(len(low)): 0 C0 S$ H7 n& J geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation6 Z7 T( }- K" U" A3 E
6 S s0 ~9 c' a6 w fitness = evaluate(geneinfo)#evaluate each chromosome+ Q* l4 B( Y# J! a
pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness 0 f1 P2 I. A( V4 v r+ i) f* i7 B: R6 t* |, k. W. _ M0 W2 K
self.pop = pop 9 ^+ u( s' N: E$ V! q3 M self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population$ v. E7 t3 P. r) }; [2 ]( @: Y
* h" ?3 `; P; B: P$ u
def selectBest(self, pop): + `! p; s$ p- m* X! E, W ''' 4 T. _9 b' Q( g9 |. _5 E6 o select the best individual from pop 8 t2 z+ }+ y4 B '''0 U! g9 m& w- A Z2 A) [. T5 M
s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False) 8 _" C" d4 n, B ?0 u' l return s_inds[0]! v3 N% e- m& E* d! M# M
4 U2 A+ l: s0 D0 p) | j def selection(self, individuals, k): $ p7 @. W/ e( v2 M% v% p, }' @7 e# P ''' # w0 h! D ?9 d1 v: c( A select two individuals from pop $ d3 ~9 w3 b8 S7 P1 e8 o ''' 1 u6 T. ^8 H! C$ x ^! B s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 9 M$ O% R) V6 a7 P" v; [1 e4 U; h
sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop $ m* K! k7 ?/ B4 j5 Y9 ?4 w: }+ m& C' X- B! n; |
chosen = []; @8 q& Q+ F4 Q) @3 B# a
for i in xrange(k): , P0 n1 j$ Y G6 X. l) j0 E u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits] ) b6 s, j8 u3 q5 C T$ ] sum_ = 0 . y# q0 d3 ?, g5 t* y$ `( s0 A! A for ind in s_inds:2 a- s3 s+ B7 i% \" j' z
sum_ += 1/ind['fitness']#sum up the 1/fitness : J0 @8 K' `8 U if sum_ > u: 7 T; y2 c& {+ | #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 % P1 p; p! o6 @7 ^2 N @) G3 o chosen.append(ind) 2 p6 F; Z1 b* r8 g- o: R break9 t v5 f+ ~, f
* v1 Y+ {7 W" ]& D1 d8 u9 L! b C
return chosen W* b/ Z7 H& p. j ]" {
, Q& Z! M6 I8 |6 ^
/ Q+ S' A+ p' v. @% C( H def crossoperate(self, offspring):: B2 j! ^1 ~, w; l/ p$ b; p& G( g! x
'''& \0 {$ ^' o+ r, g% e
cross operation 9 |6 s/ C2 E8 u, E' I( G ''' " s) w6 `. D. H0 s/ v5 N, ~# D dim = len(offspring[0]['Gene'].data)2 T* y" |- z' ?' C9 k6 U& Q
& M E9 l% {" W
geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop , Y1 B$ Z. @) `9 z9 ^ geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop4 ^" a1 T% q. @
& \( R$ f: b, p5 S
pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 6 C2 L6 }8 ^6 f; y. d pos2 = random.randrange(1,dim) 2 d+ U& x) m& D$ v* G3 h2 q 3 E2 F' d9 p3 T$ _3 { newoff = Gene(data = [])#offspring produced by cross operation7 d, j' U8 ~) r* W+ X7 T- @
temp = []) u9 A* n$ i* S6 Q ?) h' M8 i
for i in range(dim):# [- \/ s5 |2 [& k) q
if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):( u& O& i: X- n3 j& z- o( {, e3 E. W
temp.append(geninfo2) 8 m1 T& O% {& |* V #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)] 8 h7 O: n' D# E0 \, @. N: `7 ` else:+ y6 b" U- ]5 ?3 Q
temp.append(geninfo1)7 @8 d/ g! ~: i: @# \
#the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)] 8 q& G1 F2 I' |5 R3 d% i$ F newoff.data = temp. f4 \9 ~6 f M
4 K$ r, T2 p' S+ S9 M, h+ s4 @
return newoff3 D x' H7 D- F O# O: G$ ]- ^
7 \! x9 R3 P' r o: Y/ C9 w5 n
* E, m; x' E4 X" f, F def mutation(self, crossoff, bound):( w. l3 G1 z9 v) p. q# r; c, [
''' ) {; ?# n& r0 X) Z" d3 A8 ~; ` mutation operation , v3 ?- l+ L# K2 Q '''5 f& N! p0 i+ n; }
" L0 n8 o/ a8 e* y, X
dim = len(crossoff.data): X2 K6 N- O, I( B, T8 P! M# K5 q& ?4 B
+ T# i) H+ N/ {6 ~( ~
pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation. ' l7 c5 y4 q+ D8 {. V2 s 7 e+ s9 }, J* D crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos]) + M9 x: E" [' B$ J* ? return crossoff/ I/ ~9 q+ H- S d2 V( m0 ?) R
: p! e- z% w( P6 ^* }5 W$ O: ] def GA_main(self):1 ]1 j1 D/ h- ~1 k1 f
''' 4 i. f! S4 d7 n5 B' }$ x main frame work of GA* P. J( y' u0 m2 |# ^+ g
''' " x. k' a& q t" @/ B+ y! b* c / Z7 I9 v% s7 s% U2 i popsize = self.parameter[3]0 |7 s3 A, W6 j2 n) i
- _9 ~5 o2 R; o- ?( {6 k print("Start of evolution") . ^. c8 U3 v7 Q) r, s ( s$ s6 F' p9 | H1 Q! e3 D. U # Begin the evolution1 r2 D8 Q2 \' L0 I6 Q
for g in range(NGEN): # [; E! g5 W! T7 ]# s1 T/ s1 t - A/ ]* V4 u7 E( d! u* I. { print("-- Generation %i --" % g) % b3 F1 I0 O/ w, q9 R. L ( c. g, y9 v' H. f K! y9 u: x; K #Apply selection based on their converted fitness: c2 M- {+ `6 w
selectpop = self.selection(self.pop, popsize) 8 [4 h9 G- j' M; Q! Q0 U- v# l2 { ( |3 C5 N. f( ~: J. w0 P nextoff = [] ' m0 l6 P/ K9 w* r/ ]7 S# J
while len(nextoff) != popsize: 0 E- w7 V0 }7 A # Apply crossover and mutation on the offspring ) K* H7 P% f- B9 B1 E9 }5 A- o1 d" z/ {
# Select two individuals2 G0 p( F4 u) n, ]2 v
offspring = [random.choice(selectpop) for i in xrange(2)] & W! H" W) z4 K' k* ?" A2 ~ [& F& j% Q3 W1 h$ g) d( n, p3 h
if random.random() < CXPB: # cross two individuals with probability CXPB: X: \6 K6 ]7 M& U
crossoff = self.crossoperate(offspring) $ E) g% g" s7 L6 a9 U: |1 { fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals 5 K1 g d' s+ s% s3 v" l5 _0 m6 g& ?4 `0 a# \8 ~" F1 N
if random.random() < MUTPB: # mutate an individual with probability MUTPB - \7 l! C2 I, f, n6 z9 P muteoff = self.mutation(crossoff,self.bound) . A7 h; Z, }% i fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals: @/ q- U3 S' V; v* {7 B5 u/ P) Q
nextoff.append({'Gene':muteoff,'fitness':fit_muteoff}) 6 T E( ]: O( ]9 E3 p* b" w2 i9 g# L& k$ Z6 f
# The population is entirely replaced by the offspring4 |, m' H" q- t+ {5 i3 i
self.pop = nextoff y7 M% `0 z# f
* \* t. Z- K9 D1 {
# Gather all the fitnesses in one list and print the stats , G: I! j9 R5 e: ]0 z! y4 M# N* J fits = [ind['fitness'] for ind in self.pop]) f; l" m. e3 v9 B" i5 J+ w
% P6 S* f* p, X I length = len(self.pop)) R! d' V( A" V% t9 g+ t# F
mean = sum(fits) / length3 G% i/ Y X# T$ V& p3 ]. O6 @
sum2 = sum(x*x for x in fits)* }$ `3 T( k; L" b8 V. {8 j
std = abs(sum2 / length - mean**2)**0.5 ( L5 |& S$ Q7 b! z3 g7 G# o7 y6 C best_ind = self.selectBest(self.pop)7 `4 k3 R( ] j% [) x9 k
5 J5 a6 f. Q; k, C1 a2 \% D9 K if best_ind['fitness'] < self.bestindividual['fitness']: ) q* M, c( K% @ self.bestindividual = best_ind 9 F- g6 B9 q5 i% u2 e) c z3 X, j O6 v7 T5 v print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness'])) A; [. \3 ^& u ~8 c
print(" Min fitness of current pop: %s" % min(fits))) z* l8 u8 {' n d2 O5 ^! D
print(" Max fitness of current pop: %s" % max(fits)) [1 _, `5 L/ |2 }3 s' s) v
print(" Avg fitness of current pop: %s" % mean) : B4 [. A1 f/ m6 [$ q& {" ^, s1 s print(" Std of currrent pop: %s" % std) % \& v9 b- T, e! x. o* F- F# x/ f0 n1 _% I! m5 [: g u% b% s. }# k( c d
print("-- End of (successful) evolution --") $ ?7 Z6 F! w! p2 s) p: P6 Y8 L: f- V$ K- w
if __name__ == "__main__":" n4 p" r1 n* T( W& Z$ _/ N- ^- m
; y* w: k" Q& y, s( V+ m CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters ' ?0 t; K/ O9 C9 I% J8 I) K4 I* I3 @( S. s3 X* o, p
up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables ) R# Q T% x6 _% K low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables/ _, t3 {" G! P3 H1 ^
parameter = [CXPB, MUTPB, NGEN, popsize, low, up] ' P! U# F( H4 W" D; L. O& w) r; ?4 S; y! g% k* B
run = GA(parameter) 8 n) |. i6 O. w run.GA_main() . Z: H2 |9 T' Z9 \) V+ _. B———————————————— $ Y3 L7 v E9 d; F* l6 T版权声明:本文为CSDN博主「bible_reader」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ S: o7 f* `4 F) w
原文链接:https://blog.csdn.net/bible_reader/article/details/727826754 T: t" W: j$ E5 x5 M
& W- o8 Y4 E# m1 J6 K# w ; q2 J2 ~$ b1 z. h6 C( i( j1 h