Example #1
0
    def create_tree(root_id):
        # odd numbers are ids of terminal nodes, the others are non-terminal nodes.
        n1 = node.Node(root_id)
        n2 = node.Node(2)

        n3 = node.Node(1)
        n4 = node.Node(3)
        n5 = node.Node(5)

        node.set_children(n1, [n2, n3])
        node.set_children(n2, [n4, n5])

        s = solution.Solution(n1)
        solution.set_previous_fitness(s, root_id)

        return s
Example #2
0
 def donate(self, recipient, cross_point, donor):
     """
     Replace a sub-tree of the recipient with a donor
     :param recipient: solution object. recipient of the MLPS-GP crossover.
     :param cross_point: node object. a crossover point.
     :param donor: node object. root node of subtree(donor's root).
     :return: bool. if fitness is improved or not.
     """
     stop = False
     previous_fitness = recipient.previous_fitness
     parent_node, index = cross_point
     pre_node = parent_node.children[index]
     # TODO: check if the pre_node and the donor is same sub-tree, if so, we don't have to check the fitness of the new solution.
     parent_node.children[index] = donor.root
     fitness = self.problem.fitness(recipient)
     if previous_fitness >= fitness:
         parent_node.children[index] = pre_node
         solution.set_previous_fitness(recipient, previous_fitness)
     else:
         stop = True
     return stop
Example #3
0
    def test_stop_improvement_with_shuffle(self):
        root = self.s1.root
        c1 = root.children[0]
        c2 = root.children[1]
        is_shuffle = True

        flg2 = False
        flg4 = False
        for i in range(100):
            improved = localsearch.stop_improvement(self.s1,
                                                    root,
                                                    self.problem,
                                                    is_shuffle=is_shuffle)
            if i == 0:
                self.assertEqual(improved, True)
            if root.func_id == 2:
                flg2 = True
                node.set_id(root, self.root_id)
                solution.set_previous_fitness(self.s1, self.root_id)
            elif root.func_id == 4:
                flg4 = True
                node.set_id(root, self.root_id)
                solution.set_previous_fitness(self.s1, self.root_id)

            if flg2 and flg4:
                break

        self.assertEqual(flg2 and flg4, True)

        improved = localsearch.stop_improvement(self.s1,
                                                c1,
                                                self.problem,
                                                is_shuffle=is_shuffle)
        self.assertEqual(improved, False)

        improved = localsearch.stop_improvement(self.s1,
                                                c2,
                                                self.problem,
                                                is_shuffle=is_shuffle)
        self.assertEqual(improved, False)
Example #4
0
def improve(target_solution, target_node, candidate_id, problem):
    """
    Core function for local search.
    Replace the old function with a new function and then revert it if fitness is not improved.
    :param target_solution: solution object. target solution of local search.
    :param target_node: node object. target node of the target solution.
    :param candidate_id: int. ID of candidate function for local search.
    :param problem: problem object. problem for calculation of fitness.
    :return: bool. if improvement is success, return True.
    """
    pre_id = target_node.func_id
    node.set_id(target_node, candidate_id)
    if target_solution.previous_fitness is None:  # if the solution does not have previous fitness, calculate it.
        pre_fit = problem.fitness(target_solution)
    else:
        pre_fit = target_solution.previous_fitness
    new_fit = problem.fitness(target_solution)  # check the fitness.
    if pre_fit >= new_fit:  # if it is not success, revert the function.
        node.set_id(target_node, pre_id)
        solution.set_previous_fitness(target_solution, pre_fit)
        return False
    else:
        return True
Example #5
0
def bihc(target_solution, node_list, fs_core):
    """
    Best improvement hill climber (BIHC) function.
    :param node_list: list of node object. candidate node list.
    :param fs_core: function. search function for a target node.
    :return: solution object.
    """
    pre_node = None
    while node_list:
        ori_fit = target_solution.previous_fitness
        best_fit = target_solution.previous_fitness
        best_node = None
        best_id = None
        for target_node in node_list:  # Try to find the best-improving target node and the function id.
            ori_id = target_node.func_id
            fs_core(target_solution, target_node)
            if best_fit < target_solution.previous_fitness:
                best_node = target_node
                best_id = target_node.func_id
            # the target solution is reverted to the original for the next iteration.
            node.set_id(target_node, ori_id)
            solution.set_previous_fitness(target_solution, ori_fit)
        # If there is no improvement, end this local search.
        if best_node is None:
            break

        # Otherwise, adopt the improvement to the solution.
        node.set_id(best_node, best_id)
        solution.set_previous_fitness(target_solution, best_fit)

        if pre_node is not None:
            node_list.append(pre_node)
        node_list.remove(best_node)  # remove the replaced node from candidate node list
        pre_node = best_node

    return target_solution
Example #6
0
 def fitness(self, target_solution_or_solutions):
     """
     calculate the fitness of target solution(s)
     :param target_solution_or_solutions: solution object or list of solution objects.
                                          solution to calculate fitness.
     :return: fitness or list of fitness.
     """
     if isinstance(target_solution_or_solutions, Solution):
         fitness = self._cal_fitness(target_solution=target_solution_or_solutions)
         self._eval_cnt += 1
         solution.set_previous_fitness(target_solution_or_solutions, fitness)
         self._elite_fitness = max(self._elite_fitness, fitness)
         return fitness
     elif isinstance(target_solution_or_solutions, list):
         fitness_list = []
         for target_solution in target_solution_or_solutions:
             fitness = self._cal_fitness(target_solution=target_solution)
             solution.set_previous_fitness(target_solution, fitness)
             fitness_list.append(fitness_list)
             self._elite_fitness = max(self._elite_fitness, fitness)
         self._eval_cnt += len(target_solution_or_solutions)
         return fitness_list
     else:
         raise TypeError("target_solution_or_solutions should be Solution object or list of Solution objects.")
Example #7
0
def get_population():
    s1 = solution.Solution(node.Node())
    s2 = solution.Solution(node.Node())
    s3 = solution.Solution(node.Node())
    solution.set_previous_fitness(s1, 1)
    solution.set_previous_fitness(s2, 2)
    solution.set_previous_fitness(s3, 3)

    pop = []
    for _ in range(2):
        pop.extend([s1, s2, s3])
    pop = pop * 2

    return pop
Example #8
0
    def __init__(self):
        self.population = []
        self.n_set = 2
        for i in range(self.n_set):
            s1 = self.create_tree_type1()
            s2 = self.create_tree_type2()
            s3 = self.create_tree_type3()
            solution.set_previous_fitness(s1, 1)
            solution.set_previous_fitness(s2, 2)
            solution.set_previous_fitness(s3, 3)

            self.population.append(s1)
            self.population.append(s2)
            self.population.append(s3)
        self.population = self.population * 2