g_rec=[] # for recording x-data for plot, i.e. generation s_rec=[] # for recording y-data for plot, i.e. score or fitness ms_rec=[] # for recording mutation step size history #------------------------------------------------------------------------------- #--- part 3: the loop for (mu,la)-ES ------------------------------------------- #------------------------------------------------------------------------------- """ The big advantage of peabox can be seen in the inner loop below: it is super easily readable (for dude in offspring: copy .. mutate .. evaluate). Commenting is not required, because the code is so readable, it looks like pseudocode. This is the main purpose why I wrote this EA library. """ for g in range(50): # generation loop parents.sort() successrate=0. for dude in offspring: parentchoice=npr.randint(mu) dude.copy_DNA_of(parents[parentchoice]) dude.mutate(1,mstep) # mutate each gene with probability 1 and standard deviation in relation to search space width defined by mstep dude.evaluate() if dude < parents[parentchoice]: # comparison operators look at individual's score (the class Individual is just so written) successrate+=1 g_rec.append(g) s_rec.append(dude.score) ms_rec.append(mstep) successrate/=la if successrate > 1./5: # 1/5th success rule is popular because reasonable for evolution strategies mstep*=1.2 else:
ps = 40 # population size G = 80 # number of generations to go through parents = Population(Individual, ps, f11, searchspace) offspring = Population(Individual, ps, f11, searchspace) #------------------------------------------------------------------------------- #--- part 2: initialisation ---------------------------------------------------- #------------------------------------------------------------------------------- seed( 1 ) # seeding numpy's random number generator so we get reproducibly the same random numbers parents.new_random_genes() parents.eval_all() parents.sort() parents.update_no() sa_T = parents[-1].score - parents[0].score # starting temperature saga_ratio = 0.5 # fraction of offspring created by SA and not GA sa_mstep = 0.02 # mutation step size parameter sa_mprob = 0.6 # mutation probability ga_selp = 3. # selection pressure AE = 0.04 # annealing exponent --> exp(-AE) is multiplier for reducing temperature elite_size = 0 g_rec = [] # for recording x-data for plot, i.e. generation bs_rec = [] # for recording y-data for plot, here best score ws_rec = [] # for recording y-data for plot, here worst score T_rec = [] # for recording y-data for plot, here temperature ms_rec = [] # for recording y-data for plot, here mutation step size
print 'dude0<dude1 yields ',dude0<dude1,' and dude0.isbetter(dude1) yields ',dude0.isbetter(dude1) print 'dude0<dude2 yields ',dude0<dude2,' and dude0.isbetter(dude2) yields ',dude0.isbetter(dude2) print 'p.whatisfit and dude0.whatisfit are: ',p.whatisfit,dude0.whatisfit p.determine_whatisfit('max') print "now how does it look like after the spell 'p.determine_whatisfit('max')'?" print 'p.whatisfit and dude0.whatisfit are: ',p.whatisfit,dude0.whatisfit print 'and the comparisons from above?' print 'dude0<dude1 yields ',dude0<dude1,' and dude0.isbetter(dude1) yields ',dude0.isbetter(dude1) print 'dude0<dude2 yields ',dude0<dude2,' and dude0.isbetter(dude2) yields ',dude0.isbetter(dude2) print 2*'\n' print "the population's scores: ",sc # should give the list [ 1.22 1.32 0.53 0.17 1.81] print 'the population itself gets printed out like this:' print p print 'now sorting' p.sort() print p print 'now reversing' p.reverse() print p print '\n' print 'each dude has a number, its attribute "no", and each one has also a stored former number "oldno"' print 'dude.no: ',[dude.no for dude in p] print 'dude.oldno: ',[dude.oldno for dude in p] print "now let's update the numbering so it corresponds to the current sequence" p.update_no() print 'dude.no: ',[dude.no for dude in p] print 'dude.oldno: ',[dude.oldno for dude in p] print 'new look of the direct printout: ',p,' which is the output of "Population.__str__()"' print 2*'\n'
print 'p.whatisfit and dude0.whatisfit are: ', p.whatisfit, dude0.whatisfit p.determine_whatisfit('max') print "now how does it look like after the spell 'p.determine_whatisfit('max')'?" print 'p.whatisfit and dude0.whatisfit are: ', p.whatisfit, dude0.whatisfit print 'and the comparisons from above?' print 'dude0<dude1 yields ', dude0 < dude1, ' and dude0.isbetter(dude1) yields ', dude0.isbetter( dude1) print 'dude0<dude2 yields ', dude0 < dude2, ' and dude0.isbetter(dude2) yields ', dude0.isbetter( dude2) print 2 * '\n' print "the population's scores: ", sc # should give the list [ 1.22 1.32 0.53 0.17 1.81] print 'the population itself gets printed out like this:' print p print 'now sorting' p.sort() print p print 'now reversing' p.reverse() print p print '\n' print 'each dude has a number, its attribute "no", and each one has also a stored former number "oldno"' print 'dude.no: ', [dude.no for dude in p] print 'dude.oldno: ', [dude.oldno for dude in p] print "now let's update the numbering so it corresponds to the current sequence" p.update_no() print 'dude.no: ', [dude.no for dude in p] print 'dude.oldno: ', [dude.oldno for dude in p] print 'new look of the direct printout: ', p, ' which is the output of "Population.__str__()"' print 2 * '\n'
def parabolic(x): # the test function to be minimised return np.sum(x * x) dim = 8 # search space dimension searchspace = [('parameter' + str(i + 1), -1., +1.) for i in range(dim)] mu = 4 # size of parent population of (mu,lambda)-ES la = 12 # size of offspring population of (mu,lambda)-ES parents = Population(Individual, mu, parabolic, searchspace) offspring = Population(Individual, la, parabolic, searchspace) P = 1. # probability that a gene gets modified by the mutation operator mstep = 0.01 # mutation step size parameter parents.new_random_genes() parents.sort() #------------------------------------------------------------------------------- #--- part 2: the loop for (mu,la)-ES ------------------------------------------- #------------------------------------------------------------------------------- for g in range(50): # generation loop for dude in offspring: parentchoice = npr.randint( mu ) # all among the mu best of the old generation have an equal chance to reproduce dude.copy_DNA_of(parents[parentchoice]) dude.mutate( P, mstep ) # mutate each gene with probability 1 and standard deviation in relation to search space width defined by mstep dude.evaluate() offspring.sort()
G=41 # number of generations to go through dim=len(searchspace) parents=Population(Individual,ps,rastrigin,searchspace) offspring=Population(Individual,ps,rastrigin,searchspace) rw=RouletteWheel(dim) #------------------------------------------------------------------------------- #--- part 2: random starting point for search ---------------------------------- #--- and more initialisation --------------------------------------------------- #------------------------------------------------------------------------------- npr.seed(3) # seed differently or comment out if you want to see an algorithm's average performance over several runs parents.new_random_genes() parents.eval_all() parents.sort() print 'initial population:\nbest score = ',parents[0].score # change the plot interval to a low value, e.g. 1, if you want to see # the different characters of change patterns of the current best solution #ginter=G/5 # interval to take a snapshot of best solution (for plot variant 2) ginter=1 # interval to take a snapshot of best solution (for plot variants 1 and 3) glist=[]; bestDNAs=[]; bestscores=[] #------------------------------------------------------------------------------- #--- part 3: the GA generational loop ------------------------------------------ #--- step 1: generate offspring via CO-operator -------------------------------- #--- step 2: mutate offspring with rather small probability -------------------- #-------------------------------------------------------------------------------