def lambdacommamu(pop, Optimizer): """Selection function to employ a lambda,mu GA scheme """ fits = [ind.fitness for ind in pop] minindex = [i for i in range(len(pop)) if pop[i].fitness==min(fits)] try: Optimizer.mark except: Optimizer.mark = len(pop)/2 parents = pop[0:Optimizer.mark] offspring = pop[Optimizer.mark::] if minindex < Optimizer.mark: offspring.append(pop[minindex]) if len(offspring) < Optimizer.nindiv: diff = Optimizer.nindiv-len(offspring) if Optimizer.natural_selection_scheme=='elitism': addins = get_best(parents,diff) STR = 'Adding in '+repr(diff)+' lowest fitness parents\n' else: addins = selection_switch(parents, diff, Optimizer.natural_selection_scheme, Optimizer) STR = 'Adding in '+repr(diff)+' parents based on natural selection\n' for one in addins: offspring.append(one) elif len(offspring) > Optimizer.nindiv: diff = len(offspring)-Optimizer.nindiv if Optimizer.natural_selection_scheme=='elitism': offspring = get_best(offspring,Optimizer.nindiv) STR = 'Removing lowest '+repr(diff)+' fitness offspring\n' else: offspring = selection_switch(offspring, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) STR = 'Removing '+repr(diff)+' offspring by natural selection\n' else: STR = 'Number of offspring = {0}\n'.format(len(offspring)) return offspring, STR
def rank(pop, nkeep, Optimizer): """Selection function that chooses structures to survive and orders them based on their relative ranking """ pop = get_best(pop,len(pop)) newpop = [] prob = [] cumprob = [] for i in range(len(pop)): rankprob = float((nkeep-i)) / float(sum(range(nkeep+1))) prob.append(rankprob) cumprob.append(sum(prob)) prevcounter = None for i in range(nkeep): rand = random.random() counter = 0 while cumprob[counter] < rand: counter += 1 if prevcounter==counter: while True: a = random.choice(pop) if a.index != prevcounter: break newpop.append(random.choice(pop)) prevcounter = a.index else: newpop.append(pop[counter]) prevcounter = counter return newpop
def rank(pop, nkeep, Optimizer): """Selection function that chooses structures to survive and orders them based on their relative ranking """ pop = get_best(pop, len(pop)) newpop = [] prob = [] cumprob = [] for i in range(len(pop)): rankprob = float((nkeep - i)) / float(sum(range(nkeep + 1))) prob.append(rankprob) cumprob.append(sum(prob)) prevcounter = None for i in range(nkeep): rand = random.random() counter = 0 while cumprob[counter] < rand: counter += 1 if prevcounter == counter: while True: a = random.choice(pop) if a.index != prevcounter: break newpop.append(random.choice(pop)) prevcounter = a.index else: newpop.append(pop[counter]) prevcounter = counter return newpop
def fitpred_new(pop, Optimizer): """Predator function to identify similar structures based on energy and replace one with new structure. """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR += 'Predator: Removed total of ' + repr( len(fitlist) - len(nfitlist)) + ' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR += 'Predator: Removed ' + repr(pop[i].history_index) + '\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: if Optimizer.structure == 'Defect' or Optimizer.structure == 'Cluster': ind = gen_pop_box(Optimizer.atomlist, Optimizer.size) elif Optimizer.structure == 'Crystal': outts = gen_pop_box(Optimizer.atomlist, Optimizer.size, Optimizer.cell_shape_options) ind = outts[0] elif Optimizer.structure == 'Surface': mutopto = Optimizer.mutation_options Optimizer.mutation_options = ['Lattice_Alteration_rdrd'] topind = random.choice(pop)[0].copy() ind, scheme = moves_switch(topind, Optimizer) Optimizer.mutation_options = mutopto individ = Individual(ind) #CHECK THIS LATER!! MAY NEED TO ADD MORE PROPERTIES!! individ.energy = 1000 individ.fitness = 1000 newpop.append(individ) STR += 'Predator: Adding mutated duplicates to new pop history=' + individ.history_index + '\n' nindices.append(individ.index) nindices.sort() if Optimizer.natural_selection_scheme == 'fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer, ind, Optimizer.fpbin, Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index, n in enumerate(nindices) if n > Optimizer.nindiv - 1 ][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR += str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop, len(pop)) return pop, STR
def cost(pop, nkeep, Optimizer): """Selection function to order and select structures based on simple relative cost """ pop = get_best(pop,len(pop)) newpop = [] fitnesses = [ind.fitness for ind in pop] prob = [] cumprob = [] try: norms = [fit - pop[nkeep+1].fitness for fit in fitnesses[0:nkeep]] except: norms = [fit - pop[nkeep-1].fitness for fit in fitnesses[0:nkeep]] sumn = sum(norms) for i in range(nkeep): prob.append(norms[i] / sumn) cumprob.append(sum(prob)) prevcounter = [] for i in range(nkeep): rand = random.random() counter = 0 while cumprob[counter] < rand: counter += 1 if counter in prevcounter: a = random.choice(pop) newpop.append(a) prevcounter.append(a.index) else: newpop.append(pop[counter]) prevcounter.append(counter) return newpop
def cost(pop, nkeep, Optimizer): """Selection function to order and select structures based on simple relative cost """ pop = get_best(pop, len(pop)) newpop = [] fitnesses = [ind.fitness for ind in pop] prob = [] cumprob = [] try: norms = [fit - pop[nkeep + 1].fitness for fit in fitnesses[0:nkeep]] except: norms = [fit - pop[nkeep - 1].fitness for fit in fitnesses[0:nkeep]] sumn = sum(norms) for i in range(nkeep): prob.append(norms[i] / sumn) cumprob.append(sum(prob)) prevcounter = [] for i in range(nkeep): rand = random.random() counter = 0 while cumprob[counter] < rand: counter += 1 if counter in prevcounter: a = random.choice(pop) newpop.append(a) prevcounter.append(a.index) else: newpop.append(pop[counter]) prevcounter.append(counter) return newpop
def random_pick(pop, nkeep, Optimizer): """Selection function that randomly choose structures from a population to survive. """ pop = get_best(pop,len(pop)) newpop = [] for i in range(nkeep): sel = random.choice(pop) newpop.append(sel) return newpop
def random_pick(pop, nkeep, Optimizer): """Selection function that randomly choose structures from a population to survive. """ pop = get_best(pop, len(pop)) newpop = [] for i in range(nkeep): sel = random.choice(pop) newpop.append(sel) return newpop
def fitpred_bests(pop,Optimizer): """Predator function to identify similar structures based on energy and replace one with structure from BESTS List. """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) count = 0 while len(newpop) < Optimizer.nindiv: try: Optimizer.BESTS except: Optimizer.BESTS=[] if len(Optimizer.BESTS) > 0: idx = random.choice(range(len(Optimizer.BESTS))) newpop.append(Optimizer.BESTS[idx]) STR+='Predator: Adding in structure from Best List from position = {0} with fitness = {1}\n'.format(idx,Optimizer.BESTS[idx].fitness) newindices.append(len(pop)+count) count+=1 else: indiv = random.choice(otherlist).duplicate() indiv, scheme = moves_switch(indiv,Optimizer) indiv.energy = 1000 indiv.fitness = 1000 newpop.append(indiv) STR+='Predator: Adding mutated duplicates to new pop history='+indiv.history_index+'\n' nindices.append(indiv.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) return pop, STR
def lambdacommamu(pop, Optimizer): """Selection function to employ a lambda,mu GA scheme """ fits = [ind.fitness for ind in pop] minindex = [i for i in range(len(pop)) if pop[i].fitness == min(fits)] try: Optimizer.mark except: Optimizer.mark = len(pop) / 2 parents = pop[0:Optimizer.mark] offspring = pop[Optimizer.mark::] if minindex < Optimizer.mark: offspring.append(pop[minindex]) if len(offspring) < Optimizer.nindiv: diff = Optimizer.nindiv - len(offspring) if Optimizer.natural_selection_scheme == 'elitism': addins = get_best(parents, diff) STR = 'Adding in ' + repr(diff) + ' lowest fitness parents\n' else: addins = selection_switch(parents, diff, Optimizer.natural_selection_scheme, Optimizer) STR = 'Adding in ' + repr( diff) + ' parents based on natural selection\n' for one in addins: offspring.append(one) elif len(offspring) > Optimizer.nindiv: diff = len(offspring) - Optimizer.nindiv if Optimizer.natural_selection_scheme == 'elitism': offspring = get_best(offspring, Optimizer.nindiv) STR = 'Removing lowest ' + repr(diff) + ' fitness offspring\n' else: offspring = selection_switch(offspring, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) STR = 'Removing ' + repr( diff) + ' offspring by natural selection\n' else: STR = 'Number of offspring = {0}\n'.format(len(offspring)) return offspring, STR
def fitpred_new(pop,Optimizer): """Predator function to identify similar structures based on energy and replace one with new structure. """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: if Optimizer.structure=='Defect' or Optimizer.structure=='Cluster': ind=gen_pop_box(Optimizer.atomlist,Optimizer.size) elif Optimizer.structure=='Crystal': outts=gen_pop_box(Optimizer.atomlist,Optimizer.size,Optimizer.cell_shape_options) ind=outts[0] elif Optimizer.structure=='Surface': mutopto=Optimizer.mutation_options Optimizer.mutation_options=['Lattice_Alteration_rdrd'] topind=random.choice(pop)[0].copy() ind, scheme = moves_switch(topind,Optimizer) Optimizer.mutation_options=mutopto individ=Individual(ind) #CHECK THIS LATER!! MAY NEED TO ADD MORE PROPERTIES!! individ.energy=1000 individ.fitness=1000 newpop.append(individ) STR+='Predator: Adding mutated duplicates to new pop history='+individ.history_index+'\n' nindices.append(individ.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) return pop, STR
def mutation_dups_adapt_stem(pop, Optimizer): """Predator function that removes individuals based on fitness and mutates replacements """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: indiv = random.choice(otherlist).duplicate() indiv, scheme = moves_switch(indiv,Optimizer) indiv.energy = 1000 indiv.fitness = 1000 newpop.append(indiv) STR+='Predator: Adding mutated duplicates to new pop history='+indiv.history_index+'\n' nindices.append(indiv.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) indiv = pop[0] if (indiv.fitness/indiv.energy <2.0): from MAST.structopt.tools.StemCalc import find_stem_coeff outs = find_stem_coeff(Optimizer,indiv) ind = outs[1] Optimizer.stem_coeff = outs[0] STR+='Readjusting STEM Coeff = {0}'.format(Optimizer.stem_coeff)) return pop, STR
def best(pop, nkeep, Optimizer=None): """Selection function to select the best individuals in a population Inputs: pop = list of Individual class structures nkeep = number of Individuals to keep in the population must be less than or equal to the number of individuals currently in the population Optimizer = dummy placeholder Outputs: npop = population with desired number of individuals """ if nkeep <= len(pop): npop = get_best(pop,nkeep) else: print 'WARNING: selection.best nkeep > pop. Returning pop' npop = pop return npop
def best(pop, nkeep, Optimizer=None): """Selection function to select the best individuals in a population Inputs: pop = list of Individual class structures nkeep = number of Individuals to keep in the population must be less than or equal to the number of individuals currently in the population Optimizer = dummy placeholder Outputs: npop = population with desired number of individuals """ if nkeep <= len(pop): npop = get_best(pop, nkeep) else: print 'WARNING: selection.best nkeep > pop. Returning pop' npop = pop return npop
def mutation_dups_zp(pop, Optimizer): """Predator function that selects individuals that are too similar based fitness and replaces them with a zero point rotation of the structure """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: indiv = random.choice(otherlist).duplicate() mutopts = Optimizer.mutation_options Optimizer.mutation_options = ['ZP_Rotation'] indiv = moves_switch(indiv, Optimizer) Optimizer.mutation_options = mutopts newpop.append(indiv) nindices.append(indiv.index) STR+='Predator: Adding mutated duplicates to new pop history='+indiv.history_index+'\n' nindices.sort() if Optimizer.natural_selection_scheme=='FUSSF': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) return pop, STR
def mutation_dups_energy(pop, Optimizer): """Predator function that removes duplicates based on energy and replaces with mutations """ fitlist = [one.energy for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: indiv = random.choice(otherlist).duplicate() indiv, scheme = moves_switch(indiv,Optimizer) indiv.energy = 1000 indiv.fitness = 1000 newpop.append(indiv) STR+='Predator: Adding mutated duplicates to new pop history='+indiv.history_index+'\n' nindices.append(indiv.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) return pop, STR
def fingerprint_niche(pop, Optimizer): """Use a k-means clustering approach to identify individuals for new population""" STR = '' #Get coordinates for each individual pts = [] for one in pop: fpd = fingerprint_dist(pop[0].fingerprint,one.fingerprint) pts.append([one.fitness - pop[0].fitness,fpd]) for one in pts: if numpy.isnan(one[1]): one[1] = 0 #Identify spatial bounds mins = min(pts) maxs = max(pts) attemptcount=10 passflag=False while attemptcount > 0: #Select random initial centroid locations cents = [] #for i in range(Optimizer.nindiv): # cents.append([random.uniform(mins[0],maxs[0]),random.uniform(mins[1],maxs[1])]) while len(cents) < Optimizer.nindiv: a = random.choice(pts) if a not in cents: cents.append(a) #Assign individual to closest centroid clustlist = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(cents)): d = ((one[0] - cents[i][0])**2 + (one[1] - cents[i][1])**2)**0.5 ds.append([d,i]) ds = sorted(ds, key=lambda two: two[0]) loc = ds[0] clustlist[loc[1]].append(one) try: count = 0 while True: count += 1 #Calculate the centroid of the new cluster centsnew = [] for one in clustlist: if len(one) > 0: m = [1.0]*len(one) #cop = numpy.dot(m, one) / sum(m) cop = [sum([es for es,fps in one]) / sum(m),sum([fps for es,fps in one]) / sum(m)] centsnew.append(cop) else: centsnew.append(one) #Assign individuals to new centroids clustlistn=[[] for i in range(Optimizer.nindiv)] for one in pts: ds=[] for i in range(len(centsnew)): d = ((one[0] - centsnew[i][0])**2 + (one[1] - centsnew[i][1])**2)**0.5 ds.append([d,i]) ds = sorted(ds, key=lambda two: two[0]) loc = ds[0] clustlistn[loc[1]].append(one) if clustlistn==clustlist: clustlist = clustlistn centroids = centsnew attemptcount=-10 passflag=True break else: clustlist = clustlistn except: attemptcount-=1 STR+= 'WARNING: PREDATOR: K-means cluster difficulty\n' if passflag==True: #Select one individual from each cluster news = [] for one in clustlist: #Random #npop.append(random.choice(one)) #Minimum energy opts = sorted(one, key=lambda two: two[0]) news.append(opts[0]) indices = [] for one in news: for i in range(len(pts)): if pts[i]==one: indices.append(i) break npop = [pop[ind] for ind in indices] else: STR+='WARNING: PREDATOR: Population converging. Unable to find nindiv distinct clusters\n' npop = mutation_dups(pop,Optimizer) #npop = pop STR+='WARNING: PREDATOR: Chose new population based on Mutation-Dups predator\n' pop = get_best(npop,len(npop)) return pop, STR
def energy_cluster(pop, Optimizer): """Use a k-means clustering approach to identify individuals for new population """ #Get coordinates for each individual pts = [ind.energy for ind in pop] #Identify spatial bounds mins = min(pts) maxs = max(pts) STR='' attemptcount=10 passflag=False while attemptcount > 0: #Select random initial centroid locations cents = [] while len(cents) < Optimizer.nindiv: a = random.choice(pts) if a not in cents: cents.append(a) #Assign individual to closest centroid clustlist = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(cents)): d = abs(one - cents[i]) ds.append([d,i]) ds.sort() loc = ds[0] clustlist[loc[1]].append(one) try: count = 0 while True: count += 1 #Calculate the centroid of the new cluster centsnew = [] for one in clustlist: if len(one) > 0: m = [1.0]*len(one) #cop = numpy.dot(m, one) / sum(m) cop = [sum([es for es in one]) / sum(m)] centsnew.append(cop) else: centsnew.append(one) #Assign individuals to new centroids clustlistn=[[] for i in range(Optimizer.nindiv)] for one in pts: ds=[] for i in range(len(centsnew)): d = abs(one - cents[i]) ds.append([d,i]) ds.sort() loc = ds[0] clustlistn[loc[1]].append(one) if clustlistn==clustlist: clustlist = clustlistn centroids = centsnew attemptcount=-10 passflag=True break else: clustlist = clustlistn except: attemptcount-=1 STR+='WARNING: PREDATOR: K-means cluster difficulty\n' print 'WARNING: PREDATOR: K-means cluster difficulty' if passflag==True: #Select one individual from each cluster news = [] for one in clustlist: #Random news.append(random.choice(one)) #Minimum energy #one.sort() #news.append(one[0]) indices = [] for one in news: for i in range(len(pts)): if pts[i]==one: indices.append(i) break npop = [pop[ind] for ind in indices] else: STR+='WARNING: PREDATOR: Population converging. Unable to find nindiv distinct clusters\n' npop,str1 = Mutation_Dups(pop,Optimizer) STR+=str1 #npop=pop STR+='WARNING: PREDATOR: Chose new population based on Mutation-Dups predator\n' pop = get_best(npop,len(npop)) return pop
if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: STR+='Predator: Adding duplicates back\n' choice = random.choice(otherlist) if choice.index not in nindices: newpop.append(choice) nindices.append(choice.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop,str = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) Optimizer.output.write(STR) return pop
def mutation_dups_quench(pop, Optimizer): """Predator function that removes individuals based on fitness and mutates replacements Also quenches top individuals """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR+='Predator: Removed total of '+repr(len(fitlist)-len(nfitlist))+' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR+='Predator: Removed '+repr(pop[i].history_index)+'\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: indiv = random.choice(otherlist).duplicate() indiv, scheme = moves_switch(indiv,Optimizer) indiv.energy = 1000 indiv.fitness = 1000 newpop.append(indiv) STR+='Predator: Adding mutated duplicates to new pop history='+indiv.history_index+'\n' nindices.append(indiv.index) nindices.sort() if Optimizer.natural_selection_scheme=='fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer,ind,Optimizer.fpbin,Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index,n in enumerate(nindices) if n > Optimizer.nindiv-1][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR+=str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop,len(pop)) if Optimizer.genrep >10: from MAST.structopt.moves.quench import quench import os olammpsvar = os.environ['LAMMPS_COMMAND'] try: from mpi4py import MPI if '-n' in olammpsvar: lcommand = olammpsvar.split('-n') lcommand[1]=lcommand[1].split() nproc = MPI.COMM_WORLD.Get_size() os.environ['LAMMPS_COMMAND'] = '{0}-n {1} {2}'.format(lcommand[0],nproc,lcommand[1][1]) except: pass oqns2 = Optimizer.quench_n_steps_2 Optimizer.quench_n_steps_2 = 100000 opar = Optimizer.parallel Optimizer.parallel = False for i in range(3): pop[i] = quench(pop[i],Optimizer) Optimizer.quench_n_steps_2 = oqns2 os.environ['LAMMPS_COMMAND'] = olammpsvar Optimizer.parallel = opar return pop, STR
def energy_cluster(pop, Optimizer): """Use a k-means clustering approach to identify individuals for new population """ #Get coordinates for each individual pts = [ind.energy for ind in pop] #Identify spatial bounds mins = min(pts) maxs = max(pts) STR = '' attemptcount = 10 passflag = False while attemptcount > 0: #Select random initial centroid locations cents = [] while len(cents) < Optimizer.nindiv: a = random.choice(pts) if a not in cents: cents.append(a) #Assign individual to closest centroid clustlist = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(cents)): d = abs(one - cents[i]) ds.append([d, i]) ds.sort() loc = ds[0] clustlist[loc[1]].append(one) try: count = 0 while True: count += 1 #Calculate the centroid of the new cluster centsnew = [] for one in clustlist: if len(one) > 0: m = [1.0] * len(one) #cop = numpy.dot(m, one) / sum(m) cop = [sum([es for es in one]) / sum(m)] centsnew.append(cop) else: centsnew.append(one) #Assign individuals to new centroids clustlistn = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(centsnew)): d = abs(one - cents[i]) ds.append([d, i]) ds.sort() loc = ds[0] clustlistn[loc[1]].append(one) if clustlistn == clustlist: clustlist = clustlistn centroids = centsnew attemptcount = -10 passflag = True break else: clustlist = clustlistn except: attemptcount -= 1 STR += 'WARNING: PREDATOR: K-means cluster difficulty\n' print 'WARNING: PREDATOR: K-means cluster difficulty' if passflag == True: #Select one individual from each cluster news = [] for one in clustlist: #Random news.append(random.choice(one)) #Minimum energy #one.sort() #news.append(one[0]) indices = [] for one in news: for i in range(len(pts)): if pts[i] == one: indices.append(i) break npop = [pop[ind] for ind in indices] else: STR += 'WARNING: PREDATOR: Population converging. Unable to find nindiv distinct clusters\n' npop, str1 = Mutation_Dups(pop, Optimizer) STR += str1 #npop=pop STR += 'WARNING: PREDATOR: Chose new population based on Mutation-Dups predator\n' pop = get_best(npop, len(npop)) return pop
def fingerprint_niche(pop, Optimizer): """Use a k-means clustering approach to identify individuals for new population""" STR = '' #Get coordinates for each individual pts = [] for one in pop: fpd = fingerprint_dist(pop[0].fingerprint, one.fingerprint) pts.append([one.fitness - pop[0].fitness, fpd]) for one in pts: if numpy.isnan(one[1]): one[1] = 0 #Identify spatial bounds mins = min(pts) maxs = max(pts) attemptcount = 10 passflag = False while attemptcount > 0: #Select random initial centroid locations cents = [] #for i in range(Optimizer.nindiv): # cents.append([random.uniform(mins[0],maxs[0]),random.uniform(mins[1],maxs[1])]) while len(cents) < Optimizer.nindiv: a = random.choice(pts) if a not in cents: cents.append(a) #Assign individual to closest centroid clustlist = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(cents)): d = ((one[0] - cents[i][0])**2 + (one[1] - cents[i][1])**2)**0.5 ds.append([d, i]) ds = sorted(ds, key=lambda two: two[0]) loc = ds[0] clustlist[loc[1]].append(one) try: count = 0 while True: count += 1 #Calculate the centroid of the new cluster centsnew = [] for one in clustlist: if len(one) > 0: m = [1.0] * len(one) #cop = numpy.dot(m, one) / sum(m) cop = [ sum([es for es, fps in one]) / sum(m), sum([fps for es, fps in one]) / sum(m) ] centsnew.append(cop) else: centsnew.append(one) #Assign individuals to new centroids clustlistn = [[] for i in range(Optimizer.nindiv)] for one in pts: ds = [] for i in range(len(centsnew)): d = ((one[0] - centsnew[i][0])**2 + (one[1] - centsnew[i][1])**2)**0.5 ds.append([d, i]) ds = sorted(ds, key=lambda two: two[0]) loc = ds[0] clustlistn[loc[1]].append(one) if clustlistn == clustlist: clustlist = clustlistn centroids = centsnew attemptcount = -10 passflag = True break else: clustlist = clustlistn except: attemptcount -= 1 STR += 'WARNING: PREDATOR: K-means cluster difficulty\n' if passflag == True: #Select one individual from each cluster news = [] for one in clustlist: #Random #npop.append(random.choice(one)) #Minimum energy opts = sorted(one, key=lambda two: two[0]) news.append(opts[0]) indices = [] for one in news: for i in range(len(pts)): if pts[i] == one: indices.append(i) break npop = [pop[ind] for ind in indices] else: STR += 'WARNING: PREDATOR: Population converging. Unable to find nindiv distinct clusters\n' npop = mutation_dups(pop, Optimizer) #npop = pop STR += 'WARNING: PREDATOR: Chose new population based on Mutation-Dups predator\n' pop = get_best(npop, len(npop)) return pop, STR
def fitpred(pop,Optimizer): """Predator function to select best structures """ pop = get_best(pop,Optimizer.nindiv) return pop, ''
def mutation_dups_quench(pop, Optimizer): """Predator function that removes individuals based on fitness and mutates replacements Also quenches top individuals """ fitlist = [one.fitness for one in pop] nfitlist, nindices = remove_duplicates(fitlist, Optimizer.demin) STR = '' newpop = [] if len(nfitlist) != len(fitlist): STR += 'Predator: Removed total of ' + repr( len(fitlist) - len(nfitlist)) + ' from population\n' otherlist = [] for i in range(len(pop)): if i not in nindices: STR += 'Predator: Removed ' + repr(pop[i].history_index) + '\n' otherlist.append(pop[i]) else: newpop.append(pop[i]) while len(newpop) < Optimizer.nindiv: indiv = random.choice(otherlist).duplicate() indiv, scheme = moves_switch(indiv, Optimizer) indiv.energy = 1000 indiv.fitness = 1000 newpop.append(indiv) STR += 'Predator: Adding mutated duplicates to new pop history=' + indiv.history_index + '\n' nindices.append(indiv.index) nindices.sort() if Optimizer.natural_selection_scheme == 'fussf': for ind in newpop: if ind.fingerprint == 0: ind.fingerprint = get_fingerprint(Optimizer, ind, Optimizer.fpbin, Optimizer.fpcutoff) if 'lambda,mu' in Optimizer.algorithm_type: try: mark = [ index for index, n in enumerate(nindices) if n > Optimizer.nindiv - 1 ][0] except: mark = Optimizer.nindiv Optimizer.mark = mark pop, str1 = lambdacommamu.lambdacommamu(newpop, Optimizer) STR += str1 else: pop = selection_switch(newpop, Optimizer.nindiv, Optimizer.natural_selection_scheme, Optimizer) pop = get_best(pop, len(pop)) if Optimizer.genrep > 10: from MAST.structopt.moves.quench import quench import os olammpsvar = os.environ['LAMMPS_COMMAND'] try: from mpi4py import MPI if '-n' in olammpsvar: lcommand = olammpsvar.split('-n') lcommand[1] = lcommand[1].split() nproc = MPI.COMM_WORLD.Get_size() os.environ['LAMMPS_COMMAND'] = '{0}-n {1} {2}'.format( lcommand[0], nproc, lcommand[1][1]) except: pass oqns2 = Optimizer.quench_n_steps_2 Optimizer.quench_n_steps_2 = 100000 opar = Optimizer.parallel Optimizer.parallel = False for i in range(3): pop[i] = quench(pop[i], Optimizer) Optimizer.quench_n_steps_2 = oqns2 os.environ['LAMMPS_COMMAND'] = olammpsvar Optimizer.parallel = opar return pop, STR
def generation_eval(self, pop): global logger emx = max(ind.energy for ind in pop) emn = min(ind.energy for ind in pop) for ind in pop: ind.tenergymx = emx ind.tenergymin = emn #DEBUG: Write relaxed individual if 'MA' in self.debug: if self.generation > 0: inp_out.write_xyz(self.debugfile,pop[self.nindiv][0],\ 'First Relaxed Offspring '+repr(pop[self.nindiv-1].energy)) #DEBUG: Write relaxed ind in solid if self.structure=='Defect' or self.structure=='Surface': inp_out.write_xyz(self.debugfile,pop[self.nindiv].bulki,\ 'First Relaxed bulki '+repr(pop[self.nindiv-1].energy)) sols = pop[self.nindiv][0].copy() sols.extend(pop[self.nindiv].bulki) inp_out.write_xyz(self.debugfile,sols,'First from Invalid-ind + Bulki '+\ repr(pop[self.nindiv].energy)) sols = pop[self.nindiv][0].copy() sols.extend(pop[self.nindiv].bulko) inp_out.write_xyz(self.debugfile,sols,\ 'First from Invalid-ind + Bulko '+repr(pop[self.nindiv].energy)) if self.generation==0: logger.info('Initializing Bests list') self.BESTS = list() if self.best_inds_list: self.BESTS = tools.BestInds(pop,self.BESTS,self,writefile=True) # Determine survival based on fitness predator if 'lambda,mu' not in self.algorithm_type: pop = tools.get_best(pop, len(pop)) if self.fingerprinting: logger.info('Writing fingerprint files') for one in pop: self.fpfile.write(repr(fingerprinting.fingerprint_dist( pop[0].fingerprint,one.fingerprint))+' '+repr(one.energy)+' ') self.fpfile.write('\n') self.fpminfile.write(repr(pop[0].fingerprint)+'\n') self.fpminfile.write(repr(pop[0].energy)+'\n') nevals = len(pop)/2 if self.generation !=0: logger.info('Applying predator') pop = predator_switch(pop,self) else: self.genrep = 0 self.minfit = 0 # Evaluate population logger.info('Checking population for convergence') self.check_pop(pop) #Update general output tracking if self.generation !=0: histlist = [] for ind in pop: histlist.append(ind.history_index) self.Runtimes.append(time.time()) self.Evaluations.append(nevals) cxsuccess = 0 mutsuccess = [] for one in histlist: if '+' in one: cxsuccess +=1 if 'm' in one: mutsuccess.append(one) self.CXs.append((self.cxattempts,cxsuccess)) mutslist = [[0,0] for one in self.mutation_options] for one in mutsuccess: for two, opt in self.mutattempts: if one==two: index = [ind for ind,value in enumerate( self.mutation_options) if value==opt][0] mutslist[index][1]+=1 for one,opt in self.mutattempts: index = [ind for ind,value in enumerate( self.mutation_options) if value==opt][0] mutslist[index][0]+=1 self.Muts.append(mutslist) self.output.write('\n----- Generation Stats -----\n') self.output.write('Attempted Crossovers: ' + repr(self.cxattempts)+'\n') self.output.write('Successful Crossovers: ' + repr(cxsuccess)+'\n') self.output.write('Mutations:\n') i=0 for opt in self.mutation_options: self.output.write(' Attempted ' + opt + ' : ' + repr(mutslist[i][0]) + '\n') self.output.write(' Successful ' + opt + ' : ' + repr(mutslist[i][1]) + '\n') i+=1 self.generation += 1 # Set new index values index1 = 0 for ind in pop: ind.index = index1 index1+=1 index1 = 0 if not self.convergence: try: self.calc.clean() if self.fixed_region: self.static_calc.clean() except: pass if self.lammps_keep_files: try: if self.parallel and ('Island_Method' not in self.algorithm_type): nproc = MPI.COMM_WORLD.Get_size() lmpfilepath = os.path.dirname(self.calc.tmp_dir) for proc in range(nproc): pth = os.path.join(lmpfilepath,'rank-{0}'.format(proc)) fls = [fl for fl in os.listdir(pth) if '.' not in fl] for one in fls: os.remove(pth+'/'+one) else: fls = [fl for fl in os.listdir(self.calc.tmp_dir) if '.' not in fl] for one in fls: os.remove(self.calc.tmp_dir+'/'+one) except Exception, e: logger.error('Print issue in removing files {0}.'.format(e),exc_info=True) print str(e) pass
def fitpred(pop, Optimizer): """Predator function to select best structures """ pop = get_best(pop, Optimizer.nindiv) return pop, ''