def fitness(self): """Evaluates fitness value. Fitness value is calculated as sum of dissimilarity measures between each adjacent pieces. """ if self._fitness is None: fitness_value = 1 / self.FITNESS_FACTOR # For each two adjacent pieces in rows for i in range(self.rows): for j in range(self.columns - 1): ids = (self[i][j].id, self[i][j + 1].id) fitness_value += ImageAnalysis.get_dissimilarity(ids, orientation="LR") # For each two adjacent pieces in columns for i in range(self.rows - 1): for j in range(self.columns): ids = (self[i][j].id, self[i + 1][j].id) fitness_value += ImageAnalysis.get_dissimilarity(ids, orientation="TD") self._fitness = self.FITNESS_FACTOR / fitness_value return self._fitness print(self._fitness)
def fitness(self): """Evaluates fitness value. Fitness value is calculated as sum of dissimilarity measures between each adjacent pieces. 这个方法会在第一次调用时被执行,懒初始化fitness,结果是适应度因子除以空间距离,(结果越大适应度越好) """ if self._fitness is None: fitness_value = 1 / self.FITNESS_FACTOR # For each two adjacent pieces in rows # 累加所有左右关系的碎片的空间距离 for i in range(self.rows): for j in range(self.columns - 1): ids = (self[i][j].id, self[i][j + 1].id) fitness_value += ImageAnalysis.get_dissimilarity( ids, orientation="LR") # For each two adjacent pieces in columns # 累加所有上下关系的碎片的空间距离 for i in range(self.rows - 1): for j in range(self.columns): ids = (self[i][j].id, self[i + 1][j].id) fitness_value += ImageAnalysis.get_dissimilarity( ids, orientation="TD") self._fitness = self.FITNESS_FACTOR / fitness_value return self._fitness
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) selected_parents = roulette_selection(self._population, elites=self._elite_size) for first_parent, second_parent in selected_parents: crossover = Crossover(first_parent, second_parent) crossover.run() child = crossover.child() new_population.append(child) fittest = self._best_individual() if fittest.fitness <= best_fitness_score: termination_counter += 1 else: best_fitness_score = fittest.fitness 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
def _get_buddy_piece(self, piece_id, orientation): first_buddy = ImageAnalysis.best_match(piece_id, orientation) second_buddy = ImageAnalysis.best_match( first_buddy, complementary_orientation(orientation)) if second_buddy == piece_id: for edge in [ parent.edge(piece_id, orientation) for parent in self._parents ]: if edge == first_buddy: return edge
def _get_buddy_piece(self, piece_id, orientation): first_buddy = ImageAnalysis.best_match(piece_id, orientation) second_buddy = ImageAnalysis.best_match( first_buddy, complementary_orientation(orientation)) # 如果两块互相为匹配度最高的块,则表示很有可能是相邻块 if second_buddy == piece_id: for edge in [ parent.edge(piece_id, orientation) for parent in self._parents ]: if edge == first_buddy: # 如果父母中有任意一方有最佳匹配块,则返回 return edge
def best_adjoin(self, piece_size): pieces = np.reshape(self.pieces, (self.rows, self.columns)) empty_image = np.zeros( (piece_size, piece_size, pieces[0][0].shape()[2])) empty_piece = Piece(empty_image, -1) for row in range(self.rows): for col in range(self.columns): if row == 0: if col == 0 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id): continue if col < self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id): continue if col == self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "L", pieces[row][col - 1].id): continue if 0 < row < self.rows - 1: if col == 0 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id): continue if col < self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id): continue if col == self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "D", pieces[row + 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "L", pieces[row][col - 1].id): continue if row == self.rows - 1: if col == 0 and ImageAnalysis.in_range(pieces[row][col].id, "T", pieces[row - 1][col].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id): continue if col < self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "R", pieces[row][col + 1].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "T", pieces[row - 1][col].id): continue if col == self.columns - 1 and ImageAnalysis.in_range(pieces[row][col].id, "L", pieces[row][col - 1].id) \ and ImageAnalysis.in_range(pieces[row][col].id, "T", pieces[row - 1][col].id): continue # if row == 0: # if col == 0 and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id: # continue # if col < self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id: # continue # if col == self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id: # continue # if 0 < row < self.rows - 1: # if col == 0 and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id: # continue # if col < self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id: # continue # if col == self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "D") == pieces[row + 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id: # continue # if row == self.rows - 1: # if col == 0 and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id: # continue # if col < self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "R") == pieces[row][col + 1].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id: # continue # if col == self.columns - 1 and ImageAnalysis.best_match(pieces[row][col].id, "L") == pieces[row][col - 1].id \ # and ImageAnalysis.best_match(pieces[row][col].id, "T") == pieces[row - 1][col].id: # continue pieces[row][col] = empty_piece self.penalize_image = pieces return image_helpers.assemble_image( [each.image for each in pieces.flatten()], self.rows, self.columns)
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