Exemple #1
0
    def reproduce(self, generation, pop, sorted_species):
        champ_done = False
        mut_power = neat.weight_mut_power
        total_fitness = 0.0
        
        if self.expected_offspring > 0 and len(self.organisms) == 0:
            return False

        poolsize = len(self.organisms) - 1
        thechamp_i = 0
        for count in range(0, self.expected_offspring):
            mut_struct_baby = False
            mate_baby = False
            outside = False
            mom = dad = None

            if self.organisms[thechamp_i].super_champ_offspring > 0:
                dprint(DEBUG_CHECK, "super_champ_offspring()")
                mom_i = thechamp_i
                mom = self.organisms[mom_i]
                new_genome = mom.gnome.duplicate(count)
                if self.organisms[thechamp_i].super_champ_offspring == 1:
                    pass
                if self.organisms[thechamp_i].super_champ_offspring > 1:
                    if neat.randfloat() < 0.8 or neat.mutate_add_link_prob == 0.0:
                        new_genome.mutate_link_weights(mut_power, 1.0, Genome.GAUSSIAN)
                    else:
                        net_analogue = new_genome.genesis(generation)
                        ok, pop.cur_innov_num = \
                            new_genome.mutate_add_link(pop.innovations, pop.cur_innov_num, neat.newlink_tries)
                        net_analogue = None
                        mut_struct_baby = True
                #
                baby = Organism()
                baby.SetFromGenome(0.0, new_genome, generation)
                if self.organisms[thechamp_i].super_champ_offspring == 1:
                    if self.organisms[thechamp_i].pop_champ:
                        baby.pop_champ_child = True
                        baby.high_fit = mom.orig_fitness
                #
                self.organisms[thechamp_i].super_champ_offspring -= 1
                self.verify_baby(baby, mom, dad)

                # super_champ_offspring > 0
            elif (not champ_done) and (self.expected_offspring > 5):
                dprint(DEBUG_CHECK, "champ()")
                mom_i = thechamp_i
                mom = self.organisms[mom_i]
                new_genome = mom.gnome.duplicate(count)
                baby = Organism()
                baby.SetFromGenome(0.0, new_genome, generation)
                champ_done = True
                self.verify_baby(baby, mom, dad)

                # (not champ_done) and (self.expected_offspring > 5)
            elif (neat.randfloat() < neat.mutate_only_prob) or (poolsize == 0):
                dprint(DEBUG_CHECK, "mutate_only()")
                mom_i = neat.randint(0, poolsize)
                mom = self.organisms[mom_i]
                new_genome = mom.gnome.duplicate(count)
                self.verify_genome(new_genome)

                if neat.randfloat() < neat.mutate_add_node_prob:
                    dprint(DEBUG_INTEGRITY, "a: pop.cur_node_id:", pop.cur_node_id)
                    ok, pop.cur_node_id, pop.cur_innov_num = \
                        new_genome.mutate_add_node(pop.innovations, pop.cur_node_id, pop.cur_innov_num)
                    dprint(DEBUG_INTEGRITY, "b: pop.cur_node_id:", pop.cur_node_id)
                    mut_struct_baby = True
                    self.verify_genome(new_genome)

                elif neat.randfloat() < neat.mutate_add_link_prob:
                    net_analogue = new_genome.genesis(generation)
                    ok, pop.cur_innov_num = \
                        new_genome.mutate_add_link(pop.innovations, pop.cur_innov_num, neat.newlink_tries)
                    net_analogue = None
                    mut_struct_baby = True
                    self.verify_genome(new_genome)

                else:
                    if neat.randfloat() < neat.mutate_random_trait_prob:
                        new_genome.mutate_random_trait()
                        self.verify_genome(new_genome)
                    if neat.randfloat() < neat.mutate_link_trait_prob:
                        new_genome.mutate_link_trait(1)
                        self.verify_genome(new_genome)
                    if neat.randfloat() < neat.mutate_node_trait_prob:
                        new_genome.mutate_node_trait(1)
                        self.verify_genome(new_genome)
                    if neat.randfloat() < neat.mutate_link_weights_prob:
                        new_genome.mutate_link_weights(mut_power, 1.0, Genome.GAUSSIAN)
                        self.verify_genome(new_genome)
                    if neat.randfloat() < neat.mutate_toggle_enable_prob:
                        new_genome.mutate_toggle_enable(1)
                        self.verify_genome(new_genome)
                    if neat.randfloat() < neat.mutate_gene_reenable_prob:
                        new_genome.mutate_gene_reenable()
                        self.verify_genome(new_genome)

                baby = Organism()
                baby.SetFromGenome(0.0, new_genome, generation)
                self.verify_baby(baby, mom, dad)

                # (neat.randfloat() < neat.mutate_only_prob) or (poolsize == 0)
            else:
                mom_i = neat.randint(0, poolsize)
                mom = self.organisms[mom_i]

                if neat.randfloat() > neat.interspecies_mate_rate:
                    # within species
                    dad_i = neat.randint(0, poolsize)
                    dad = self.organisms[dad_i]

                else:
                    # outside species
                    randspecies = self

                    giveup = 0
                    while (randspecies == self) and (giveup < 5):
                        randmult = neat.gaussrand() / 4.
                        if randmult > 1.0:
                            randmult = 1.0
                        randspeciesnum = int(math.floor( (randmult * (len(sorted_species) - 1.0)) + 0.5 ))
                        randspecies = sorted_species[randspeciesnum]
                        giveup += 1

                    dad = randspecies.organisms[0]
                    outside = True

                if neat.randfloat() < neat.mate_multipoint_prob:
                    dprint(DEBUG_CHECK, "mate_multipoint()")
                    new_genome = mom.gnome.mate_multipoint(dad.gnome, count, mom.orig_fitness, dad.orig_fitness, outside)
                elif neat.randfloat() < neat.mate_multipoint_avg_prob / (neat.mate_multipoint_avg_prob+neat.mate_singlepoint_prob):
                    dprint(DEBUG_CHECK, "mate_multipoint_avg()")
                    new_genome = mom.gnome.mate_multipoint_avg(dad.gnome, count, mom.orig_fitness, dad.orig_fitness, outside)
                else:
                    dprint(DEBUG_CHECK, "mate_singlepoint()")
                    new_genome = mom.gnome.mate_singlepoint(dad.gnome, count)

                mate_baby = True

                if ((neat.randfloat() > neat.mate_only_prob) or
                    (dad.gnome.genome_id == mom.gnome.genome_id) or
                    (dad.gnome.compatibility(mom.gnome) == 0.0)):
                    dprint(DEBUG_CHECK, "mate_and_mutate()")
                    if neat.randfloat() < neat.mutate_add_node_prob:
                        dprint(DEBUG_INTEGRITY, "a: pop.cur_node_id:", pop.cur_node_id)
                        ok, pop.cur_node_id, pop.cur_innov_num = \
                            new_genome.mutate_add_node(pop.innovations, pop.cur_node_id, pop.cur_innov_num)
                        dprint(DEBUG_INTEGRITY, "b: pop.cur_node_id:", pop.cur_node_id)
                        mut_struct_baby = True
                    elif neat.randfloat() < neat.mutate_add_link_prob:
                        net_analogue = new_genome.genesis(generation)
                        ok, pop.cur_innov_num = \
                            new_genome.mutate_add_link(pop.innovations, pop.cur_innov_num, neat.newlink_tries)
                        net_analogue = None
                        mut_struct_baby = True
                    else:
                        if neat.randfloat() < neat.mutate_random_trait_prob:
                            new_genome.mutate_random_trait()
                        if neat.randfloat() < neat.mutate_link_trait_prob:
                            new_genome.mutate_link_trait(1)
                        if neat.randfloat() < neat.mutate_node_trait_prob:
                            new_genome.mutate_node_trait(1)
                        if neat.randfloat() < neat.mutate_link_weights_prob:
                            new_genome.mutate_link_weights(mut_power, 1.0, Genome.GAUSSIAN)
                        if neat.randfloat() < neat.mutate_toggle_enable_prob:
                            new_genome.mutate_toggle_enable(1)
                        if neat.randfloat() < neat.mutate_gene_reenable_prob:
                            new_genome.mutate_gene_reenable()

                    baby = Organism()
                    baby.SetFromGenome(0.0, new_genome, generation)
                    self.verify_baby(baby, mom, dad)

                else:
                    dprint(DEBUG_CHECK, "mate_only()")
                    baby = Organism()
                    baby.SetFromGenome(0.0, new_genome, generation)
                    self.verify_baby(baby, mom, dad)

                # else

            baby.mut_struct_baby = mut_struct_baby
            baby.mate_baby = mate_baby
            
            curspecies_i = 0
            found = False
            while (curspecies_i < len(pop.species)) and (not found):
                comporg = pop.species[curspecies_i].first()
                if comporg == None:
                    curspecies_i += 1
                elif baby.gnome.compatibility(comporg.gnome) < neat.compat_threshold:
                    pop.species[curspecies_i].add_Organism(baby)
                    baby.species = pop.species[curspecies_i]
                    found = True
                else:
                    curspecies_i += 1
            #
            if not found:
                pop.last_species += 1
                newspecies = Species()
                newspecies.SetFromIdAndNovel(pop.last_species, True)
                pop.species.append(newspecies)
                newspecies.add_Organism(baby)
                baby.species = newspecies
                    

            # for count in self.expected_offspring

        return True