Esempio n. 1
0
    def mutate(self, genome):
        if random.random() < genome.mute_rates["gene_action"]:
            # Mutate this gene's action
            self.action = mutated_intenum(self.action, goomba.Action, 1.0,
                                          genome.mute_rates["enum_rel"])

        elif random.random() < genome.mute_rates["struct_mod"]:
            # Structure-modifying function mutations.

            # Select a random node and mutation
            node = random.choice(self.function.as_list())
            mute = weighted_choice(genome.mute_rates["struct_rel"])

            if mute == StructMutes.SubTree:
                new_node = FTreeNode.random(round(genome.fun_gen_depth),
                                            len(genome), genome.const_bounds,
                                            genome.mute_rates["leaf_rel"],
                                            node.parent)
                if node.parent is None:
                    self.function = new_node
                elif node.parent.left == node:
                    node.parent.left = new_node
                else:
                    node.parent.right = new_node

            elif mute == StructMutes.OpAbove:
                new_node = FTreeNode(random.choice(list(Op)), None, None,
                                     node.parent)

                if node.parent is None:
                    self.function = new_node
                elif node.parent.left == node:
                    node.parent.left = new_node
                else:
                    node.parent.right = new_node

                new_child = FTreeNode.random(round(genome.fun_gen_depth),
                                             len(genome), genome.const_bounds,
                                             genome.mute_rates["leaf_rel"],
                                             new_node)

                if random.random() < 0.5:
                    new_node.left = node
                    new_node.right = new_child
                else:
                    new_node.left = new_child
                    new_node.right = node

            elif mute == StructMutes.Swap:
                if isinstance(node, FTreeLeaf):
                    if node.parent is not None:
                        node = node.parent
                    else:
                        return
            # swap operands
                tmp = node.left
                node.left = node.right
                node.right = tmp

        else:
            # Non-strucure-modifying function mutation

            # Select a random node
            node = random.choice(self.function.as_list())

            if isinstance(node, FTreeNode):
                # mutate operator
                node.operator = mutated_intenum(node.operator, Op, 1.0,
                                                genome.mute_rates["enum_rel"])
            else:
                if random.random() < genome.mute_rates["leaf_type"]:
                    # mutate the leaf type

                    new_type = node.ref_type
                    # Keep trying to mutate until the value actually changes
                    while new_type == node.ref_type:
                        new_type = mutated_intenum(
                            node.ref_type, RefType, 1.0,
                            genome.mute_rates["leaf_rel"])
                    if node.ref_type == RefType.Constant:
                        node.val = round(
                            node.val)  # In case mutating from float to int
                    node.ref_type = new_type

                else:
                    # mutate the leaf value
                    if node.ref_type == RefType.Constant:
                        node.val = mutated_num(node.val, 1.0, genome,
                                               [None, None])
                    elif node.ref_type in [
                            RefType.Pure_Offset_Call,
                            RefType.Impure_Offset_Call
                    ]:
                        node.val = mutated_int_in_range(
                            node.val, 1.0,
                            [-len(genome), len(genome)],
                            genome.mute_rates["enum_rel"])
                    elif node.ref_type == RefType.Poll_Sensor:
                        node.val = mutated_int_in_range(
                            node.val, 1.0, [0, len(goomba.Sensor) - 1],
                            genome.mute_rates["enum_rel"])
Esempio n. 2
0
    def mutate(self, genome):
        if random.random() < genome.mute_rates["gene_action"]:
            # Mutate this gene's action
            self.action = mutated_intenum(self.action, goomba.Action,
                                          1.0, genome.mute_rates["enum_rel"])

        elif random.random() < genome.mute_rates["struct_mod"]:
            # Structure-modifying function mutations.

            # Select a random node and mutation
            node = random.choice(self.function.as_list())
            mute = weighted_choice(genome.mute_rates["struct_rel"])

            if mute == StructMutes.SubTree:
                new_node = FTreeNode.random(round(genome.fun_gen_depth),
                                            len(genome),
                                            genome.const_bounds,
                                            genome.mute_rates["leaf_rel"],
                                            node.parent)
                if node.parent is None:
                    self.function = new_node
                elif node.parent.left == node:
                    node.parent.left = new_node
                else:
                    node.parent.right = new_node

            elif mute == StructMutes.OpAbove:
                new_node = FTreeNode(random.choice(list(Op)), None, None, node.parent)
                
                if node.parent is None:
                    self.function = new_node
                elif node.parent.left == node:
                    node.parent.left = new_node
                else:
                    node.parent.right = new_node
                
                new_child = FTreeNode.random(round(genome.fun_gen_depth),
                                             len(genome),
                                             genome.const_bounds,
                                             genome.mute_rates["leaf_rel"],
                                             new_node)

                if random.random() < 0.5:
                    new_node.left = node
                    new_node.right = new_child
                else:
                    new_node.left = new_child
                    new_node.right = node
                    
            elif mute == StructMutes.Swap:
                if isinstance(node, FTreeLeaf):
                    if node.parent is not None:
                        node = node.parent
                    else:
                        return
            # swap operands
                tmp = node.left
                node.left = node.right
                node.right = tmp

        else:
            # Non-strucure-modifying function mutation
            
            # Select a random node
            node = random.choice(self.function.as_list())

            if isinstance(node, FTreeNode):
                # mutate operator
                node.operator = mutated_intenum(node.operator, Op, 
                                                1.0, genome.mute_rates["enum_rel"])
            else:
                if random.random() < genome.mute_rates["leaf_type"]:
                    # mutate the leaf type

                    new_type = node.ref_type
                    # Keep trying to mutate until the value actually changes
                    while new_type == node.ref_type:
                        new_type = mutated_intenum(node.ref_type, RefType,
                                                   1.0, genome.mute_rates["leaf_rel"])
                    if node.ref_type == RefType.Constant:
                        node.val = round(node.val)  # In case mutating from float to int
                    node.ref_type = new_type
                    
                else:
                    # mutate the leaf value
                    if node.ref_type == RefType.Constant:
                        node.val = mutated_num(node.val, 1.0,
                                               genome, [None, None])
                    elif node.ref_type in [RefType.Pure_Offset_Call, RefType.Impure_Offset_Call]:
                        node.val = mutated_int_in_range(node.val, 1.0,
                                                        [-len(genome), len(genome)],
                                                        genome.mute_rates["enum_rel"])
                    elif node.ref_type == RefType.Poll_Sensor:
                        node.val = mutated_int_in_range(node.val, 1.0,
                                                        [0, len(goomba.Sensor) - 1],
                                                        genome.mute_rates["enum_rel"])
Esempio n. 3
0
 def random(cls, max_depth, gen_len, const_bounds, leaf_weights):
     action = random.choice(list(goomba.Action))
     function = FTreeNode.random(max_depth, gen_len, const_bounds,
                                 leaf_weights)
     return cls(action, function)
Esempio n. 4
0
 def random(cls, max_depth, gen_len, const_bounds, leaf_weights):
     action = random.choice(list(goomba.Action))
     function = FTreeNode.random(max_depth, gen_len, const_bounds, leaf_weights)
     return cls(action, function)