class Population: def __init__(self, size=10, life_time=60, origin=None, target=None, prev_child=None): if origin is None: origin = [300, 500] if target is None: target = [300, 100] self.origin = origin self.prev_child = prev_child self.mutation_rate = 0.05 self.average_fitness = 0 self.highest_average_fitness = 1 self.fitness_graph = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] self.size = size self.life_time = life_time self.target = Vector(target[0], target[1]) self.best_child = Rocket(self.life_time) self.members = [] for member in range(0, self.size): self.members.append( Rocket(self.life_time, origin=self.origin, prev_genes=self.prev_child)) # start the main loop def next_gen(self): # define aux variables for genetic algorithm mating_pool = [] new_generation = [] for member in self.members: # calculate the fitness for every member from the population fitness = (member.fitness(self.target)) * 1000 self.average_fitness += fitness # save the member with the best fitness if self.best_child.fitness(self.target) * 1000 < fitness: self.best_child = member # create the mating pool using every member's fitness # the recombination will use roulette method which means every member # is added to the mating pool multiple times depending on its fitness value for i in range(0, int(fitness)): mating_pool.append(member) self.average_fitness /= len(self.members) self.fitness_graph.insert(0, self.average_fitness) self.fitness_graph.pop() if self.average_fitness > self.highest_average_fitness: self.highest_average_fitness = self.average_fitness if len(mating_pool) > 0: for i in range(0, self.size): # the recombination is done selecting to random members from the mating pool first = np.random.random_integers(0, len(mating_pool) - 1) second = np.random.random_integers(0, len(mating_pool) - 1) child = mating_pool[first].crossover(mating_pool[second]) # the child will suffer a mutation according to the probability of the mutation rate child.mutate(self.mutation_rate) # the newer generation will represent the population for the next iteration new_generation.append(child) else: new_generation = [] for member in range(0, self.size): new_generation.append( Rocket(self.life_time, origin=self.origin, prev_genes=self.prev_child)) self.members = new_generation
class Genetic: def __init__(self, title, width, height, iteratons , loc_x, loc_y, population_size=100, mutation_rate=0.1, obstacles=[]): # initialize all variables self.title = title self.width = width self.height = height self.iteratons = iteratons self.target_location = Vector(loc_x, loc_y) self.population_size = population_size self.mutation_rate = mutation_rate self.population = [] self.best_child = Rocket(FPS) self.obstacles = obstacles for i in range(0, self.population_size): self.population.append(Rocket(FPS)) def _next_gen(self): fitness_list = [] new_generation = [] for member in self.population: fitness = (member.fitness(self.target_location)) * 1000 fitness_list.append((fitness,member)) new_list = sorted(fitness_list, key=lambda rkt: rkt[0]) child1,child2 = new_list[len(new_list)-1][1].crossover(new_list[len(new_list)-2][1]) child1.mutate(self.mutation_rate) child2.mutate(self.mutation_rate) for member in self.population: if ((member.fitness(self.target_location)) * 1000) == new_list[0][0] : new_generation.append(child1) elif ((member.fitness(self.target_location)) * 1000) == new_list[1][0] : new_generation.append(child2) else : temp = Rocket(FPS) temp.forces = member.forces new_generation.append(temp) self.population = [] self.population = new_generation self.best_child = new_list[len(new_list)-1][1] def simulate_with_graphics(self): pygame.init() game_display = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption(self.title) clock = pygame.time.Clock() game_exit = False counter = 0 iter_cnt = 0 while not game_exit and iter_cnt < self.iteratons: for event in pygame.event.get(): if event.type == pygame.QUIT: game_exit = True game_display.fill(WHITE) if counter == FPS: counter = 0 iter_cnt += 1 self._next_gen() for member in self.population: if member.is_alive: member.apply_force_at(counter) member.update() for obs in self.obstacles: if obs[0] <= member.location.x <= obs[0]+obs[2] and obs[1] <= member.location.y <= obs[1]+obs[3]: member.is_alive = False if member.location.x <= 10 or member.location.x >= 800 or member.location.y <= 10 or member.location.y >= 600 : member.is_alive = False pygame.draw.circle(game_display, green, member.location.tuple_int(),10 ) counter += 1 pygame.draw.circle(game_display, RED, self.target_location.tuple_int(), 25) font = pygame.font.SysFont("monospace", 20) label = font.render("Target", 1, (0, 0, 0)) game_display.blit(label, (67, 125)) for obs in self.obstacles: pygame.draw.rect(game_display, blue, obs) label = font.render("Generation: " + str(iter_cnt+1), 1, (0, 0, 0)) game_display.blit(label, (10, 512)) label = font.render("Best Fitness: " + str(self.best_child.fitness(self.target_location)), 1, (0, 0, 0)) game_display.blit(label, (10, 540)) label = font.render("Distance: " + str(self.best_child.location.dist(self.target_location)), 1, (0, 0, 0)) game_display.blit(label, (10, 570)) pygame.display.update() clock.tick(FPS) self.print_stats() def print_stats(self): print("--------------------------------") print("Best member from the population:") print("Fitness value: ", self.best_child.fitness(self.target_location)) print("Final location: ", self.best_child.location) print("Distance from the target: ", self.best_child.location.dist(self.target_location)) print("Forces:") for f in self.best_child.forces: print(f) print("--------------------------------")
class Genetic: def __init__(self, loc_x, loc_y, population_size=50, mutation_rate=0.1, obstacles=[]): # initialize all variables self.target_location = Vector(loc_x, loc_y) self.population_size = population_size self.mutation_rate = mutation_rate self.population = [] self.best_child = Rocket(FPS) self.obstacles = [] # initialize the rockets at random values for i in range(0, self.population_size): self.population.append(Rocket(FPS)) # create obstacle objects for obs in obstacles: self.obstacles.append(Obstacle(obs[0], obs[1], obs[2], obs[3])) # implementation of the genetic algorithm def _next_gen(self): # define aux variables for genetic algirthm mating_pool = [] new_generation = [] for member in self.population: # calculate the fitness for every member from the population fitness = (member.fitness(self.target_location)) * 1000 # save the member with the best fitness if self.best_child.fitness(self.target_location) * 1000 < fitness: self.best_child = member # create the mating pool using every member's fitness # the recombination will use roulette method which means every member # is added to the mating pool multiple times depending on its fitness value for i in range(0, int(fitness)): mating_pool.append(member) for i in range(0, self.population_size): # the recombination is done selecting to random members from the mating pool first = np.random.random_integers(0, len(mating_pool) - 1) second = np.random.random_integers(0, len(mating_pool) - 1) child = mating_pool[first].crossover(mating_pool[second]) # the child will suffer a mutation according to the probability of the mutation rate child.mutate(self.mutation_rate) # the newer generation will represent the population for the next iteration new_generation.append(child) self.population = new_generation # this method computes the routes of the rockets without using visual simulation def simulate(self, iterations): for i in range(0, iterations): # apply all forces for every member for member in self.population: for force in member.forces: # do not update the rockets position if it did collide with an obstacle if member.is_alive: # apply force to the rocket member.apply_force(force) # update rocket's position member.update() # check member's collision with the obstacles for obs in self.obstacles: if obs.do_collide(member): member.is_alive = False # compute the newer generation self._next_gen() # this method computes the routes of the rockets using visual simulation def simulate_with_graphics(self, title="Rockets", width=800, height=600, iteratons=100): # calculate an offset point to be able to draw negative positions reference_point = Vector(width / 4, height / 4) # initialize pygame pygame.init() game_display = pygame.display.set_mode((width, height)) pygame.display.set_caption(title) # get the clock module for handling FPS clock = pygame.time.Clock() # set an exit flag game_exit = False # set a counter for handling genetic algorithm steps at given moments counter = 0 # iteration counter iter_cnt = 0 # start the main loop while not game_exit and iter_cnt < iteratons: # handle input events for event in pygame.event.get(): if event.type == pygame.QUIT: game_exit = True # clear the playground game_display.fill(BLACK) if counter == FPS: # reset the counter to 0 counter = 0 # increment iter iter_cnt += 1 # compute the newer generation of the population self._next_gen() for member in self.population: # check if rocket did not collide before if member.is_alive: # calculate the new position for every rocket member.apply_force_at(counter) # update the rocket's position member.update() # check member's collision with the obstacles for obs in self.obstacles: if obs.do_collide(member): member.is_alive = False # display the rockets pygame.draw.circle(game_display, WHITE, member.location.tuple_int(reference_point.x), 1) counter += 1 # display the target position pygame.draw.circle(game_display, RED, self.target_location.tuple_int(reference_point.x), 3) # draw the obstacles for obs in self.obstacles: rect = obs.tuple_int(reference_point.x) pygame.draw.rect(game_display, WHITE, (rect[0], (rect[1][0] - rect[0][0], rect[1][1] - rect[0][1]))) # display iteration number to the screen font = pygame.font.SysFont("monospace", 15) label = font.render("iteration: " + str(iter_cnt), 1, (255, 255, 0)) game_display.blit(label, (width - 150, 10)) # update the display pygame.display.update() # sleep the mainloop for achieving the preset FPS value clock.tick(FPS) # print statistics for the best child when the main loop is finished self.print_stats() # display stats for the best child def print_stats(self): print("--------------------------------") print("Best member from the population:") print("Fitness value: ", self.best_child.fitness(self.target_location)) print("Final location: ", self.best_child.location) print("Distance from the target: ", self.best_child.location.dist(self.target_location)) print("Forces:") for f in self.best_child.forces: print(f) print("--------------------------------")