def test_set_activation(self): g = Genome(3, 3) node_ids = range(len(g.get_nodes())) act = [activations.relu, activations.gaussian, activations.square] # Test to make sure the activation is set correctly msg = 'Activation set incorrectly!' for nid in node_ids: for a in act: g.set_activation(nid, a) self.assertEqual(g.get_node(nid).activation, a)
def test_mutate_add_connection(self): # Test adding a connection msg = 'Connection added incorrectly!' g = Genome(2, 2) for i in range(30): g = Genome(2, 2) g.mutate_add_connection() self.assertEqual(len(g.get_connections()), 1, msg) self.assertEqual(g.get_connections()[0].innovation_number, 0, msg) self.assertTrue( g.get_connections()[0].in_node in [n.id for n in g.get_nodes()], msg) self.assertTrue( g.get_connections()[0].out_node in [n.id for n in g.get_nodes()], msg) self.assertTrue(-1.0 <= g.get_connections()[0].weight <= 1.0, msg) self.assertTrue(g.get_connections()[0].expressed, msg) self.assertNotEqual(g.get_connections()[0].in_node, g.get_connections()[0].out_node) in_type = g.get_node(g.get_connections()[0].in_node).type out_type = g.get_node(g.get_connections()[0].out_node).type self.assertFalse(in_type == out_type != 'hidden') self.assertFalse((in_type == 'output' and out_type == 'input')) self.assertFalse((in_type == 'hidden' and out_type == 'input')) # Test to make sure connections are always added (unless at max) msg = 'Connection not added!' for i in range(2, 4): g.mutate_add_connection() self.assertEqual(len(g.get_connections()), i, msg) # Test to make sure it doesn't go above the maximum connections msg = 'Connections exceeded maximum amount!' g.mutate_add_connection() self.assertEqual(len(g.get_connections()), 4, msg) # Shouldn't go past 4
def test_get_node_max_distance(self): g = Genome(2, 2) # Test to make sure empty genomes return the correct values for output nodes msg = 'Disconnected output node returned invalid value!' self.assertEqual(g.get_node_max_distance(g.get_node(2).id), -1, msg) self.assertEqual(g.get_node_max_distance(g.get_node(3).id), -1, msg) # Add nodes and connections g.add_connection(0, 2, weight=-0.7) g.add_connection(0, 3, weight=-0.1) g.add_connection(1, 2, weight=0.5) g.add_connection(1, 3, weight=0.9) g.add_node(0) g.add_node(2) g.add_connection(4, 5, 0.5) msg = 'Incorrect node max distance!' # Test the values of each node distance to make sure they are correct correct_distances = [0, 0, 3, 1, 1, 2] for node, distance in zip(g.get_nodes(), correct_distances): self.assertEqual(g.get_node_max_distance(node.id), distance, msg) # Add a node and test again g.add_node(8) correct_distances = [0, 0, 4, 1, 1, 3, 2] for node, distance in zip(g.get_nodes(), correct_distances): self.assertEqual(g.get_node_max_distance(node.id), distance, msg) # Add connection and test again g.add_connection(6, 3) correct_distances = [0, 0, 4, 3, 1, 3, 2] for node, distance in zip(g.get_nodes(), correct_distances): self.assertEqual(g.get_node_max_distance(node.id), distance, msg) # Test genome with connection loop msg = 'Genome failed to handle connection loop!' g2 = Genome(1, 1) g2.add_connection(0, 1) g2.add_node(0) g2.add_node(0) g2.add_node(1) g2.add_connection(3, 2) g2.add_connection(4, 3) correct_distances = [0, 4, 3, 3, 3] for node, distance in zip(g2.get_nodes(), correct_distances): self.assertEqual(g2.get_node_max_distance(node.id), distance, msg)
def test_cross(self): e = Ecosystem() # Create genomes g = Genome(2, 2, ecosystem=e) g2 = Genome(2, 2, ecosystem=e) # Cross the genomes child = e.cross(g, g2) # Test child connections msg = 'Child connection doesn\'t exist within either parent!' for c in child.get_connections(): self.assertTrue( g.get_connection(c.innovation_number) is not None or g2.get_connection(c.innovation_number) is not None, msg) # Test to make sure the child has the same amount of connections as the fitter parent msg = 'Child missing fitter parent connection(s)!' self.assertEqual(len(child.get_connections()), len(g.get_connections()), msg) # Test child nodes msg = 'Child node doesn\'t exist within either parent!' for n in child.get_nodes(): self.assertTrue( g.get_node(n.id) is not None or g2.get_node(n.id) is not None, msg) # Test to make sure the child has the same amount of nodes as the fitter parent msg = 'Child is missing fitter parent node(s)!' self.assertEqual(len(child.get_nodes()), len(g.get_nodes()), msg) # Test preference for fit parents msg = 'Child connection preferred less fit parent!' for c in child.get_connections(): in_both = g.get_connection( c.innovation_number) is not None and g2.get_connection( c.innovation_number) is not None in_fit_parent = g.get_connection( c.innovation_number) is not None and g2.get_connection( c.innovation_number) is None self.assertTrue(in_both or in_fit_parent, msg) # Add connections and nodes g.add_connection(0, 2) g.add_connection(0, 3) g.add_connection(1, 2) g.add_connection(1, 3) g.add_node(0) g.get_connections()[5].weight = 0.4 g2.add_connection(0, 2) g2.add_connection(0, 3) g2.add_connection(1, 2) g2.add_connection(1, 3) g2.add_node(1) g.add_node(2) # Assign fitness to genomes g.fitness = 10 g2.fitness = 5 # Cross the genomes child = e.cross(g, g2) # Test child connections msg = 'Child connection doesn\'t exist within either parent!' for c in child.get_connections(): self.assertTrue( g.get_connection(c.innovation_number) is not None or g2.get_connection(c.innovation_number) is not None, msg) # Test to make sure the child has the same amount of connections as the fitter parent msg = 'Child missing fitter parent connection(s)!' self.assertEqual(len(child.get_connections()), len(g.get_connections()), msg) # Test child nodes msg = 'Child node doesn\'t exist within either parent!' for n in child.get_nodes(): self.assertTrue( g.get_node(n.id) is not None or g2.get_node(n.id) is not None, msg) # Test to make sure the child has the same amount of nodes as the fitter parent msg = 'Child is missing fitter parent node(s)!' self.assertEqual(len(child.get_nodes()), len(g.get_nodes()), msg) # Test preference for fit parents msg = 'Child connection preferred less fit parent!' for c in child.get_connections(): in_both = g.get_connection( c.innovation_number) is not None and g2.get_connection( c.innovation_number) is not None in_fit_parent = g.get_connection( c.innovation_number) is not None and g2.get_connection( c.innovation_number) is None self.assertTrue(in_both or in_fit_parent, msg) # Swap the fitness and test again g.fitness = 5 g2.fitness = 10 # Cross the genomes child = e.cross(g, g2) # Test child connections msg = 'Child connection doesn\'t exist within either parent!' for c in child.get_connections(): self.assertTrue( g.get_connection(c.innovation_number) is not None or g2.get_connection(c.innovation_number) is not None, msg) # Test to make sure the child has the same amount of connections as the fitter parent msg = 'Child missing fitter parent connection(s)!' self.assertEqual(len(child.get_connections()), len(g2.get_connections()), msg) # Test child nodes msg = 'Child node doesn\'t exist within either parent!' for n in child.get_nodes(): self.assertTrue( g.get_node(n.id) is not None or g2.get_node(n.id) is not None, msg) # Test to make sure the child has the same amount of nodes as the fitter parent msg = 'Child is missing fitter parent node(s)!' self.assertEqual(len(child.get_nodes()), len(g2.get_nodes()), msg) # Test preference for fit parents msg = 'Child connection preferred less fit parent!' for c in child.get_connections(): in_both = g.get_connection( c.innovation_number) is not None and g2.get_connection( c.innovation_number) is not None in_fit_parent = g.get_connection( c.innovation_number) is None and g2.get_connection( c.innovation_number) is not None self.assertTrue(in_both or in_fit_parent, msg)