Example #1
0
    def mutate(self, parent: Tree):
        if (self.mutation_algorithms is None) or (self.mutation_algorithms is
                                                  []):
            return
        elif random.random() > self.mutation_rate:
            return

        rand_mutation_method: str = self.mutation_algorithms[random.randrange(
            0, self.mutation_algorithms.__len__())]

        # todo not sure about correct names for these types of mutations
        if rand_mutation_method is "delete":  # delete children underneath and attach random terminals to it
            self.__mutate_delete(parent)
        elif rand_mutation_method is "change":  # change the label of the node with respect to its max_num_of_children
            self.__mutate_change(parent)
        elif rand_mutation_method is "add":  # adds a whole new tree as one of its children
            self.__mutate_add(parent)
        elif rand_mutation_method is "exchange":  # change the type (function to terminal and otherwise)
            pass  # todo implement this
        else:
            raise Exception("Invalid Algorithm for Mutation")

        parent.is_mutated = True
        parent.update_tree()
        if parent.depth > self.max_depth:
            parent.reshape_max_depth(self.max_depth)
Example #2
0
    def __mutate_delete(self, parent: Tree):
        rand_node_index = random.randrange(0, parent.number_of_nodes_in_tree)
        temp_node: Node = parent.get_node(rand_node_index)

        if temp_node is None:
            raise Exception("Invalid Node Index")
        while temp_node.type is "T":
            rand_node_index = random.randrange(0,
                                               parent.number_of_nodes_in_tree)
            temp_node = parent.get_node(rand_node_index)

        for i in range(temp_node.max_num_of_children):
            temp_node.children_list[i] = parent.generate_random_terminal()
Example #3
0
def calculate_fitness_for_individual(circuit: Tree):
    global found_solution
    temp_fitness = 0
    for state in truth_table:
        if solve_circuit(state[0], circuit) is state[1]:
            temp_fitness += 1

    if temp_fitness is total_combinations:
        circuit.is_answer = True
        found_solution = True
        input("Found Solution in Generation : {0}".format(gp.generation))

    # temp_fitness /= circuit.depth + 1
    circuit.fitness = temp_fitness
Example #4
0
    def __mutate_add(self, parent: Tree):
        rand_node_index = random.randrange(1, parent.number_of_nodes_in_tree)
        temp_node: Node = parent.get_node(rand_node_index)

        while temp_node.type is "T":
            rand_node_index = random.randrange(0,
                                               parent.number_of_nodes_in_tree)
            temp_node: Node = parent.get_node(rand_node_index)

        final_depth = parent.depth if hp.GP.mutate_add_depth < 2 else hp.GP.mutate_add_depth
        temp_tree = Tree(final_depth, self.function_set, self.terminal_set)
        temp_tree.populate_random_tree(["grow", "full"
                                        ].__getitem__(random.randrange(0, 2)))
        temp_node.children_list[random.randrange(
            0, temp_node.max_num_of_children)] = temp_tree.root
Example #5
0
    def __mutate_change(self, parent: Tree):
        rand_node_index = random.randrange(0, parent.number_of_nodes_in_tree)
        temp_node: Node = parent.get_node(rand_node_index)

        # make sure excluding current terminal won't break our lovely program
        if (temp_node.type is "T") and (self.terminal_set.__len__() > 1):
            temp_remaining_terminals = [
                t for t in self.terminal_set if t is not temp_node.label
            ]
            temp_node.label = temp_remaining_terminals[random.randrange(
                0, temp_remaining_terminals.__len__())]
        if (temp_node.type is "F") and (self.function_set.__len__() > 1):
            # generating a list of tuples from remaining function excluding current function label
            temp_remaining_functions = [
                f_tpl[0] for f_tpl in self.function_set
                if (f_tpl[0] is not temp_node.label) and (
                    f_tpl[1] is temp_node.max_num_of_children)
            ]
            if temp_remaining_functions.__len__() > 0:
                temp_node.label = temp_remaining_functions[random.randrange(
                    0, temp_remaining_functions.__len__())]
Example #6
0
    def __cross_over(self, parent_1: Tree, parent_2: Tree) -> Tree:
        # getting a random node from parent_2
        temp_node = parent_2.get_random_node().copy()

        # region generating a index range for parent_1
        depth_min_range = hp.GP.cross_over_min_range
        depth_max_range = int(hp.GP.cross_over_min_range_multiplier *
                              parent_1.number_of_nodes_in_tree)
        if depth_min_range >= depth_max_range:
            raise Exception("Invalid Range for crossover replacement : (",
                            depth_min_range, " , ", depth_max_range, ")")

        if depth_max_range is 1:
            depth_max_range += 1
        depth_range = (depth_min_range, depth_max_range)
        # endregion

        parent_1.select_random_node_and_replace(depth_range, temp_node)

        # update and reshape the tree if needed
        parent_1.update_tree()
        if parent_1.depth > self.max_depth:
            parent_1.reshape_max_depth(self.max_depth)
        return parent_1
Example #7
0
    def initialize_population(self,
                              initialization_method: str,
                              shuffle: bool = True):

        if initialization_method is "full":

            for i in range(self.population_size):
                rand_depth = random.randrange(self.depth_range[0],
                                              self.depth_range[1] + 1)
                temp_tree = Tree(rand_depth, self.function_set,
                                 self.terminal_set)
                temp_tree.populate_random_tree("full")
                self.population.append(temp_tree)

        elif initialization_method is "grow":

            for i in range(self.population_size):
                rand_depth = random.randrange(self.depth_range[0],
                                              self.depth_range[1] + 1)
                temp_tree = Tree(rand_depth, self.function_set,
                                 self.terminal_set)
                temp_tree.populate_random_tree("grow")
                self.population.append(temp_tree)

        # ramped (or ramped half and half) is a combination of both "grow" and "full"
        elif initialization_method is "ramped":

            for i in range(0, int(self.population_size / 2)):
                rand_depth = random.randrange(self.depth_range[0],
                                              self.depth_range[1] + 1)
                temp_tree = Tree(rand_depth, self.function_set,
                                 self.terminal_set)
                temp_tree.populate_random_tree("grow")
                self.population.append(temp_tree)

            for i in range(int(self.population_size / 2),
                           self.population_size):
                rand_depth = random.randrange(self.depth_range[0],
                                              self.depth_range[1] + 1)
                temp_tree = Tree(rand_depth, self.function_set,
                                 self.terminal_set)
                temp_tree.populate_random_tree("full")
                self.population.append(temp_tree)

        else:
            raise Exception("Invalid Algorithm for initializing population")
        if shuffle:
            random.shuffle(self.population)