示例#1
0
    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()
示例#2
0
    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))
示例#3
0
class Trainer:
    def __init__(self, network, populationsize):
        self.population = Population(populationsize, network)
        self.network = network

    #The fitness function rewards based on how accurate the output is
    #Optimal fitness is reached if input[0] is substracted from input[1]
    #Iterations is the amount of training cycles
    #Mutationrate is the chance that offspring is mutated
    #Elitism is the amount of genomes that are put into the next generation without change
    def train(self, iterations, mutationrate, elitism):
        oldFitnessSum = 0
        newFitnessSum = 0
        for i in range(iterations):

            #EVALUATION

            for member in self.population.population:
                self.network.loadDNA(member)

                #repeat network evalutation 5 times for accuracy
                for _ in range(5):
                    #two random inputs
                    inputs = []
                    inputs.append(uniform(-5, 10))
                    inputs.append(uniform(-10, 20))
                    self.network.setInputs(inputs)

                    result = self.network.run()[0]
                    expectation = inputs[0] - inputs[1]
                    #perfect fitness if there is no difference
                    #we also square the difference because we want some dope ass inequality
                    member.fitness += 100 - pow(abs(result - expectation), 2)

            #PRINT GENERATION PROGRESS
            if (i % 2 == 0):
                oldFitnessSum = sum(dna.fitness
                                    for dna in self.population.population)
            else:
                newFitnessSum = sum(dna.fitness
                                    for dna in self.population.population)

            if (oldFitnessSum != 0 and newFitnessSum != 0):
                print("Gen Nr: " + str(i))
                print("Difference between Generation Fitness Sum: " +
                      str(round(newFitnessSum - oldFitnessSum, 2)))
                percentage = (newFitnessSum -
                              oldFitnessSum) / oldFitnessSum * 100
                print("Percentage difference between generation: " +
                      str(round(percentage, 2)) + "%")
                print("New Fitness Sum: " + str(round(newFitnessSum, 2)))
                print(
                    "Highest Fitness: " +
                    str(max(dna.fitness
                            for dna in self.population.population)))

            #CREATE NEW POPULATION

            #best genomes at beginning of list, so we can include them easily (elitism)
            self.population.population.sort(key=lambda x: x.fitness,
                                            reverse=True)
            #dont make a new generation on last iteration, so we can
            #take the population as-is and evaluate it one more time in main.py
            if (i < iterations - 1):
                population2 = []
                #add 5 best genomes unchanged
                for elitismIndex in range(elitism):
                    self.population.population[elitismIndex].fitness = 0
                    population2.append(
                        self.population.population[elitismIndex])
                for _ in range(len(self.population.population) - elitism):
                    parent1 = self.population.rouletteSelect()
                    parent2 = self.population.rouletteSelect()
                    child = self.population.crossover(parent1, parent2)
                    if (uniform(0, 1) < mutationrate):
                        child = self.population.mutate(child)
                    child.fitness = 0
                    population2.append(child)

                self.population.population = population2
        return self.population
示例#4
0
 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))