def run(self, fitness_threshold, generation_limit): result = [] while self.generationCount < generation_limit: self.generationCount += 1 self.selection() self.crossover(generation_limit // 1000) fittest = self.population.get_fittest() if fittest.fitness >= fitness_threshold: if result and tuple(fittest.key) == tuple(result[-1][2]): continue r = (fittest.decrypt(), fittest.fitness, fittest.key) result.append(r) fprint("Solution Found:\n{}\nFitness:{} Key:{}".format( r[0], r[1], r[2])) if input( "\nIs this solution bingo? Enter b to break the program. Otherwise press Enter to continue searching..." ) == 'b': return fitness_threshold = fittest.fitness fprint("Generation: {} Fittest: {}".format( self.generationCount, self.population.fittest)) if not result: fprint("Can't find solution") else: fprint("\n\nSolutions Found:{}") for i, r in enumerate(result): fprint("{}.\n{}\nFitness:{} Key:{}".format( i, r[0], r[1], r[2]))
def crossover(self, revive_threshold): P = self.key_length c1 = [0] * P c2 = [0] * P p1 = self.fittest.key p2 = self.secondFittest.key tmp_set = set() r = randint(0, P - 1) for i in range(r): c1[i] = p1[i] tmp_set.add(p1[i]) i = 0 k = 0 while i < P - r and k < P: if p2[k] not in tmp_set: c1[i + r] = p2[k] tmp_set.add(p2[k]) i += 1 else: k += 1 tmp_set.clear() r = randint(0, P - 1) for i in range(P - 1, r - 1, -1): c2[i] = p1[i] tmp_set.add(p1[i]) i = 1 k = P - 1 while i <= r and k >= 0: if p2[k] not in tmp_set: c2[r - i] = p2[k] tmp_set.add(p2[k]) i += 1 else: k -= 1 fprint("r:{}|p1:{}|p2:{}|c1:{}|c2:{}".format(r, p1, p2, c1, c2)) r = randint(0, 2) for i in range(r): # mutation swap = sample(list(range(P)), 2) c1[swap[0]], c1[swap[1]] = c1[swap[1]], c1[swap[0]] swap = sample(list(range(P)), 2) c2[swap[0]], c2[swap[1]] = c2[swap[1]], c2[swap[0]] c_i1 = Individual(self.crypt, self.key_length, key=c1) c_i1.calcFitness() c_i2 = Individual(self.crypt, self.key_length, key=c2) c_i2.calcFitness() # get_fittest_offspring(self) c_i_max = max(c_i1, c_i2, key=(lambda x: x.fitness)) #add_fittest_offspring(self) self.population.replace(self.population.get_least_fittest_index(), c_i_max, revive_threshold)
def replace(self, replace_index, replace, revive_threshold): rk = tuple(replace.key) if rk in self.individuals_dict: self.individuals_dict[rk] += 1 self.check_revive(rk, revive_threshold) return try: del self.individuals_dict[tuple( self.individuals[replace_index].key)] except: fprint("KeyError:{}".format( tuple(self.individuals[replace_index].key))) del self.individuals[replace_index] self.individuals.add(replace) self.individuals_dict[rk] += 1
def __init__(self, crypt, key_length): self.crypt = crypt self.generationCount = 0 self.key_length = key_length fprint("Initializing...Please wait") self.population = Population(1000, crypt, key_length) for i in range(self.population.pop_size): fprint(self.population.individuals[i].key) self.fittest = self.population.get_fittest_rand() self.secondFittest = self.population.get_second_fittest_rand() fprint("Generation: {} Fittest: {}".format(self.generationCount, self.population.fittest))
def check_revive(self, key, revive_threshold): if self.individuals_dict[key] > revive_threshold: fprint("revive...") self.init()