Пример #1
0
 def test_clean_start(self):
     """> Test if the restart indeed removes all the parameters."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Get the nodes
     cfg = Config()
     cfg.genome.compatibility_weight = 1
     node0 = SimpleNodeGene(key=0, cfg=cfg.genome)
     node1 = SimpleNodeGene(key=1, cfg=cfg.genome)
     node3 = SimpleNodeGene(key=2, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Feed the nodes to the NodeComparingCache (successful matches)
     cache(node0, node1, {}, {}, cfg.genome)
     cache(node0, node3, {}, {}, cfg.genome)
     cache(node1, node3, {}, {}, cfg.genome)
     
     # Reset the cache
     cache.reset()
     self.assertEqual(cache.comparable, dict())
     self.assertEqual(next(cache.indexer), 0)
     self.assertEqual(cache.index_map, dict())
Пример #2
0
def get_pruned2(cfg: Config):
    """
    Genome with partially valid connections and nodes (dangling node on other hidden node).
    Configuration:
       0   1
      /
     2---3>
     |
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=2,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0
    genome.nodes[3] = SimpleNodeGene(key=3, cfg=cfg.genome)  # Hidden node
    genome.nodes[3].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 2), (2, 0), (2, 3), (3, 3)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #3
0
 def test_increasing_nodes(self):
     """> Test if the index-parameter keeps increasing with each newly fed node."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Get the nodes
     cfg = Config()
     cfg.genome.compatibility_weight = 1
     node0 = SimpleNodeGene(key=0, cfg=cfg.genome)
     node1 = SimpleNodeGene(key=1, cfg=cfg.genome)
     node3 = SimpleNodeGene(key=2, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Feed the nodes to the NodeComparingCache (successful matches)
     r1 = cache(node0, node1, {}, {}, cfg.genome)
     r2 = cache(node0, node3, {}, {}, cfg.genome)
     r3 = cache(node1, node3, {}, {}, cfg.genome)
     self.assertTrue(r1[0])
     self.assertTrue(r2[0])
     self.assertTrue(r3[0])
     
     # Get the current indexer-value
     self.assertEqual(next(cache.indexer), 3)
     
     # Check the index_map, keys should be merged
     self.assertEqual(cache.index_map[node0.key], cache.index_map[node1.key])
     self.assertEqual(cache.index_map[node1.key], cache.index_map[node3.key])
Пример #4
0
def get_circular2(cfg: Config):
    """
    Genome with circular connections, not connected to the output genome.
    Configuration:
       0   1
       
     2---3
     |   |
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=2,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0
    genome.nodes[3] = SimpleNodeGene(key=3, cfg=cfg.genome)  # Hidden node
    genome.nodes[3].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 2), (2, 3), (3, 2), (-2, 3)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #5
