def create_new_population(self, operations): # print("\nCreating initial population...") genome = Genome(operations[:]) genome.score = calculate_fitness(genome.operations) self.genomes.append(genome) for _ in range(self.population_size): genome = Genome(shuffle_valid_genome(operations[:])) genome.score = calculate_fitness(genome.operations) self.genomes.append(genome)
def crossover(self, parent1: Genome, parent2: Genome) -> Genome: child1: Genome = Genome(2, 2) child2: Genome = Genome(2, 2) for i in range(parent1.nvariables): if (random() < 0.5): child1.variable(i, parent1.variable(i)) child2.variable(i, parent2.variable(i)) else: child1.variable(i, parent2.variable(i)) child2.variable(i, parent1.variable(i)) self._population.add_genome(child1) self._population.add_genome(child2)
def run(self, ngeneration: int, populationsize: int, crossoverrate: float, mutationrate: float, problem: ZDTOne): self._population = NonDominatingSortingPopulation() for generationcount in range(populationsize): gene: Genome = Genome(2, 2) gene.calculate_fitnesses(problem) self._population.add_genome(gene) self._population.rank() for generationcount in tqdm(range(ngeneration)): for nchildren in range(populationsize): parent1: Genome = self.tournament_selection(populationsize) parent2: Genome = self.tournament_selection(populationsize) rand = random() if (rand < crossoverrate): self.crossover(parent1, parent2) else: self._population.add_genome(parent1) self._population.add_genome(parent2) if (random() < mutationrate): self.mutate(self._population.get_genome(-1)) self.mutate(self._population.get_genome(-2)) self._population.get_genome(-1).calculate_fitnesses(problem) self._population.get_genome(-2).calculate_fitnesses(problem) self._population.rank() self._population.truncate(populationsize) return self._population
def initialize_population(self, population=None, size=None): if population is not None: self.previous_generation = population self.max_id = len(population.keys()) elif size is not None: self.max_id = self.config.POPULATION_SIZE pop_size = self.config.POPULATION_SIZE input_size = size[0] output_size = size[1] for genome_id in range(pop_size): genome = Genome(genome_id) node_id = 0 # Input Nodes for _ in range(input_size): node_gene = self.random.choice(self.node_classes)(node_id, NodeType.INPUT) genome.add_node_gene(node_gene) node_id += 1 # Output Nodes for _ in range(output_size): node_gene = self.random.choice(self.node_classes)(node_id, NodeType.OUTPUT) genome.add_node_gene(node_gene) node_id += 1 # Connect each input to every other output for in_id in range(input_size): for out_id in range(output_size): connection = ConnectionGene(in_id, out_id + input_size, 1.0, True, self.innovator.next_innovation_number((in_id, out_id))) genome.add_connection_gene(connection) self.previous_generation[genome_id] = genome else: raise ValueError("Invalid Parameters")
def create_asexual_genome(parent, mutation_tracker, newNodeProb=0.03, newConnectionProb=0.05, alterConnectionProb=0.8, newConnectionValueProb=0.1): new_c_genes = {} new_n_genes = {} # clone the parent for key, value in parent.n_genes.items(): new_n_genes[key] = copy.deepcopy(value) for key, value in parent.c_genes.items(): new_c_genes[key] = copy.deepcopy(value) # apply mutation to all connection for c_key in new_c_genes: if not new_c_genes[c_key].disable: if np.random.uniform(0, 1) < alterConnectionProb: new_c_genes[c_key] = alter_connection(new_c_genes[c_key], newConnectionValueProb) child_genome = Genome(parent.input_size, parent.output_size, new_n_genes, new_c_genes, parent.generation + 1, [parent.species_id]) # apply new nodes mutation if np.random.uniform(0, 1) < newNodeProb: add_node_mutation(child_genome, mutation_tracker) # apply new connection mutation if np.random.uniform(0, 1) < newConnectionProb: add_connection_mutation(child_genome, mutation_tracker) return child_genome
def create_members(self): nkey = str(self.niecheID) self.nieches[nkey] = Nieche(self.niecheID) for i in range(self.members): # Create a new genome gkey = str(self.genome_id) self.genomes[gkey] = Genome( weight_mutation = self.weight_mutation, input_nodes = self.inputs, output_nodes = self.outputs, genome_id = self.genome_id) # Create input, output nodes, and connect them self.genomes[gkey].create_inputs() self.genomes[gkey].create_outputs() self.genomes[gkey].create_innitial_connections() # Tell which nieche this node is belongs to, at init all belongs to the same, the 0 self.genomes[gkey].set_nieche_id(self.niecheID) # At init add every member to the first nieche/species self.nieches[nkey].add_member(self.genome_id) # Increment ID self.genome_id += 1 #The newly created Genomes has init innovations, connection between outputs and inputs #which we need to group together self.group_innovations() self.niecheID += 1
def initial_generation(self): initial_genomes = [] for i in range(self.population): g = Genome() g.solution = random_solution(self.genome_length) initial_genomes.append(g) return Generation(initial_genomes, self.answer)
def conceive(self, mother: Genome, father: Genome, prisoner_cb: Callable[[Prisoner], None]) -> None: # Construct duplicates of the mother and father. mother = Genome(mother.genes) father = Genome(father.genes) # Perform a uniform crossover. mother.crossover(father, Genetics.__uniform_crossover) # Mutate both sets of genes. mother.mutate(self.__uniform_mutation) father.mutate(self.__uniform_mutation) # Pass the two children to the callback. prisoner_cb(Prisoner(mother)) prisoner_cb(Prisoner(father))
def create_new_genome(input_size, output_size, fully_connected=False): nodes_genes = {} for i in range(0, input_size): nodes_genes[i] = NodeGene(input_nodes=None, output_nodes=[], neuron_type='i') for j in range(input_size, input_size + output_size): nodes_genes[j] = NodeGene(input_nodes=[], output_nodes=[], neuron_type='o') cpt = input_size + output_size connection_genes = dict() if fully_connected: for i in range(0, input_size): for j in range(input_size, input_size + output_size): connection_genes[i, j] = ConnectionGene(cpt, Mutation.get_new_weight(), False) nodes_genes[i].output_nodes.append(j) nodes_genes[j].input_nodes.append(i) cpt += 1 return Genome(input_size=input_size, output_size=output_size, nodes_genes=nodes_genes, connection_genes=connection_genes, generation=0, parents_species_id=[])
def run(self): population = [] best_genome = None data = [] for _ in range(population_total): genome_dna = generate(problem_grid) population.append(Genome(genome_dna)) for i in range(simulations): population_fitness = 0 for genome in population: genome.fitness() population_fitness += genome.getFitness() sorted_population = population.copy() best_genome = max(population, key=operator.attrgetter('fit')) best_fitness = round(1 / best_genome.getFitness()) data.append(best_fitness) if i % 1000 == 0: self.show(i, best_genome) if best_fitness <= limit: print('DONE\n') population.clear() population.append(best_genome) while len(population) < population_total: new_genome = tournamentSelection(sorted_population) option_2 = tournamentSelection(sorted_population) if npR.uniform() < crossover_rate: option_3 = tournamentSelection(sorted_population) dna_1 = crossover(new_genome, option_2, option_3) new_genome = Genome(dna_1) if npR.uniform() < mutation_rate: new_genome.mutateSell(problem_grid) population.append(new_genome) self.show(i, best_genome) return data
def initializePool(env): pool = Pool(env) for i in range(0, Population): basic = Genome(pool) basic.basicGenome() pool.addToSpecies(basic) pool.initializeRun() return pool
def get_child(self, parent1, parent2): new_genome = Genome(weight_mutation=self.weight_mutation, input_nodes=self.inputs, output_nodes=self.outputs, genome_id=self.genome_id) self.genome_id += 1 fitness1 = parent1.get_fitness() fitness2 = parent2.get_fitness() if(fitness1 > fitness2): genome1 = parent1 genome2 = parent2 else: genome1 = parent2 genome2 = parent1 for conn1 in genome1.get_connection_genes(): copy_con1 = copy.deepcopy(conn1) excessGene = True disjointGene = False newConn = 0 for conn2 in genome2.get_connection_genes(): copy_con2 = copy.deepcopy(conn2) # Both have connection with this innovation number if(conn1.get_innovation_number() == conn2.get_innovation_number()): excessGene = False # The expressed parameter is not matching if(conn1.expressed != conn2.expressed): disjointGene = True # Get the deltaWeight, because everything seems to be in order else: newConn = copy_con1 if(randint(0,1) == 1) else copy_con2 if(excessGene == True): new_genome.connection_genes.append(copy_con1) elif(disjointGene == True): new_genome.connection_genes.append(copy_con1) else: new_genome.connection_genes.append(newConn) #Add node #nodeIn, nodeOut = copy.deepcopy(new_genome.connection_genes[-1].get_connected_nodes()) nodeInID, nodeOutID = copy.copy(new_genome.connection_genes[-1].get_connected_nodes_id()) #Add node if there wasnt any node like this before if(new_genome.get_node_by_id(nodeInID) == False): node = copy.deepcopy(genome1.get_node_by_id(nodeInID)) new_genome.node_genes.append(node) if(new_genome.get_node_by_id(nodeOutID) == False): node = copy.deepcopy(genome1.get_node_by_id(nodeOutID)) new_genome.node_genes.append(node) # Get the higher global node id copy_gnID1 = copy.copy(parent1.global_node_id) copy_gnID2 = copy.copy(parent2.global_node_id) new_genome.global_node_id = copy_gnID1 if(copy_gnID1>copy_gnID2) else copy_gnID2 return new_genome
class UnitOfWork: _dataSet=[] _genomes=[Genome('Num_units',20,50), Genome('learning_rate',0. 0020,0.0030), Genome('lambda_loss_amount',0.0010,0.0020), Genome('Batch_size',1000,2000), Genome('Num_iterations',100,500), Genome('Segment_size',100,200), ] _popSize=10 _perMut=0.5 _iteration=22 # _test_user_ids=[2, 4, 9, 10, 12, 13, 18, 20, 24] in DataSet def __init__(self, pathDataset='datasets/uci_raw_data'): _genomes=[] self._dataSet=DataSet(pathDataset,'l')
def reproduce_population(self): """ The miracle of life This method will take two random parents and create two children from them. """ first_child, second_child = self.mate() mutate_genome(first_child) mutate_genome(second_child) first_genome = Genome(first_child) second_genome = Genome(second_child) first_genome.score = calculate_fitness(first_child) second_genome.score = calculate_fitness(second_child) self.genomes.append(first_genome) self.genomes.append(second_genome) self.sort_population() self.reap_population()
def apply(self, mutant_vector, target_vector, Cr): genes = [] for j in range(0, len(mutant_vector.get_genes())): randji = random.uniform(0, 1) Jrand = random.randint(0, len(mutant_vector.get_genes())) if randji <= Cr or j == Jrand: genes.append(mutant_vector.get_genes()[j]) else: genes.append(target_vector.get_genes()[j]) uig = Genome(genes) return uig
def __init__(self, psize, bounds): self.population_list = [] i = 0 while i < psize: genes = [] for j in bounds: genes.append(random.uniform(j[0], j[1])) new_genome = Genome(genes) self.population_list.append(new_genome) i = i + 1
def tournament(self, prev_generation): new_genome = Genome() # pick two parents parent_genome_1 = pick_parent(prev_generation) parent_genome_2 = pick_parent(prev_generation) new_genome.solution = crossover(parent_genome_1, parent_genome_2) new_genome.solution = mutate(new_genome.solution, self.mutation_rate) return new_genome
def breedChild(self): child = Genome() if random.random() < CrossoverChance: g1 = self.genomes[random.randint(1, len(self.genomes))] g2 = self.genomes[random.randint(1, len(self.genomes))] child = g1.crossover(g2) else: g = self.genomes[random.randint(1, len(self.genomes))] child = g.clone() child.mutate() return child
def get_clone(self, genome): # Create a child child = Genome(weight_mutation=self.weight_mutation, input_nodes=self.inputs, output_nodes=self.outputs, genome_id=self.genome_id) self.genome_id += 1 # Copy the parents genes to the child child.connection_genes = copy.deepcopy(genome.connection_genes) child.node_genes = copy.deepcopy(genome.node_genes) child.global_node_id = copy.copy(genome.global_node_id) # I dont have to mutate the child, it will be mutated all together. return child
def __init__(self): assert INPUTS != 0 and OUTPUTS != 0, "You must call the initialize method before creating players!" self.fitness = -1 self.unadjustedFitness = -1 self.brain = Genome(INPUTS, OUTPUTS, False) self.vision = [] self.actions = [] self.lifespan = 0 self.dead = False self.replay = False self.gen = 0 self.name = "" self.speciesName = "Not yet defined"
def apply(self, mutant_vector, target_vector, Cr): genes = [] for j in range(0, len(mutant_vector.genes)): max_bounds = self.bounds[j][1] min_bound = self.bounds[j][0] res = target_vector.get_genes()[j] + Cr * (mutant_vector.get_genes()[j] - target_vector.get_genes()[j]) if res >= max_bounds: res = max_bounds if res <= min_bound: res = min_bound genes.append(res) genes.append(res) uig = Genome(genes) return uig
def generate_complete_genome(id, n, r, ir): g = Genome(id) for i in range(n): g.add_node_gene(TestNode(i, r.choice(list(NodeType)))) for i in range(n): for j in range(i, n): w = r.random() a = r.random() < 0.7 inr = ir.next_innovation_number((i, j)) g.add_connection_gene(ConnectionGene(i, j, w, a, inr)) return g
def __init__(self, genome_1: Genome, genome_2: Genome): """ Constructor Parameters ---------- genome_1 First genome for distance calculation genome_2 Genome to test distance from the first one """ gene_count_1: int = 0 gene_count_2: int = 0 self.genome_1: Genome = Genome(list()) # Genome 1 as String self.genome_2: Genome = Genome(list()) # Genome 2 as String for chromosome in genome_1.chromosomes: if len(chromosome.genes) != 0: gene_count_1 += len(chromosome.genes) self.genome_1.add_chromosome(chromosome) for chromosome in genome_2.chromosomes: if len(chromosome.genes) != 0: gene_count_2 += len(chromosome.genes) self.genome_2.add_chromosome(chromosome) if gene_count_1 == gene_count_2: # Algorithm requires genomes are equal length self.gene_count: int = gene_count_1 # Number of genes else: raise Exception("Different numbers of genes in both genomes.\n") self.node_ints: ndarray = npzeros(self.gene_count * 2) self.node_strings_1: List[Optional[str]] = list() self.node_strings_2: List[Optional[str]] = list() self.genome_paths_1: List[Optional[BPGPath]] = list() self.genome_paths_2: List[Optional[BPGPath]] = list() self.distance: int = int()
def run(self): for _ in range(population_total): scramble = shuffle(key) self.population.append(Genome(scramble)) for _ in range(100000): #print('GENERATION :', i, round(1/population[0].getFitness())) population_fitness = 0 for genome in self.population: genome.fitness(row_score, col_score) population_fitness += genome.getFitness() for genome in self.population: genome.setFitness2Population(population_fitness) sorted_population = sorted( self.population, key=operator.attrgetter('fitness_ratio')) sorted_population.reverse() best = sorted_population[0] sorted_population.append(best) if 1 / best.getFitness() <= 10: break self.population.clear() for _ in range(population_total - 1): new_genome = rouletteSelection(sorted_population) option_2 = rouletteSelection(sorted_population) if npR.uniform() < crossover_rate: new_genome = Genome(crossover(new_genome, option_2)) if npR.uniform() < mutation_rate: new_genome.mutate() self.population.append(new_genome)
def apply(self, target_vector): genes = [] res_SO = SOperator(self.population_list).apply(target_vector) x1 = res_SO[1] x2 = res_SO[2] global F for i in range(0, len(target_vector.genes)-1): max_bound = self.bounds[i][1] min_bound = self.bounds[i][0] res = target_vector.genes[i] + F * (x1.genes[i] - x2.genes[i]) if res >= max_bound: res = max_bound if res <= min_bound: res = min_bound genes.append(res) vig = Genome(genes) return vig
def generate_genome(id, n, r, ir): g = Genome(id) max_c = int(n * (n - 1) / 2) c = r.randint(max_c - 1, max_c) for i in range(n): g.add_node_gene(TestNode(i, r.choice(list(NodeType)))) for _ in range(c): i = r.randint(0, n - 1) o = r.randint(0, n - 1) w = r.random() a = r.random() < 0.7 inr = ir.next_innovation_number((i, o)) g.add_connection_gene(ConnectionGene(i, o, w, a, inr)) return g
def loadFile(self, filename, env): file = open(filename, "r") self.__init__(env) self.generation = int(file.readline().replace("\n", "")) self.maxFitness = int(file.readline().replace("\n", "")) #gui.settext(5, 8, maxFitnessLabel, "Max Fitness. " .. math.floor(pool.maxFitness)) numSpecies = int(file.readline().replace("\n", "")) for s in range(0, numSpecies): species = Species() self.species.append(species) species.topFitness = float(file.readline().replace("\n", "")) species.staleness = int(file.readline().replace("\n", "")) numGenomes = int(file.readline().replace("\n", "")) for g in range(0, numGenomes): genome = Genome(self) species.genomes.append(genome) genome.fitness = float(file.readline().replace("\n", "")) genome.maxneuron = int(file.readline().replace("\n", "")) line = file.readline().replace("\n", "") while line != "done": genome.mutationRates[line] = float(file.readline().replace( "\n", "")) line = file.readline().replace("\n", "") numGenes = int(file.readline().replace("\n", "")) for n in range(0, numGenes): gene = Gene() genome.genes.append(gene) enabled = 0 line = file.readline() data = [] for x in [x for i, x in enumerate(line.split(" "))]: try: data.append(int(x)) except ValueError: data.append(float(x)) gene.into, gene.out, gene.weight, gene.innovation, enabled = data gene.enabled = enabled == 1 file.close() while self.fitnessAlreadyMeasured(): self.nextGenome() self.initializeRun() self.currentFrame = self.currentFrame + 1
def __init__(self, t_population, input_n, output_n, target_fitness): self.t_pop = t_population self.input_n = input_n self.output_n = output_n self.innov_dict = {} self.id_dict = {} # id_dict is dictionary that has innovation number of connections as key and the id # number of node created by dividing the connection as value of the key self.id_timer = {} self.population = [] self.species = [] self.species_fitness_counter = [] self.species_max_fitness = [] self.population_max = 0 self.population_max_timer = 0 self.best_genome = Genome( ) # The fittest genome to ever exist in the population self.target = target_fitness
def start_genomes(self, gene_pool: GenePool, conditions: Conditions) -> List[Genome]: """ Creates the starter genomes :param conditions: The conditions to use when creating new genes :param gene_pool: The gene pool to update with the starter genomes :return: A list of starter genomes """ in_size = self.simulation.get_data_size() out_size = self.simulation.get_controls_size() for in_ in range(1, in_size + 1): gene_pool.node_depths[in_] = conditions.app_start_node_depth for out_ in range(0, -out_size, -1): gene_pool.node_depths[out_] = conditions.app_end_node_depth starter_genomes = [] starter_genes = [] for in_ in range(1, in_size + 1): for out_ in range(0, -out_size, -1): gene = Gene(random.random() * (self.conditions.gene_max_weight - self.conditions.gene_min_weight) + self.conditions.gene_min_weight, in_, out_, 0, gene_pool=gene_pool) starter_genes.append(gene) for i in range(self.conditions.population_size): new_genes = [gene.copy() for gene in starter_genes] for gene in new_genes: gene.weight = (random.random() * (self.conditions.gene_max_weight - self.conditions.gene_min_weight) + self.conditions.gene_min_weight) starter_genomes.append( Genome(new_genes, in_size, out_size, gene_pool)) return starter_genomes
def run(population: int, generations: int, mutation_rate: float, tests: int, seed: int) -> None: random.seed(seed) # Population of prisoners -- modified each generation. prisoners = [Prisoner(Genome()) for _ in range(population)] # Controls mutation, crossover, and re-population. genetics = Genetics(mutation_rate) for generation in range(0, generations): costs = [0] * population # Initialize costs to zero each generation. random.shuffle(prisoners) # De-segregate parents and children. Simulation.__assess_population(prisoners, generation) # Group up each prisoner with a random unique partner. for i in range(0, population, 2): # Perform the prisoner's dilemma test with the two subjects N times. for k in range(0, tests): Simulation.__cost(prisoners, costs, i, i + 1) # Sort the prisoners by cost, in ascending order. order = {v: i for i, v in enumerate(prisoners)} prisoners.sort(key=lambda x: costs[order[x]]) i = 0 cutoff_limit = population // 2 # Called when a new child is born and added to the population. def born_child_cb(child: Prisoner) -> None: nonlocal i # Replace an under-performing prisoner with a new child. prisoners[cutoff_limit + i] = child i += 1 while i in range(0, cutoff_limit): # Loop incremented via callback. j = random.randrange(i + 1, cutoff_limit) mother, father = prisoners[i], prisoners[j] mother.mature() father.mature() # Switch the father with the mother's right neighbor. prisoners[j] = prisoners[i + 1] prisoners[i + 1] = father genetics.conceive(mother.genome, father.genome, born_child_cb)