Exemple #1
0
    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)
Exemple #2
0
    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
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
 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)
Exemple #7
0
    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