예제 #1
0
def get_large_genome(TypeGenome: Union[Type[Genome], Type[ModuleGenome], Type[BlueprintGenome]],
                     TypeNode: Union[Type[Node], Type[ModuleNode], Type[BlueprintNode]]) \
        -> Tuple[Union[Genome, ModuleGenome, BlueprintGenome], MutationRecords]:
    """
            1
           / \
          4   3
          |   /
          \  2
           \/
           0
    """
    large_genome = TypeGenome(
        [TypeNode(*input_node_params), TypeNode(hidden2_node, NodeType.HIDDEN), TypeNode(hidden3_node, NodeType.HIDDEN),
         TypeNode(hidden4_node, NodeType.HIDDEN), TypeNode(*output_node_params)],
        [Connection(1, 0, 2), Connection(3, 2, 3), Connection(4, 3, 1), Connection(5, 0, 4), Connection(6, 4, 1),
         Connection(6, 1, 1)])

    return large_genome, MutationRecords({(0, 1): 0,
                                          0: 2,  # add node on connection 0
                                          (0, 2): 1,  # add connection for new node
                                          (2, 1): 2,  # add connection for new node
                                          2: 3,  # Add node id=3 on connection id=2
                                          (2, 3): 3,  # Add connection for node 3
                                          (3, 1): 4,  # Add connection for node 3
                                          # TODO: this is the problem with mutation records. A lookup would've been done
                                          #  for an add node on connection 0 and this node would've been given id=2, but
                                          #  that is already in the genome elsewhere...
                                          0: 4,  # Add node id=4 on connection id=0
                                          (0, 4): 5,  # Add connection for node 4
                                          (4, 1): 6},  # Add connection for node 4
                                         3, 6)
예제 #2
0
def get_small_linear_genome(TypeGenome: Union[Type[Genome], Type[ModuleGenome], Type[BlueprintGenome]],
                            TypeNode: Union[Type[Node], Type[ModuleNode], Type[BlueprintNode]]) \
        -> Tuple[Union[Genome, ModuleGenome, BlueprintGenome], MutationRecords]:
    """0 -- 2 -- 1"""
    small_linear_genome = TypeGenome(
        [TypeNode(*input_node_params), TypeNode(hidden2_node, NodeType.HIDDEN), TypeNode(*output_node_params)],
        [Connection(1, 0, 2), Connection(2, 2, 1)])
    return small_linear_genome, MutationRecords({(0, 1): 0,  # initial mini genome
                                                 0: 2,  # add node on connection 0
                                                 (0, 2): 1,  # add connection for new node
                                                 (2, 1): 2},  # add connection for new node
                                                2, 2)
def _create_individual(Node: Union[Type[ModuleNode], Type[BlueprintNode], Type[DANode]],
                       Genome: Union[Type[ModuleGenome], Type[BlueprintGenome], Type[DAGenome]]) -> \
        Union[ModuleGenome, BlueprintGenome, DAGenome]:
    in_node = Node(0, NodeType.INPUT)
    out_node = Node(1, NodeType.OUTPUT)

    # Making the in and out nodes of modules blank
    if Node == ModuleNode and config.blank_io_nodes:
        _blank_node(in_node)
        _blank_node(out_node)

    return Genome(
        [in_node, Node(2, NodeType.HIDDEN), out_node],
        [Connection(0, 0, 2), Connection(1, 2, 1)
         ]  # TODO should this have the connection from 0 -> 1?
    )
예제 #4
0
    def test_and_add_connection(self, genome: Genome,
                                mutation_record: MutationRecords,
                                from_node: Node, to_node: Node):
        """
            Adds a connection between to nodes if possible
            creates a copy genome, adds the node, checks for cycles in the copy
            if no cycles, the connection is added to the original genome

            :returns whether or not the candidate connection was added to the original genome
        """

        copy_genome = copy.deepcopy(genome)

        # Validation
        if from_node.id == to_node.id:
            return False

        candidate_connection = (from_node.id, to_node.id)

        if candidate_connection in genome.connected_nodes:
            # this connection is already in the genome
            return False
        # else:
        #     print("candidate conn", candidate_connection, " not in connections:", genome.connected_nodes,
        #           "nodes:", genome.nodes.keys(), "connections:", genome.connections)

        if from_node.node_type == NodeType.OUTPUT:
            return False

        if to_node.node_type == NodeType.INPUT:
            return False

        # Adding to global mutation dictionary
        if mutation_record.exists(candidate_connection, True):
            mutation_id = mutation_record.connection_mutations[
                candidate_connection]
        else:
            mutation_id = mutation_record.add_mutation(candidate_connection,
                                                       True)

        # Adding new mutation
        mutated_conn = Connection(mutation_id, from_node.id, to_node.id)

        copy_genome.add_connection(mutated_conn)
        if copy_genome.has_cycle():
            # the candidate connection creates a cycle
            return False

        # by now the candidate connection is valid
        genome.add_connection(mutated_conn)

        return True
