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())
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
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])
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
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
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
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)
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
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
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
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
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)
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
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))
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))
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
def create_node(config: GenomeConfig, node_id: int): node = SimpleNodeGene(node_id, cfg=config) return node
def get_simple_node_gene(key, config): return SimpleNodeGene(key, config)