def __init__(self, image, piece_size, population_size, generations, elite_size=2): self._image = image self._piece_size = piece_size self._generations = generations self._elite_size = elite_size pieces, rows, columns = image_helpers.flatten_image(image, piece_size, indexed=True) self._population = [Individual(pieces, rows, columns) for _ in range(population_size)] self._pieces = pieces
def child(self): pieces = [None] * self._pieces_length for piece, (row, column) in self._kernel.items(): index = (row - self._min_row) * self._child_columns + ( column - self._min_column) pieces[index] = self._parents[0].piece_by_id(piece) return Individual(pieces, self._child_rows, self._child_columns, shuffle=False)
def __init__(self, image, piece_size, population_size, generations, elite_size=2, position_file="image_position.txt"): # 初始化种群: 代数,人口 TODO self._image = image self._piece_size = piece_size self._generations = generations self._elite_size = elite_size pieces, rows, columns = image_helpers.flatten_image( image, piece_size, indexed=True, position_file=position_file) # 循环population_size次,每次都将Individual方法调用返回的对象加入到list中 self._population = [ Individual(pieces, rows, columns) for _ in range(population_size) ] self._pieces = pieces
def start_evolution(self, verbose): print("=== Pieces: {}\n".format(len(self._pieces))) if verbose: plot = Plot(self._image) ImageAnalysis.analyze_image(self._pieces) fittest = None best_fitness_score = float("-inf") termination_counter = 0 for generation in range(self._generations): print_progress(generation, self._generations - 1, prefix="=== Solving puzzle: ") new_population = [] # Elitism # 取适应度最高的两个图片 elite = self._get_elite_individuals(elites=self._elite_size) new_population.extend(elite) # 从种群中随机选择popultation - elite_size个父母 selected_parents = roulette_selection(self._population, elites=self._elite_size) # 通过父母生成子代,加入到new_population中 for first_parent, second_parent in selected_parents: # 交叉互换,生成子代 crossover = Crossover(first_parent, second_parent) crossover.run() child = crossover.child() # child.mutate() new_population.append(child) # 从上一代中选出适应度最高的一个 fittest = self._best_individual() fittest.mutate() # min_fitness = 0 # for index in range(len(new_population)): # if new_population[index].fitness < new_population[min_fitness].fitness: # min_fitness = index # fittest.clear_fitness() # if fittest.fitness > new_population[min_fitness].fitness: # new_population[min_fitness] = fittest print("old_fittest : ", fittest.fitness, end="") # image = fittest.to_image() # rightImage = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # cv2.imwrite("temp_image_" + str(generation) + ".jpg", rightImage) best_adjoin = fittest.best_adjoin(self._piece_size) rightImage = cv2.cvtColor(best_adjoin, cv2.COLOR_RGB2BGR) cv2.imwrite("temp_image_best_adjoin_" + str(generation) + ".jpg", rightImage) # penalisze = fittest.penalize() # print(" new_fittest : ", fittest.fitness) # rightImage = cv2.cvtColor(penalize, cv2.COLOR_RGB2BGR) # cv2.imwrite("temp_image_penalize_" + str(generation) + ".jpg", rightImage) # 如果上一代最佳比历史最佳好,则termination_counter += 1,否则替换 if fittest.fitness < best_fitness_score: termination_counter += 1 else: best_fitness_score = fittest.fitness termination_counter = 0 if termination_counter % 4 == 2: predicate = Individual(fittest.pieces, fittest.rows, fittest.columns, shuffle=False) predicate.penalize_image = fittest.penalize_image # 处理局部最优 predicate.manually_select() # predicate.shuffle_assembling() print("predicate_fitness : %s " % str(predicate.fitness)) image = predicate.to_image() rightImage = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) cv2.imwrite("predicate_image_" + str(generation) + ".jpg", rightImage) for index in range(len(new_population)): if new_population[index].fitness < predicate.fitness: new_population[index] = predicate break # 如果连续十代都没有更优子代,则退出 if termination_counter == self.TERMINATION_THRESHOLD: print("\n\n=== GA terminated") print("=== There was no improvement for {} generations".format( self.TERMINATION_THRESHOLD)) return fittest self._population = new_population if verbose: plot.show_fittest( fittest.to_image(), "Generation: {} / {}".format(generation + 1, self._generations)) return fittest