def random_genome(TypeGenome: Union[Type[Genome], Type[ModuleGenome], Type[BlueprintGenome]],
                  TypeNode: Union[Type[Node], Type[ModuleNode], Type[BlueprintNode]]) \
        -> Tuple[Union[Genome, ModuleGenome, BlueprintGenome], MutationRecords]:
    genome = TypeGenome([
        TypeNode(input_node_params),
        TypeNode(2),
        TypeNode(3),
        TypeNode(4),
        TypeNode(5),
        TypeNode(output_node_params)
    ], [
        Connection(1, 0, 2),
        Connection(3, 2, 3),
        Connection(7, 3, 4),
        Connection(8, 4, 5),
        Connection(9, 5, 1)
    ])
    mr = MutationRecords(
        {
            (0, 1): 0,  # initial mini genome
            0: 2,  # add node 2 on connection 0
            (0, 2): 1,  # add connection for new node
            (2, 1): 2,  # add connection for new node
            2: 3,
            (2, 3): 3,
            (3, 1): 4,
            4: 4,
            (3, 4): 7,
            (4, 1): 10,
            10: 5,
            (4, 5): 8,
            (5, 1): 9
        },
        5,
        10)

    for _ in random.randint(1, 10):  # random number of mutations
        if random.choice([True, False]):
            # Add connection
            from_id = random.randint(0, 6)
            to_id = random.randint(0, 6)
            if mr.exists((from_id, to_id)):
                new_id = mr.connection_mutations[(from_id, to_id)]
            else:
                new_id = mr.add_mutation((from_id, to_id))
            genome.add_connection(Connection(new_id, from_id, to_id))
        else:
            # Add node
            # TODO once mutation records have been fixed
            pass

    return genome, mr
예제 #6
0
from src2.Configuration import config
from src2.Genotype.CDN.Genomes.BlueprintGenome import BlueprintGenome
from src2.Genotype.CDN.Genomes.ModuleGenome import ModuleGenome

from src2.Genotype.NEAT.Connection import Connection
from src2.Genotype.NEAT.Node import Node, NodeType

from src2.Genotype.CDN.Nodes.ModuleNode import ModuleNode
from src2.Genotype.CDN.Nodes.BlueprintNode import BlueprintNode
from src2.Genotype.NEAT.Population import Population

from src2.Genotype.NEAT.Species import Species
from src2.Phenotype.NeuralNetwork.NeuralNetwork import Network
from src2.main.Generation import Generation

conn0 = Connection(0, 0, 2)
conn1 = Connection(1, 0, 3)
conn2 = Connection(2, 2, 5)
conn3 = Connection(3, 3, 6)
conn4 = Connection(4, 6, 4)
conn5 = Connection(5, 5, 1)
conn6 = Connection(6, 4, 1)
conn7 = Connection(7, 3, 5)

# conn3.enabled.set_value(False)

n0 = ModuleNode(0, NodeType.INPUT)
n1 = ModuleNode(1, NodeType.OUTPUT)
n2 = ModuleNode(2)
n3 = ModuleNode(3)
n4 = ModuleNode(4)
예제 #7
0
    def test_and_add_node_on_connection(self, genome: Genome,
                                        mutation_record: MutationRecords,
                                        connection: Connection):

        n_mutations_on_conn = genome.n_mutations_on_connection(
            mutation_record, connection.id)
        mutation_id = (connection.id, n_mutations_on_conn)

        if mutation_record.exists(mutation_id, False):
            # this node mutation has occurred before
            # ie: this connection has had a node placed already

            # the id of the original node which was placed on this connection
            mutated_node_id = mutation_record.node_mutations[mutation_id]
            if mutated_node_id in genome.nodes:
                raise Exception(
                    "node id already in genome, but searched for unique node id"
                )

            # the id of the connection which bridges to the new node
            into_node_connection_id = mutation_record.connection_mutations[(
                connection.from_node_id, mutated_node_id)]
            # the id of the connection which bridges from the new node
            out_of_node_connection_id = mutation_record.connection_mutations[(
                mutated_node_id, connection.to_node_id)]
        else:
            # if this mutation hasn't occurred before if should not be in any genome

            mutated_node_id = mutation_record.add_mutation(mutation_id, False)

            if mutated_node_id in genome.nodes:  # this connection has already created a new node
                raise Exception(
                    "tried to mutate a node onto connection " +
                    str(connection.id) + " mutation (node id) given value " +
                    str(mutated_node_id) +
                    " but this value is already present in the genome: " +
                    repr(genome.nodes.keys()) + "\nmutation record: " +
                    repr(mutation_record))

            into_node_connection_id = mutation_record.add_mutation(
                (connection.from_node_id, mutated_node_id), True)
            out_of_node_connection_id = mutation_record.add_mutation(
                (mutated_node_id, connection.to_node_id), True)

        TypeNode = type(list(genome.nodes.values())
                        [0])  # node could be a blueprint, module or da node
        # multiple node objects share the same id. indicating they are functionally the same
        mutated_node = TypeNode(mutated_node_id, NodeType.HIDDEN)

        genome.add_node(mutated_node)

        mutated_from_conn = Connection(into_node_connection_id,
                                       connection.from_node_id,
                                       mutated_node_id)
        mutated_to_conn = Connection(out_of_node_connection_id,
                                     mutated_node_id, connection.to_node_id)

        genome.add_connection(mutated_from_conn)
        genome.add_connection(mutated_to_conn)

        connection.enabled.set_value(False)

        return True
예제 #8
0
def get_mini_genome(TypeGenome: Union[Type[Genome], Type[ModuleGenome], Type[BlueprintGenome]],
                    TypeNode: Union[Type[Node], Type[ModuleNode], Type[BlueprintNode]]) \
        -> Tuple[Union[Genome, ModuleGenome, BlueprintGenome], MutationRecords]:
    """0 - 1"""
    mini_genome = TypeGenome([TypeNode(*input_node_params), TypeNode(*output_node_params)], [Connection(0, 0, 1)])
    return mini_genome, MutationRecords({(0, 1): 0}, {}, 1, 0)