def swap_mutation(genome: Genome): for i in range(len(genome.genes)): if np.random.uniform(low=0, high=1) < Const.MUTATION_PROBABILITY: temp = genome.genes[i] index = np.random.randint(low=0, high=len(genome.genes)) genome.genes[i] = genome.genes[index] genome.genes[index] = temp return genome
def __init__(self, img, triangles): self.length = triangles self.img = img self.genome = Genome(img.width, img.height, triangles) self.fitness = self.genome.fitness(img) self.generation = 0
def gaussian(genome: Genome): for i in range(len(genome.genes)): if np.random.uniform(low=0, high=1) < Const.MUTATION_PROBABILITY: genome.genes[i] = np.clip([np.random.normal(scale=0.5)], -Const.GENOME_BOUNDS, Const.GENOME_BOUNDS)[0] return genome
def __init__(self, image, int_res, n_triangles, pop_size): """ Create a new population of random genomes. """ assert pop_size % 2 == 0, 'Population size must be even' self.bestFitness = None self.bestGenome = None self.generation = 0 self.fitnessRanking = None self.image = image self.int_res = int_res self.length = n_triangles self.size = pop_size #+ 1 self.ref = self.image.copy() self.ref.thumbnail((100, 100), Image.ANTIALIAS) sp = np.linspace(self.MIN_SP, self.MAX_SP, self.size) # Selection pressure per ranking self.distribution = np.cumsum(sp) / np.sum( sp) # Cumulative selection distribution self.members = [] for i in range(self.size): self.members.append(Genome(n_triangles))
def _init_genome(self, observation_space: gym.Space, action_space: gym.Space) -> Genome: all_layer_sizes = [np.product(observation_space.shape) ] + self.hidden_nodes + [action_space.n] weights = [ np.random.uniform(-1, 1, size=[i + 1, o]) for (i, o) in zip(all_layer_sizes[:-1], all_layer_sizes[1:]) ] return Genome(weights)
def _init_genome(observation_space: gym.Space, action_space: gym.Space) -> Genome: weights = [ np.random.uniform( -1, 1, size=[np.product(observation_space.n) + 1, action_space.n]), ] return Genome(weights)
def climb(self): newGenome = Genome(self.img.width, self.img.height, self.length, genes=self.genome.genes) rate = 1.0 while uniform(0, 1) < rate: i = randint(0, self.length - 1) newGenome.genes[i].mutate() rate = 2 * rate / 3 newFitness = newGenome.fitness(self.img) #print('%d %d' % (self.fitness, newFitness)) #print('') if newFitness < self.fitness: self.genome = newGenome self.fitness = newFitness self.generation += 1
def build_agent(observation_space: gym.Space, action_space: gym.Space) -> \ Tuple[Callable[[Genome, np.ndarray], np.ndarray], Genome]: weights = [ np.random.uniform(-1, 1, size=[np.product(observation_space.n) + 1, 10]), np.random.uniform(-1, 1, size=[10 + 1, action_space.n]) ] def _get_action(genome: Genome, ob: np.ndarray) -> np.ndarray: ob_reshaped = ob.reshape([1, np.product(ob.shape)]) h1 = sigmoid((cat_ones(ob_reshaped).dot(genome.values[0]))) action_logits = sigmoid((cat_ones(h1).dot(genome.values[1]))) return np.argmax(action_logits) return _get_action, Genome(weights)
def build_agent(observation_space: gym.Space, action_space: gym.Space) -> \ Tuple[Callable[[Genome, np.ndarray], np.ndarray], Genome]: weights = [ np.random.uniform( -1, 1, size=[np.product(observation_space.n) + 1, action_space.n]), ] def _get_action(genome: Genome, ob: np.ndarray) -> np.ndarray: ob_reshaped = ob.reshape([1, np.product(ob.shape)]) action_logits = softmax( (cat_ones(ob_reshaped).dot(genome.values[0])), temperature=1E-3) return np.random.choice(np.arange(action_space.n), p=action_logits[0]) return _get_action, Genome(weights)
def breed(self) -> None: """Modify the genomes of the agents to create the next generation.""" self.generation += 1 # Crossover and mutation. current_genomes = [a.genome for a in self.agents] # Filter out champions. argsorted_indices = np.argsort(self.fitnesses) champion_indices = argsorted_indices[-self.num_champions:] new_genomes = [current_genomes[i] for i in champion_indices] # Breed remaining population weighted by fitness. d = Distribution(self.fitnesses, current_genomes) for i in range(self.num_champions, self.num_agents): a, b = d.sample(n=2) new_genomes.append(Genome.crossover(a, b).mutate(p=0.01)) print(f"\rBreeding... agent {i+1}/{self.num_agents} ", end="") print("\r", end="") # Assign Genomes to Agents. for a, g in zip(self.agents, new_genomes): a.genome = g
class Climber: #MUTATION_RATE = 0.5 def __init__(self, img, triangles): self.length = triangles self.img = img self.genome = Genome(img.width, img.height, triangles) self.fitness = self.genome.fitness(img) self.generation = 0 def climb(self): newGenome = Genome(self.img.width, self.img.height, self.length, genes=self.genome.genes) rate = 1.0 while uniform(0, 1) < rate: i = randint(0, self.length - 1) newGenome.genes[i].mutate() rate = 2 * rate / 3 newFitness = newGenome.fitness(self.img) #print('%d %d' % (self.fitness, newFitness)) #print('') if newFitness < self.fitness: self.genome = newGenome self.fitness = newFitness self.generation += 1
def boundary(genome: Genome): for i in range(len(genome.genes)): if np.random.uniform(low=0, high=1) < Const.MUTATION_PROBABILITY: genome.genes[i] = Const.GENOME_BOUNDS * ( 1 if np.random.uniform(low=0, high=1) < 0.5 else -1) return genome
def mutationInt(genome: Genome): for i in range(len(genome.genes)): if np.random.uniform(low=0, high=1) < Const.MUTATION_PROBABILITY: genome.genes[i] = np.random.randint(low=-Const.GENOME_BOUNDS, high=Const.GENOME_BOUNDS) return genome
# Find the AIFH core files aifh_dir = os.path.dirname(os.path.abspath(__file__)) aifh_dir = os.path.abspath(aifh_dir + os.sep + ".." + os.sep + "lib" + os.sep + "aifh") sys.path.append(aifh_dir) from genetic import * from genetic import Genome from genetic import Species population = Population() species = Species(population) # Construct a simple population for i in range(0,999): genome = Genome() genome.score = i species.members.append(genome) # Perform the test for round counts between 1 and 10. for round_count in range(1,11): selection = TournamentSelection() selection.rounds = round_count sum = 0 count = 0; for i in range(0, 100000): genome = selection.select(species) sum = sum + genome.score
def iterate(self): """ Create the next generation. """ # for i in range(self.size): # for j in range(self.length): # print(self.members[i].genes[j], end=', ') # print('') # print('') newPop = [] t = datetime.now() # Calculate each members fitness fitness = [] for i in range(self.size): fitness.append(self.members[i].fitness(self.ref)) # Rank members by fitness ranking = zip(fitness, self.members) ranking = sorted(ranking, key=lambda x: x[0]) self.fitnessRanking, self.genomeRanking = zip(*ranking) self.bestGenome = self.genomeRanking[0] # Calculate the best fitness as percentage sum = self.fitnessRanking[0] total = self.ref.width * self.ref.height * 3 * 255 * 255 # error is squared self.fitnessPercentage = 100 - (100.0 * sum / total) print('fitness: %0.2f ms' % (1000 * (datetime.now() - t).total_seconds())) t = datetime.now() # Pick (population / 2) pairs to produce 2 offspring each for i in range(int(self.size / 2)): # Pick two (different) members of the population as parents p0 = self._pickMate(self.genomeRanking) p1 = p0 while p1 == p0: p1 = self._pickMate(self.genomeRanking) # Crossover if uniform(0, 1) < self.CROSSOVER_RATE: c0, c1 = Genome.cross(p0, p1) else: c0 = p0 c1 = p1 newPop.extend([c0, c1]) self.members = newPop print('crossover: %0.2f ms' % (1000 * (datetime.now() - t).total_seconds())) t = datetime.now() for i in range(self.size): self.members[i].mutate(self.MUTATION_RATE) print('mutation: %0.2f ms' % (1000 * (datetime.now() - t).total_seconds())) self.generation += 1
# Find the AIFH core files aifh_dir = os.path.dirname(os.path.abspath(__file__)) aifh_dir = os.path.abspath(aifh_dir + os.sep + ".." + os.sep + "lib" + os.sep + "aifh") sys.path.append(aifh_dir) from genetic import * from genetic import Genome from genetic import Species population = Population() species = Species(population) # Construct a simple population for i in range(0, 999): genome = Genome() genome.score = i species.members.append(genome) # Perform the test for round counts between 1 and 10. for round_count in range(1, 11): selection = TournamentSelection() selection.rounds = round_count sum = 0 count = 0 for i in range(0, 100000): genome = selection.select(species) sum = sum + genome.score count = count + 1
def bit_flip_mutation(genome: Genome): for i in range(len(genome.genes)): if np.random.uniform(low=0, high=1) < Const.MUTATION_PROBABILITY: genome.genes[i] = -1 * genome.genes[i] return genome