def run(file, num=1, output=True, **kwargs): node_inno = [Counter() for _ in range(num)] if num > 1 else Counter() con_inno = [Counter() for _ in range(num)] if num > 1 else Counter() genome = [Genome() for _ in range(num)] if num > 1 else Genome() setup_func(genome, node_inno, con_inno) name = 'output/' + file.split('/')[-1].replace('.py', '') viewer = GenomeViewer(**kwargs) viewer.orientation = GenomeViewer.RIGHT if output: if num > 1: for i, g in enumerate(genome): viewer.gen(g).save(f'{name}_{i}_before.png', format='PNG') else: viewer.gen(genome).save(f'{name}_before.png', format='PNG') test_func(genome, node_inno, con_inno) if output: if num > 1: for i, g in enumerate(genome): viewer.gen(g).save(f'{name}_{i}_after.png', format='PNG') else: viewer.gen(genome).save(f'{name}_after.png', format='PNG')
def test_print(self): g = Genome(3, 1) g.connect_nodes_by_id(1, 4, 1) g.connect_nodes_by_id(2, 4, 2) g.connect_nodes_by_id(3, 4, 3) g.create_node_between(2, 4, 5, 4) g.connect_nodes_by_id(1, 5, 6) printer = Printer(g) printer.print()
def setup(genome, node_inno, con_inno): seed(1337) for _ in range(3): genome.add_node(Node(node_inno.inc, 0, NodeType.INPUT)) genome.add_node(Node(node_inno.inc, 2, NodeType.OUTPUT)) genome.add_node(Node(node_inno.inc, 1, NodeType.HIDDEN)) genome.add_connection(Connection(con_inno.inc, 0, 3, 1.0, True)) genome.add_connection(Connection(con_inno.inc, 1, 3, 1.0, False)) genome.add_connection(Connection(con_inno.inc, 2, 3, 1.0, True)) genome.add_connection(Connection(con_inno.inc, 1, 4, 1.0, True)) genome.add_connection(Connection(con_inno.inc, 4, 3, 1.0, True)) genome.add_connection(Connection(con_inno.inc, 0, 4, 1.0, True)) # genome.add_connection(Connection(con_inno.inc, 2, 4, 1.0, True)) Genome.save(genome, 'output/save_load')
def test_init(self): g = Genome(2, 1) self.assertEqual(1, g.nodes[0].get_innovation()) self.assertEqual(2, g.nodes[1].get_innovation()) self.assertEqual(3, g.nodes[2].get_innovation()) self.assertEqual(Node.TYPE_INPUT, g.nodes[0].get_type()) self.assertEqual(Node.TYPE_INPUT, g.nodes[1].get_type()) self.assertEqual(Node.TYPE_OUTPUT, g.nodes[2].get_type())
def test_another_crossover(self): g1 = Genome(3, 1) g2 = Genome(3, 1) node_i = 4 conn_i = 0 for generation in range(10): conn_i = g1.mutate_connections(conn_i) node_i, conn_i = g1.mutate_nodes(node_i, conn_i) conn_i = g2.mutate_connections(conn_i) node_i, conn_i = g2.mutate_nodes(node_i, conn_i) a1, a2 = Population.align_genome(g1, g2) g1 = Population.crossover(a1, a2, g1.get_input_nodes(), g1.get_output_nodes()) g2 = Population.crossover(a1, a2, g1.get_input_nodes(), g1.get_output_nodes()) Printer(g1).print()
def test_remove_node(self): g = Genome(1, 1) g.create_node(Node.TYPE_HIDDEN, 3) g.nodes[0].connect_to(g.nodes[2], 1) g.nodes[2].connect_to(g.nodes[1], 2) self.assertEqual(3, g.nodes[0].get_next_connections()[0].get_next_node().get_innovation()) self.assertEqual(2, g.nodes[0].get_next_connections()[0].get_next_node().get_next_connections()[ 0].get_next_node().get_innovation()) g.remove_node(3) self.assertEqual(0, len(g.connections)) self.assertEqual(0, len(g.nodes[0].get_next_connections())) self.assertEqual(0, len(g.nodes[1].get_prev_connections()))
def test_create_node_between(self): g = Genome(1, 1) g.create_node_between(1, 2, 3, 1) self.assertEqual(2, len(g.connections)) self.assertEqual(1, g.connections[0].get_innovation()) self.assertEqual(2, g.connections[1].get_innovation()) g.create_node_between(3, 2, 4, 3, g.select_connection_by_innovation(2)) self.assertEqual(3, len(g.connections)) current_node = g.nodes[0] self.assertEqual(1, g.nodes[0].get_innovation()) current_node = current_node.get_next_connections()[0].get_next_node() self.assertEqual(3, current_node.get_innovation()) current_node = current_node.get_next_connections()[0].get_next_node() self.assertEqual(4, current_node.get_innovation()) current_node = current_node.get_next_connections()[0].get_next_node() self.assertEqual(2, current_node.get_innovation())
def ttt_test(config): gens = config['max_generations'] pop = None start_genome = None #//Hold records for each run evals = [ 0 for i in range(neatconfig.num_runs) ] genes = [ 0 for i in range(neatconfig.num_runs) ] nodes = [ 0 for i in range(neatconfig.num_runs) ] # Made as lists for pass-by-reference winnernum = [ 0 ] winnergenes = [ 0 ] winnernodes = [ 0 ] #//For averaging totalevals = 0 totalgenes = 0 totalnodes = 0 dprint(DEBUG_INFO, "START TTT TEST") if config['seed_with_start_genome']: gene_filename = neatconfig.genedir + "/" + config['start_genome_file'] iFile = open(gene_filename, "r") if not iFile: dprint(DEBUG_ERROR, "Unable to open starting genome file %s." % (gene_filename, )) return pop dprint(DEBUG_INFO, "Opened start genome file %s." % (gene_filename, )) #//Read in the start Genome dprint(DEBUG_INFO, "Reading in the start genome") line = iFile.readline() words = line.strip().split() curword = words[0] gid = int(words[1]) if curword != "genomestart": dprint(DEBUG_ERROR, "Bad starting genome file %s." % (gene_filename, )) return pop dprint(DEBUG_INFO, "Reading in Genome id %d." % (gid,)) start_genome = Genome() start_genome.SetFromFile(gid, iFile) iFile.close() dprint(DEBUG_INFO, "Verifying start_genome") if not start_genome.verify(): dprint(DEBUG_ERROR, "genome.verify() failed:", start_genome.deep_string()) #Complete a number of runs for expcount in range(neatconfig.num_runs): if config['seed_with_start_genome']: #//Spawn the Population dprint(DEBUG_INFO, "Spawning Population off Genome") pop = Population() pop.SetFromGenome(start_genome, neatconfig.pop_size) dprint(DEBUG_INFO, "Verifying Spawned Population[%d]" % (expcount, )) if not pop.verify(): dprint(DEBUG_ERROR, "Population[%d] verification failed" % (expcount, )) elif config['seed_with_previous_population']: population_filename = neatconfig.genedir + "/" + config['previous_population_file'] dprint(DEBUG_INFO, "Reading Population from %s" % (population_filename, )) pop = Population() pop.SetFromFilename(population_filename) dprint(DEBUG_INFO, "Verifying Start Population[%d]" % (expcount, )) if not pop.verify(): dprint(DEBUG_ERROR, "Population[%d] verification failed" % (expcount, )) #// evolve up to gens generations gen = 1 while gen <= gens: dprint(DEBUG_INFO, "Evaluating Spawned Population[%d] Epoch[%d]" % (expcount, gen)) # if not pop.verify(): # dprint(DEBUG_ERROR, "Population[%d] Epoch[%d] verification failed" % (expcount, gen)) #print "Epoch", gen generation_filename = neatconfig.generationdir + "/tttgen_%d" % (gen,) # Evaluate one generation, checking for a successful end #//Check for success if ttt_epoch(pop, gen, generation_filename, winnernum, winnergenes, winnernodes): evals[expcount] = neatconfig.pop_size * (gen-1) + winnernum[0] genes[expcount] = winnergenes[0] nodes[expcount] = winnernodes[0] break # in case we want to change after run has started config = ttt_read_config(neatconfig.configdir + '/ttt.config') gens = config['max_generations'] gen += 1 # end of generation loop if g_found_optimal: break # end of num_runs loop #//Average and print stats dprint(DEBUG_INFO, "Nodes: ") for expcount in range(neatconfig.num_runs): dprint(DEBUG_INFO, nodes[expcount]) totalnodes += nodes[expcount] dprint(DEBUG_INFO, "Genes: ") for expcount in range(neatconfig.num_runs): dprint(DEBUG_INFO, genes[expcount]) totalgenes += genes[expcount] dprint(DEBUG_INFO, "Evals ") samples = 0 for expcount in range(neatconfig.num_runs): dprint(DEBUG_INFO, evals[expcount]) if evals[expcount] > 0: totalevals += evals[expcount] samples += 1 if samples > 0: avgnodes = float(totalnodes)/samples avggenes = float(totalgenes)/samples avgevals = float(totalevals)/samples else: avgnodes = 0 avggenes = 0 avgevals = 0 dprint(DEBUG_INFO, "Failures:", (neatconfig.num_runs - samples), "out of", neatconfig.num_runs, "runs") dprint(DEBUG_INFO, "Average Nodes:", avgnodes) dprint(DEBUG_INFO, "Average Genes:", avggenes) dprint(DEBUG_INFO, "Average Evals:", avgevals) return pop
def xor_test(gens): gene_filename = neatconfig.genedir + "/xorstartgenes" pop = None start_genome = None #//Hold records for each run evals = [ 0 for i in range(neatconfig.num_runs) ] genes = [ 0 for i in range(neatconfig.num_runs) ] nodes = [ 0 for i in range(neatconfig.num_runs) ] # Made as lists for pass-by-reference winnernum = [ 0 ] winnergenes = [ 0 ] winnernodes = [ 0 ] #//For averaging totalevals = 0 totalgenes = 0 totalnodes = 0 iFile = open(gene_filename, "r") if not iFile: dprint(DEBUG_ERROR, "Unable to open starting genome file %s." % (gene_filename, )) return pop print "START XOR TEST" #//Read in the start Genome print "Reading in the start genome" line = iFile.readline() words = line.strip().split() curword = words[0] gid = int(words[1]) if curword != "genomestart": print "Bad starting genome file %s." % (gene_filename, ) return pop print "Reading in Genome id %d." % (gid,) start_genome = Genome() start_genome.SetFromFile(gid, iFile) iFile.close() print "Verifying start_genome" if not start_genome.verify(): dprint(DEBUG_ERROR, "genome.verify() failed:", start_genome.deep_string()) #Complete a number of runs for expcount in range(neatconfig.num_runs): #//Spawn the Population print "Spawning Population off Genome2" pop = Population() pop.SetFromGenome(start_genome, neatconfig.pop_size) print "Verifying Spawned Population[%d]" % (expcount, ) if not pop.verify(): dprint(DEBUG_ERROR, "Population[%d] verification failed" % (expcount, )) #// evolve up to gens generations for gen in range(1, gens+1): print "Verifying Spawned Population[%d] Epoch[%d]" % (expcount, gen) if not pop.verify(): dprint(DEBUG_ERROR, "Population[%d] Epoch[%d] verification failed" % (expcount, gen)) #print "Epoch", gen generation_filename = neatconfig.generationdir + "/gen_%d" % (gen,) # Evaluate one generation, checking for a successful end #//Check for success if xor_epoch(pop, gen, generation_filename, winnernum, winnergenes, winnernodes): evals[expcount] = neatconfig.pop_size * (gen-1) + winnernum[0] genes[expcount] = winnergenes[0] nodes[expcount] = winnernodes[0] break # end of generation loop if g_found_optimal: break # end of num_runs loop #//Average and print stats print "Nodes: " for expcount in range(neatconfig.num_runs): print nodes[expcount] totalnodes += nodes[expcount] print "Genes: " for expcount in range(neatconfig.num_runs): print genes[expcount] totalgenes += genes[expcount] print "Evals " samples = 0 for expcount in range(neatconfig.num_runs): print evals[expcount] if evals[expcount] > 0: totalevals += evals[expcount] samples += 1 if samples > 0: avgnodes = float(totalnodes)/samples avggenes = float(totalgenes)/samples avgevals = float(totalevals)/samples else: avgnodes = 0 avggenes = 0 avgevals = 0 print "Failures:", (neatconfig.num_runs - samples), "out of", neatconfig.num_runs, "runs" print "Average Nodes:", avgnodes print "Average Genes:", avggenes print "Average Evals:", avgevals return pop
def make_child(genome1, genome2, number_of_species): if genome1.fitness > genome2.fitness: new_genes = select_genes(genome1, genome2) elif genome1.fitness < genome2.fitness: new_genes = select_genes(genome2, genome1) else: new_genes = select_genes(genome1, genome2) nodes = [i + 1 for i in range(genome1.input_nodes + genome1.output_nodes)] hidden_nodes = [] for gene in new_genes: if gene.type == 0: if gene.out_node not in hidden_nodes: hidden_nodes.append(gene.out_node) elif gene.type == 1: if gene.in_node not in hidden_nodes: hidden_nodes.append(gene.in_node) node_array = np.concatenate((nodes, hidden_nodes), axis=None) new_genome = Genome.Genome(0, 0, node_array, genome1.input_nodes, genome1.output_nodes) new_genome.connection_genes = new_genes """ Add a new connection between to nodes""" # if random.uniform(0, 1) <= CREATE_NEW_CONNECTION_PROBABILITY: # new_genome.add_connection() if number_of_species > 5: """ Add a random amount of weights form 1 to N """ for i in range( random.randint(1, int(CREATE_NEW_CONNECTION_PROBABILITY))): new_genome.add_connection() """ Add a new node inside an existing connection between input node and output node """ if random.uniform(0, 1) <= CREATE_NEW_NODE_PROBABILITY: new_genome.add_node() """ Randomly mutate som genes """ if random.uniform(0, 1) <= MUTATE_NEW_CHILD_PROBABILITY: for genome in new_genome.connection_genes: if random.uniform(0, 1) <= MUTATE_GENE_PROBABILITY: if random.uniform(0, 1) <= CHANGE_WEIGHT_SLIGHTLY_PROBABILITY: genome.weight = genome.weight + random.uniform(-1, 1) * 0.1 else: genome.weight = random.uniform(-1, 1) else: """ Add a random amount of weights form 2 to 3 """ for i in range(random.randint(2, 3)): new_genome.add_connection() """ Add a new node inside an existing connection between input node and output node """ if random.uniform(0, 1) <= 0.35: new_genome.add_node() """ Randomly mutate som genes """ if random.uniform(0, 1) <= 0.8: for genome in new_genome.connection_genes: if random.uniform(0, 1) <= 1: if random.uniform(0, 1) <= 0.8: genome.weight = genome.weight + random.uniform(-1, 1) * 0.2 else: genome.weight = random.uniform(-1, 1) return new_genome
def test_empty_crossover(self): g1 = Genome(3, 1) g2 = Genome(3, 1) a1, a2 = Population.align_genome(g1, g2) c = Population.crossover(a1, a2, g1.get_input_nodes(), g1.get_output_nodes()) self.assertGreaterEqual(4, len(c.nodes))
def setUpClass(cls): print("Testing Mutator") with open(os.path.join(here, "loopback_test_genome.yaml"), 'r') as in_file: cls.loopback_test_genome = Genome().from_yaml( yaml.load(in_file.read()))
def test_get_next_nodes(self): g = Genome(1, 1) g.create_node_between(1, 2, 3, 1) self.assertEqual([3], [n.get_innovation() for n in g.select_node_by_id(1).get_next_nodes()])
def test_align_genome(self): g1 = Genome(3, 1) g1.create_node(Node.TYPE_HIDDEN, 5) g1.connect_nodes_by_id(1, 4, 1) g1.connect_nodes_by_id(2, 4, 2) g1.connect_nodes_by_id(3, 4, 3) g1.connect_nodes_by_id(2, 5, 4) g1.connect_nodes_by_id(5, 4, 5) g1.connect_nodes_by_id(1, 5, 8) g2 = Genome(3, 1) g2.create_node(Node.TYPE_HIDDEN, 5) g2.create_node(Node.TYPE_HIDDEN, 6) g2.connect_nodes_by_id(1, 4, 1) g2.connect_nodes_by_id(2, 4, 2) g2.connect_nodes_by_id(3, 4, 3) g2.connect_nodes_by_id(2, 5, 4) g2.connect_nodes_by_id(5, 4, 5) g2.connect_nodes_by_id(5, 6, 6) g2.connect_nodes_by_id(6, 4, 7) g2.connect_nodes_by_id(3, 5, 9) g2.connect_nodes_by_id(1, 6, 10) # p = Population(2, 3, 1) # p.population['s0'] = [g1, g2] a1, a2 = Population.align_genome(g1, g2) self.assertEqual(1, a1[0].get_innovation()) self.assertEqual(2, a1[1].get_innovation()) self.assertEqual(3, a1[2].get_innovation()) self.assertEqual(4, a1[3].get_innovation()) self.assertEqual(5, a1[4].get_innovation()) self.assertEqual(None, a1[5]) self.assertEqual(None, a1[6]) self.assertEqual(8, a1[7].get_innovation()) self.assertEqual(None, a1[8]) self.assertEqual(None, a1[9]) self.assertEqual(1, a2[0].get_innovation()) self.assertEqual(2, a2[1].get_innovation()) self.assertEqual(3, a2[2].get_innovation()) self.assertEqual(4, a2[3].get_innovation()) self.assertEqual(5, a2[4].get_innovation()) self.assertEqual(6, a2[5].get_innovation()) self.assertEqual(7, a2[6].get_innovation()) self.assertEqual(None, a2[7]) self.assertEqual(9, a2[8].get_innovation()) self.assertEqual(10, a2[9].get_innovation())
def setup(genome, node_inno, con_inno): seed(1337) print('========== Test 1 ==========') genome = Genome() genome.add_node(Node(0, 0, NodeType.INPUT)) genome.add_node(Node(1, 1, NodeType.OUTPUT)) genome.add_connection(Connection(0, 0, 1, 0.5, True)) net = Network(genome) input = [1.0] for _ in range(3): output = net.calculate(input) print(f'Output len={len(output)}, output[0]={output[0]}=0.9192') print() print('========== Test 2 ==========') genome = Genome() genome.add_node(Node(0, 0, NodeType.INPUT)) genome.add_node(Node(1, 1, NodeType.OUTPUT)) genome.add_connection(Connection(0, 0, 1, 0.1, True)) net = Network(genome) input = [-0.5] for _ in range(3): output = net.calculate(input) print(f'Output len={len(output)}, output[0]={output[0]}=0.50973') print() print('========== Test 3 ==========') genome = Genome() genome.add_node(Node(0, 0, NodeType.INPUT)) genome.add_node(Node(1, 2, NodeType.OUTPUT)) genome.add_node(Node(2, 1, NodeType.HIDDEN)) genome.add_connection(Connection(0, 0, 2, 0.4, True)) genome.add_connection(Connection(1, 2, 1, 0.7, True)) net = Network(genome) input = [0.9] for _ in range(3): output = net.calculate(input) print(f'Output len={len(output)}, output[0]={output[0]}=0.9524') print() print('========== Test 4 ==========') genome = Genome() genome.add_node(Node(0, 0, NodeType.INPUT)) genome.add_node(Node(1, 0, NodeType.INPUT)) genome.add_node(Node(2, 0, NodeType.INPUT)) genome.add_node(Node(3, 2, NodeType.OUTPUT)) genome.add_node(Node(4, 1, NodeType.HIDDEN)) genome.add_connection(Connection(0, 0, 4, 0.4, True)) genome.add_connection(Connection(1, 1, 4, 0.7, True)) genome.add_connection(Connection(2, 2, 4, 0.1, True)) genome.add_connection(Connection(3, 4, 3, 1.0, True)) net = Network(genome) input = [0.5, 0.75, 0.9] for _ in range(3): output = net.calculate(input) print(f'Output len={len(output)}, output[0]={output[0]}=0.9924') print() print('========== Test 5 ==========') genome = Genome() genome.add_node(Node(0, 0, NodeType.INPUT)) genome.add_node(Node(1, 0, NodeType.INPUT)) genome.add_node(Node(2, 0, NodeType.INPUT)) genome.add_node(Node(3, 2, NodeType.OUTPUT)) genome.add_node(Node(4, 1, NodeType.HIDDEN)) genome.add_node(Node(5, 1, NodeType.HIDDEN)) genome.add_connection(Connection(0, 0, 4, 0.4, True)) genome.add_connection(Connection(1, 1, 4, 0.7, True)) genome.add_connection(Connection(2, 2, 4, 0.1, True)) genome.add_connection(Connection(3, 4, 3, 1.0, True)) genome.add_connection(Connection(4, 2, 5, 0.2, True)) genome.add_connection(Connection(5, 5, 4, 0.75, True)) genome.add_connection(Connection(6, 5, 3, 0.55, True)) net = Network(genome) input = [1., 2., 3.] for _ in range(3): output = net.calculate(input) print(f'Output len={len(output)}, output[0]={output[0]}=0.99895') print()
def test_run(self): g = Genome(3, 1, initializer=lambda: random.random()) g.connect_nodes_by_id(1, 4, 1) g.connect_nodes_by_id(2, 4, 2) g.connect_nodes_by_id(3, 4, 3) g.create_node_between(2, 4, 5, 4) g.connect_nodes_by_id(1, 5, 6) g.connect_nodes_by_id(5, 5, 7) output = g.run([1, 1, 1]) self.assertNotEqual(0, output[0])
def test_get_output_nodes(self): g = Genome(3, 1) self.assertEqual([4], [g.get_innovation() for g in g.get_output_nodes()])
def test_mutate_add_node(self): g = Genome(3, 1) g.connect_nodes_by_id(1, 4, 1) g.connect_nodes_by_id(2, 4, 2) g.connect_nodes_by_id(3, 4, 3) g.create_node_between(2, 4, 5, 4) g.connect_nodes_by_id(1, 5, 6) self.assertEqual(True, g.select_node_by_id(1).is_connected_to_next_by_id(4)) self.assertEqual(True, g.select_node_by_id(4).is_connected_to_prev_by_id(1)) self.assertEqual(True, g.select_node_by_id(1).is_connected_to_next_by_id(5)) self.assertEqual(True, g.select_node_by_id(2).is_connected_to_next_by_id(5)) self.assertEqual(True, g.select_node_by_id(5).is_connected_to_next_by_id(4)) self.assertEqual(True, g.select_node_by_id(3).is_connected_to_next_by_id(4)) g.create_node_between(3, 4, 6, 7) self.assertIsNotNone(g.select_node_by_id(6)) self.assertRaises(Exception, lambda: g.select_node_by_id(7))
def test_mutate_add_connection(self): g = Genome(3, 1) g.connect_nodes_by_id(1, 4, 1) g.connect_nodes_by_id(2, 4, 2) g.connect_nodes_by_id(3, 4, 3) g.create_node_between(2, 4, 5, 4) g.connect_nodes_by_id(1, 5, 6) self.assertEqual(True, g.select_node_by_id(1).is_connected_to_next_by_id(4)) self.assertEqual(True, g.select_node_by_id(4).is_connected_to_prev_by_id(1)) self.assertEqual(True, g.select_node_by_id(1).is_connected_to_next_by_id(5)) self.assertEqual(True, g.select_node_by_id(2).is_connected_to_next_by_id(5)) self.assertEqual(True, g.select_node_by_id(5).is_connected_to_next_by_id(4)) self.assertEqual(True, g.select_node_by_id(3).is_connected_to_next_by_id(4)) g.connect_nodes_by_id(3, 5, 7) self.assertEqual(True, g.select_node_by_id(3).is_connected_to_next_by_id(5))
def test(genome, node_inno, con_inno): genome[2] = Genome.crossover(genome[0], genome[1], 0.10) print(genome[2]) pass
def run_simulation(): multiprocessing.set_start_method( 'spawn') # Spawn fresh worker processes, don't use fork config = load_config() setup_logging(config['log_level']) Evolution.set_globals_from_config(config) Speciation._config = config print('Using these parameters:') for k, v in config.items(): print('- {}: {}'.format(k, v)) global mutations_in_gen population_size = config['population_size'] # default 500 generations = config['generations'] # default 100 species_list = [] genomes_list = [] input_nodes = config['input_nodes'] # default 130 output_nodes = config['output_nodes'] # default 7 initial_nodes = [i + 1 for i in range(input_nodes + output_nodes)] new_genome = Genome.Genome(1, 1, initial_nodes, input_nodes, output_nodes) number_of_new_connections = random.randint(2, 8) for i in range(number_of_new_connections): new_genome.add_connection() new_species = Species.Species(new_genome) species_list.append(new_species) genomes_list.append(new_genome) data = CollectData.DataCollection(population_size, generations, config) for i in range(population_size - 1): new_genome = Genome.Genome(i + 2, 1, initial_nodes, input_nodes, output_nodes) number_of_new_connections = random.randint(1, 4) for _ in range(number_of_new_connections): new_genome.add_connection() Speciation.add_to_species(species_list, new_genome) genomes_list.append(new_genome) print('New genomes added to species list:', input_nodes + output_nodes) print('Number of new species:', len(species_list)) simulator = ParallelSimulator(num_workers=config['num_workers'], max_steps=config['max_simulation_steps'], render=config['render']) for gen_num in range(1, generations + 1): mutations_in_gen = [] """ counter = 0 for genome in genomes_list: SimulateMario.simulate_run(genome, 5000, False) counter += 1 print('Simulating genome:', counter) """ simulator.simulate_genomes(genomes_list) data.collect_data(genomes_list, gen_num, len(species_list)) print('\nFitness:', [genome.fitness for genome in genomes_list]) # for genome in genomes_list: # print(genome.fitness) print('\nMaking new children.') print('\nNumber of species:', len(species_list)) Speciation.calculate_adjusted_fitness(species_list) genomes_list = Evolution.make_new_generation(population_size, species_list, gen_num + 1) """ Empty all genomes from species """ for species in species_list: # species.update_species_parameters() species.genomes = [] """ Add new genomes to the existing species, or create new ones """ for i in range(0, len(genomes_list)): Speciation.add_to_species(species_list, genomes_list[i]) print('Generation', gen_num, 'done.\n') """ Remove all species without genomes """ species_without_genomes_exist = True while species_without_genomes_exist: species_without_genomes_exist = False for i in range(0, len(species_list)): if len(species_list[i].genomes) == 0: del species_list[i] species_without_genomes_exist = True break """ Replace old species representative with new """ for species in species_list: species.replace_representative()
def test(genome, node_inno, con_inno): Genome.load('output/save_load.json', genome)
def newGeneration(): global reproduction_count reproduction_count = 0 global next_generation # if len(next_generation) > 1: # if len(next_generation) < 10: # neat.species_threshold -= 0.3 # elif len(next_generation) >= 10: # neat.species_threshold +=0.3 children = [] calculateAverageFitness(next_generation) updateStagnationInformation() removeStagnantSpecies() calculateAverageFitness(next_generation) totalFitness = totalAverageFitness(next_generation) for x in next_generation: genelog.info("[Species : " + str(x.number) + " Organisms: " + str(len(x.organisms)) + " ]") x.sort() if (len(x.organisms) > 10): x.removeUnfit() genelog.info("[Trim Step- Organisms Survived: " + str(len(x.organisms)) + " ]") breedCount = int((x.repFitness / totalFitness) * gen_iterations) - 1 for i in range(breedCount): if random.random() < crossover_rate and len(x.organisms) > 1: genelog.info("[ORGANISM]") xx = random.randrange(0, len(x.organisms)) xy = random.randrange(0, len(x.organisms)) while xx == xy: xx = random.randrange(0, len(x.organisms)) xy = random.randrange(0, len(x.organisms)) if x.organisms[xy].global_fitness > x.organisms[ xx].global_fitness: temp = xx xx = xy xy = temp childGenome = Genome.crossover(x.organisms[xx].genome, x.organisms[xy].genome) reproduction_count += 1 # apply random chance of further mutation childGenome.mutate() childGenome.mutate_topology() childOrganism = Agent(i_shape, o_shape, childGenome, agent_name) # TODO: random enable disable genes children.append(childOrganism) else: xx = random.randrange(0, len(x.organisms)) childGenome = copy.deepcopy(x.organisms[xx].genome) childGenome.mutate() childOrganism = Agent(i_shape, o_shape, childGenome, agent_name) children.append(childOrganism) reproduction_count += 1 if random.random() < mating_rate and len(next_generation) > 1: print("Interspecies Breeding") xx = x.organisms[0] xy = next_generation[random.randrange( 0, len(next_generation))].organisms[0] while xx == xy: xy = next_generation[random.randrange( 0, len(next_generation))].organisms[0] childGenome = Genome.crossover(xx.genome, xy.genome) reproduction_count += 1 childGenome.mutate() childGenome.mutate_topology() childOrganism = Agent(i_shape, o_shape, childGenome, agent_name) children.append(childOrganism) for species in next_generation: species.reduce() for organism in children: speciate(organism) global exceeded
def test_crossover(self): g1 = Genome(3, 1) g1.create_node(Node.TYPE_HIDDEN, 5) g1.connect_nodes_by_id(1, 4, 1) g1.connect_nodes_by_id(2, 4, 2) g1.connect_nodes_by_id(3, 4, 3) g1.connect_nodes_by_id(2, 5, 4) g1.connect_nodes_by_id(5, 4, 5) g1.connect_nodes_by_id(1, 5, 8) g2 = Genome(3, 1) g2.create_node(Node.TYPE_HIDDEN, 5) g2.create_node(Node.TYPE_HIDDEN, 6) g2.connect_nodes_by_id(1, 4, 1) g2.connect_nodes_by_id(2, 4, 2) g2.connect_nodes_by_id(3, 4, 3) g2.connect_nodes_by_id(2, 5, 4) g2.connect_nodes_by_id(5, 4, 5) g2.connect_nodes_by_id(5, 6, 6) g2.connect_nodes_by_id(6, 4, 7) g2.connect_nodes_by_id(3, 5, 9) g2.connect_nodes_by_id(1, 6, 10) p = Population(2, 3, 1) p.population[0] = g1 p.population[1] = g2 a1, a2 = Population.align_genome(g1, g2) g3 = Population.crossover(a1, a2, g1.get_input_nodes(), g1.get_output_nodes()) self.assertEqual(10, len(g3.connections)) self.assertEqual(6, len(g3.nodes)) self.assertEqual(1, g3.select_connection_by_innovation(1).get_innovation()) self.assertEqual(2, g3.select_connection_by_innovation(2).get_innovation()) self.assertEqual(3, g3.select_connection_by_innovation(3).get_innovation()) self.assertEqual(4, g3.select_connection_by_innovation(4).get_innovation()) self.assertEqual(5, g3.select_connection_by_innovation(5).get_innovation()) self.assertEqual(6, g3.select_connection_by_innovation(6).get_innovation()) self.assertEqual(7, g3.select_connection_by_innovation(7).get_innovation()) self.assertEqual(8, g3.select_connection_by_innovation(8).get_innovation()) self.assertEqual(9, g3.select_connection_by_innovation(9).get_innovation()) self.assertEqual(10, g3.select_connection_by_innovation(10).get_innovation()) self.assertEqual((2, 3), Population.calculate_excess_disjoint(g1, g2)) self.assertEqual(5, species_distance(g1, g2))