0
def get_invalid4(cfg: Config):
    """
    Genome with connection from start to recurrent node, and from another recurrent node to the output.
    Configuration:
       0   1
           |
     2>    3>
     |
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=4,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0
    genome.nodes[3] = SimpleNodeGene(key=3, cfg=cfg.genome)  # Hidden node
    genome.nodes[3].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 2), (2, 2), (3, 3), (3, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #6
0
def get_invalid5(cfg: Config):
    """
    Genome with connections between the hidden nodes and to one output node.
    Configuration:
       0   1
           |
        2--3
     
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=4,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0
    genome.nodes[3] = SimpleNodeGene(key=3, cfg=cfg.genome)  # Hidden node
    genome.nodes[3].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(2, 3), (3, 2), (3, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #7
0
 def test_distance_failure(self):
     """> Test if the distance-parameter is updated correctly after unsuccessful read."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Setup the nodes to compare
     cfg = Config()
     output_node = OutputNodeGene(key=0, cfg=cfg.genome)
     simple_node = SimpleNodeGene(key=1, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Fetch the result of the distance-measure
     result = cache(
             node0=output_node,
             node1=simple_node,
             conn0={},
             conn1={},
             cfg=cfg.genome,
     )
     
     # Check the distance-parameter
     self.assertEqual(result, (False, None))
     self.assertEqual(cache.comparable[(0, 1)], False)
     self.assertFalse((1, 0) in cache.comparable)
Пример #8
0
def get_genome2(cfg: Config):
    """
    Genome with all biases set to 0, only simple hidden nodes used, all connections enabled with weight 1.
    Configuration:
        0   1
       /    |
      2     \
     /       |
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
            key=2,
            num_outputs=cfg.genome.num_outputs,
            bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0
    
    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 2), (2, 0), (-3, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True
    
    return genome
Пример #9
0
def get_invalid3(cfg: Config):
    """
    Genome without connections to the input nodes.
    Configuration:
       0   1
           |
           2>
          
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=3,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(2, 2), (2, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #10
0
def get_valid2(cfg: Config):
    """
    Network with a recurrent connection (at node 2).
    Configuration:
         0   1
        /
       2>
      / \
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=2,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 2), (-2, 2), (2, 0), (2, 2)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #11
0
def get_valid1(cfg: Config):
    """
    Simple network with only one input and one output used.
    Configuration:
         0   1
             |
             |
             |
    -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
        key=1,
        num_outputs=cfg.genome.num_outputs,
        bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    genome.nodes[2] = SimpleNodeGene(key=2, cfg=cfg.genome)  # Hidden node
    genome.nodes[2].bias = 0

    # Reset the connections
    genome.connections = dict()
    for key in [(-3, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True

    return genome
Пример #12
0
 def test_distance_success(self):
     """> Test if the distance-parameter is updated correctly after successful read."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Setup the nodes to compare
     cfg = Config()
     cfg.genome.compatibility_weight = 1
     node0 = SimpleNodeGene(key=0, cfg=cfg.genome)
     node0.bias = 0
     node1 = SimpleNodeGene(key=1, cfg=cfg.genome)
     node1.bias = 1
     conn_set1 = get_connections(receiving_key=0, sending_keys={-1, -2}, cfg=cfg.genome)
     conn_set2 = get_connections(receiving_key=1, sending_keys={-1, -2}, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Cache the result of the distance-measure
     result = cache(
             node0=node0,
             node1=node1,
             conn0=conn_set1,
             conn1=conn_set2,
             cfg=cfg.genome,
     )
     
     # Check the distance-parameter
     self.assertEqual(result, (True, 1.0))
     self.assertEqual(cache.comparable[(0, 1)], True)
     self.assertFalse((1, 0) in cache.comparable)
Пример #13
0
 def test_successful_distance(self):
     """> Test when a distance-measure should be performed."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Setup the nodes to compare
     cfg = Config()
     cfg.genome.compatibility_weight = 1
     node0 = SimpleNodeGene(key=0, cfg=cfg.genome)
     node0.bias = 0
     node1 = SimpleNodeGene(key=1, cfg=cfg.genome)
     node1.bias = 1
     conn_set1 = get_connections(receiving_key=0, sending_keys={-1, -2}, cfg=cfg.genome)
     conn_set2 = get_connections(receiving_key=1, sending_keys={-1, -2}, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Fetch the result of the distance-measure
     result = cache(
             node0=node0,
             node1=node1,
             conn0=conn_set1,
             conn1=conn_set2,
             cfg=cfg.genome,
     )
     self.assertEqual(result, (True, 1.0))  # Only distance-difference is in the bias
Пример #14
0
 def test_different_connections(self):
     """> Test if False is returned when comparing nodes of different type."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Setup the nodes to compare
     cfg = Config()
     node0 = SimpleNodeGene(key=0, cfg=cfg.genome)
     node1 = SimpleNodeGene(key=1, cfg=cfg.genome)
     conn_set1 = get_connections(receiving_key=0, sending_keys={-1, -2}, cfg=cfg.genome)
     conn_set2 = get_connections(receiving_key=1, sending_keys={-2, -3}, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Fetch the result of the distance-measure
     result = cache(
             node0=node0,
             node1=node1,
             conn0=conn_set1,
             conn1=conn_set2,
             cfg=cfg.genome,
     )
     self.assertEqual(result, (False, None))
Пример #15
0
 def test_different_type(self):
     """> Test if False is returned when comparing nodes of different type."""
     # Folder must be root to load in make_net properly
     if os.getcwd().split('\\')[-1] == 'tests': os.chdir('..')
     
     # Setup the nodes to compare
     cfg = Config()
     output_node = OutputNodeGene(key=0, cfg=cfg.genome)
     simple_node = SimpleNodeGene(key=1, cfg=cfg.genome)
     
     # Create an empty NodeComparingCache
     cache = NodeComparingCache()
     
     # Fetch the result of the distance-measure
     result = cache(
             node0=output_node,
             node1=simple_node,
             conn0={},
             conn1={},
             cfg=cfg.genome,
     )
     self.assertEqual(result, (False, None))
Пример #16
0
def get_deep_genome3(cfg: Config):
    """
    Genome with all biases set to 0, only simple hidden nodes used, all connections enabled with weight 1.
    Configuration:
        0       1
        |       |
        16      |
        |  \    |
        15  |   |
        |   |   |
        14  |   |
        |   |   |
       -1  -2  -3
    """
    # Create a dummy genome
    genome = Genome(
            key=3,
            num_outputs=cfg.genome.num_outputs,
            bot_config=cfg.bot,
    )
    # Reset the nodes
    genome.nodes[0] = OutputNodeGene(key=0, cfg=cfg.genome)  # OutputNode 0
    genome.nodes[0].bias = 0
    genome.nodes[1] = OutputNodeGene(key=1, cfg=cfg.genome)  # OutputNode 1
    genome.nodes[1].bias = 0
    for k in [14, 15, 16]:
        genome.nodes[k] = SimpleNodeGene(key=k, cfg=cfg.genome)  # Hidden node
        genome.nodes[k].bias = 0
    
    # Reset the connections
    genome.connections = dict()
    for key in [(-1, 14), (14, 15), (15, 16), (16, 0), (-2, 16), (-3, 1)]:
        genome.connections[key] = ConnectionGene(key=key, cfg=cfg.genome)
        genome.connections[key].weight = 1
        genome.connections[key].enabled = True
    
    return genome
Пример #17
0
 def create_node(config: GenomeConfig, node_id: int):
     node = SimpleNodeGene(node_id, cfg=config)
     return node
Пример #18
0
def get_simple_node_gene(key, config):
    return SimpleNodeGene(key, config)