def test_best_chromosomes_sorts_them_in_descending_order(): chromosomes = [ Chromosome(np.array(list("ABCXXXXXXXXXXXXXXXXXXXXXXX"))), Chromosome(np.array(list("ABXXXXXXXXXXXXXXXXXXXXXXXX"))), Chromosome(np.array(list(string.ascii_uppercase))), ] subject = Population(chromosomes) expected = [chromosomes[2], chromosomes[0], chromosomes[1]] assert subject.best_chromosomes() == expected
def main(): m = readMatrix('matrix_games/5x5.txt') numR, numC = m.shape Population.initPopulation = initPopulation Population.evolve = evolve p = Population(30, 2) p.initPopulation(numC, numR) p.evolve(m)
def test_parents_probabilities_returns_values_proportional_to_their_fitness(): chromosomes = [ Chromosome(np.array(list("ABCXXXXXXXXXXXXXXXXXXXXXXX"))), Chromosome(np.array(list("ABXXXXXXXXXXXXXXXXXXXXXXXX"))), Chromosome(np.array(list(string.ascii_uppercase))), ] subject = Population(chromosomes) result = subject.parents_probabilities() expected = [0.12121212, 0.09090909, 0.78787879] np.testing.assert_allclose(result, expected)
def test_random_parents_returns_two_random_chromosomes(): chromosomes = [ Chromosome(np.array(list("A" * 26))), Chromosome(np.array(list("B" * 26))), Chromosome(np.array(list("C" * 26))), ] subject = Population(chromosomes) random_parents = subject.random_parents() assert len(random_parents) == 2 assert random_parents[0] == chromosomes[0] assert random_parents[1] == chromosomes[0]
def test_init_assigns_chromosomes(): chromosomes = [ Chromosome(np.array(list("A" * 26))), Chromosome(np.array(list("B" * 26))), ] subject = Population(chromosomes) assert subject.chromosomes == chromosomes
def evolve_previous_generation(self): number_of_candidates_to_maintain = round(self.SIZE * self.etilism_percentage) next_generation = self.etilist_candidates() for _ in range(self.n_crossovers): parents = self.previous_generation.random_parents() offspring = Crossover(parents)() for chromosome in offspring: next_generation.append(chromosome.mutated()) return Population(next_generation)
def main(): pygame.init() window = pygame.display.set_mode((d_width, d_height)) circles = getCircles() for circle in circles: pygame.draw.circle(window, (255, 255, 255), circle[0], circle[1], 1) Population.initPopulation = initPopulation Population.evolve = evolve p = Population(80, 3) p.initPopulation() p.evolve(window, circles) #pygame.display.flip() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0)
def testNeuralNetWithGA(): net = NeuralNet(2, 2, 1) t_model = utils.readTrainModel(os.path.join(utils.getResourcesPath(), 'logic_gates/NAND.txt')) Population.initPopulation = initPopulation Population.evolve = evolve p = Population(70, 9) p.initPopulation() p.evolve(net, t_model) print(net.getOutputs([0, 0])) print(net.getOutputs([0, 1])) print(net.getOutputs([1, 0])) print(net.getOutputs([1, 1])) print(net.getError(t_model)) #testPerceptron() #testNeuralNet() #testNeuralNetWithGA() #numberRecognition()
def main(): global fitnessHistory Population.initPopulation = initPopulation Population.evolve = evolve p = Population(30, 1) #fig = plt.figure() for i in range(1): colors = ['b', 'r', 'g'] p.initPopulation() p.evolve() #ax = fig.add_subplot(111) #ax.plot(np.arange(len(fitnessHistory)), fitnessHistory, c=colors[i]) fitnessHistory = [] h = np.array(history) h = np.rot90(h, 1) print(h) plt.imshow(h, cmap='Greys', aspect='auto', interpolation='nearest') plt.show()
def setup_population(): dm = DataManager.shared() from genetic_algorithm.population import Population from neural_network.neural_network import NeuralNetwork population = Population.instantiate(NeuralNetwork.instantiate) population.calculate_fitness(dm.get_X_train(), dm.get_y_train()) population.get_chromosomes().sort(key=lambda ann: ann.get_fitness(), reverse=True) print_population(population, 0) return population
def __init__(self, screen): self.screen = screen # LOAD POPULATION self.group = [] self.load() self.population = Population(self.group) self.game = Game(self.group, self.screen) self.cfg = GA_SETTINGS self._mutation_bins = np.cumsum([ self.cfg['probability_gaussian'], self.cfg['probability_random_uniform'] ]) self._crossover_bins = np.cumsum( [self.cfg['probability_SBX'], self.cfg['probability_SPBX']]) self._SPBX_type = self.cfg['SPBX_type'].lower() self._SBX_eta = self.cfg['SBX_eta'] self._mutation_rate = self.cfg['mutation_rate'] self._next_gen_size = self.cfg['num_offspring'] self.current_generation = 0
def main(): pygame.init() maze = readMaze('mazes/9x15.txt') numR, numC = maze.shape window = pygame.display.set_mode((numC * square_l, numR * square_l)) renderMaze(window, maze) Population.initPopulation = initPopulation Population.evolve = evolve p = Population(50, 30) p.mutation_rate = 0.1 p.elites_num = 5 p.initPopulation() p.evolve(window, maze) print("done") while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0)
def __init__(self, world, replay=False): super().__init__() self.world = world self.title = 'Genetic Algorithm - Cars' self.top = 150 self.left = 150 self.width = 1100 self.height = 700 self.max_fitness = 0.0 self.cars = [] self.population = Population([]) self.state = States.FIRST_GEN self._next_pop = [ ] # Used when you are in state 1, i.e. creating new cars from the old population self.current_batch = 1 self.batch_size = get_boxcar_constant('run_at_a_time') self.gen_without_improvement = 0 self.replay = replay self.manual_control = False self.current_generation = 0 self.leader = None # What car is leading self.num_cars_alive = get_boxcar_constant('run_at_a_time') self.batch_size = self.num_cars_alive self._total_individuals_ran = 0 self._offset_into_population = 0 # Used if we display only a certain number at a # Determine whether or not we are in the process of creating random cars. # This is used for when we only run so many at a time. For instance if `run_at_a_time` is 20 and # `num_parents` is 1500, then we can't just create 1500 cars. Instead we create batches of 20 to # run at a time. This flag is for deciding when we are done with that so we can move on to crossover # and mutation. self._creating_random_cars = True # Determine how large the next generation is if get_ga_constant('selection_type').lower() == 'plus': self._next_gen_size = get_ga_constant( 'num_parents') + get_ga_constant('num_offspring') elif get_ga_constant('selection_type').lower() == 'comma': self._next_gen_size = get_ga_constant('num_parents') else: raise Exception('Selection type "{}" is invalid'.format( get_ga_constant('selection_type'))) if self.replay: global args self.floor = Floor(self.world) self.state = States.REPLAY self.num_replay_inds = len([ x for x in os.listdir(args.replay_from_folder) if x.startswith('car_') ]) else: self._set_first_gen() # self.population = Population(self.cars) # For now this is all I'm supporting, may change in the future. There really isn't a reason to use # uniform or single point here because all the values have different ranges, and if you clip them, it # can make those crossovers useless. Instead just use simulated binary crossover to ensure better crossover. self._crossover_bins = np.cumsum([get_ga_constant('probability_SBX')]) self._mutation_bins = np.cumsum([ get_ga_constant('probability_gaussian'), get_ga_constant('probability_random_uniform') ]) self.init_window() self.stats_window.pop_size.setText(str(get_ga_constant('num_parents'))) self._set_number_of_cars_alive() self.game_window.cars = self.cars self._timer = QTimer(self) self._timer.timeout.connect(self._update) self._timer.start(1000 // get_boxcar_constant('fps'))
def __init__(self, settings, show=False, fps=2000): super().__init__() self.printIndividualSnakeFitness = True self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QtGui.QColor(240, 240, 240)) self.setPalette(palette) self.settings = settings self._SBX_eta = self.settings['SBX_eta'] self._mutation_bins = np.cumsum([self.settings['probability_gaussian'], self.settings['probability_random_uniform'] ]) self._crossover_bins = np.cumsum([self.settings['probability_SBX'], self.settings['probability_SPBX'] ]) self._SPBX_type = self.settings['SPBX_type'].lower() self._mutation_rate = self.settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if self.settings['selection_type'].lower() == 'plus': self._next_gen_size = self.settings['num_parents'] + self.settings['num_offspring'] elif self.settings['selection_type'].lower() == 'comma': self._next_gen_size = self.settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format(self.settings['selection_type'])) self.board_size = settings['board_size'] #self.border = (0, 10, 0, 10) # Left, Top, Right, Bottom self.border = (0, self.board_size[0], 0, self.board_size[1]) # Left, Top, Right, Bottom self.snake_widget_width = SQUARE_SIZE[0] * self.board_size[0] self.snake_widget_height = SQUARE_SIZE[1] * self.board_size[1] # Allows padding of the other elements even if we need to restrict the size of the play area self._snake_widget_width = max(self.snake_widget_width, 620) self._snake_widget_height = max(self.snake_widget_height, 600) self.top = 150 self.left = 150 self.width = self._snake_widget_width + 700 + self.border[0] + self.border[2] self.height = self._snake_widget_height + self.border[1] + self.border[3] + 200 individuals: List[Individual] = [] #load the best snakes, if there are any self.pathToBestSnakes = 'best_snakes/' for f in os.scandir(self.pathToBestSnakes): if f.is_dir(): individuals.append(load_snake(self.pathToBestSnakes,f.name)) #load up new snakes, minus the best snakes for _ in range(self.settings['num_parents'] - len(individuals)): individual = Snake(self.board_size, hidden_layer_architecture=self.settings['hidden_network_architecture'], hidden_activation=self.settings['hidden_layer_activation'], output_activation=self.settings['output_layer_activation'], lifespan=self.settings['lifespan'], apple_and_self_vision=self.settings['apple_and_self_vision']) individuals.append(individual) #clear out any saved snakes try: shutil.rmtree('./snakes/') except OSError as e: print("Error: %s : %s" % ('./snakes/', e.strerror)) self.best_fitness = 0 self.best_score = 0 self._current_individual = 0 self.population = Population(individuals) self.snake = self.population.individuals[self._current_individual] self.current_generation = 0 self.init_window() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000//fps) if show: self.show()
def __init__(self, settings, show= (not NEW), fps=5000): super().__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QtGui.QColor(0, 0, 0)) self.setPalette(palette) self.settings = settings self._SBX_eta = self.settings['SBX_eta'] self._mutation_bins = np.cumsum([self.settings['probability_gaussian'], self.settings['probability_random_uniform'] ]) self._crossover_bins = np.cumsum([self.settings['probability_SBX'], self.settings['probability_SPBX'] ]) self._SPBX_type = self.settings['SPBX_type'].lower() self._mutation_rate = self.settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if self.settings['selection_type'].lower() == 'plus': self._next_gen_size = self.settings['num_parents'] + self.settings['num_offspring'] elif self.settings['selection_type'].lower() == 'comma': self._next_gen_size = self.settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format(self.settings['selection_type'])) self.board_size = settings['board_size'] self.border = (0, 10, 0, 10) # Left, Top, Right, Bottom self.puzzle_widget_width = SQUARE_SIZE[0] * self.board_size[0] self.puzzle_widget_height = SQUARE_SIZE[1] * self.board_size[1] # Allows padding of the other elements even if we need to restrict the size of the play area self._puzzle_widget_width = max(self.puzzle_widget_width, 620) self._puzzle_widget_height = max(self.puzzle_widget_height, 600) self.top = 150 self.left = 150 self.width = self._puzzle_widget_width + 700 + self.border[0] + self.border[2] self.height = self._puzzle_widget_height + self.border[1] + self.border[3] + 200 self.nrGroupRange = settings['nrGroupRange'] self.nrBlocksRange = (settings['nrBlocksRange'][0] * self.nrGroupRange[0], settings['nrBlocksRange'][1] * self.nrGroupRange[1]) individuals: List[Individual] = [] if NEW: for _ in range(self.settings['num_parents']): nrG = random.randint(self.nrGroupRange[0], self.nrGroupRange[1]) nrC = random.randint(self.nrBlocksRange[0], self.nrBlocksRange[1]) individual = Puzzle(self.board_size, nrG, nrC, hidden_layer_architecture=self.settings['hidden_network_architecture'], hidden_activation=self.settings['hidden_layer_activation'], output_activation=self.settings['output_layer_activation']) individuals.append(individual) else: for i in range(NR_OLD_ONES): individual = load_puzzle('population15', 'best_snake'+str(i+320), self.settings) individuals.append(individual) self.best_fitness = np.inf self._current_individual = 0 self.population = Population(individuals) self.puzzle = self.population.individuals[self._current_individual] self.current_generation = 0 self.init_window() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000./fps) if show: self.show()
def __init__(self, settings, show=True, fps=300): super().__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QtGui.QColor(240, 240, 240)) self.setPalette(palette) self.settings = settings self._SBX_eta = self.settings['SBX_eta'] self._mutation_bins = np.cumsum([self.settings['probability_gaussian'], self.settings['probability_random_uniform'] ]) self._crossover_bins = np.cumsum([self.settings['probability_SBX'], self.settings['probability_SPBX'] ]) self._SPBX_type = self.settings['SPBX_type'].lower() self._mutation_rate = self.settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if self.settings['selection_type'].lower() == 'plus': self._next_gen_size = self.settings['num_parents'] + self.settings['num_offspring'] elif self.settings['selection_type'].lower() == 'comma': self._next_gen_size = self.settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format(self.settings['selection_type'])) self.board_size = settings['board_size'] self.border = (0, 10, 0, 10) # Left, Top, Right, Bottom self.snake_widget_width = SQUARE_SIZE[0] * self.board_size[0] self.snake_widget_height = SQUARE_SIZE[1] * self.board_size[1] # Allows padding of the other elements even if we need to restrict the size of the play area self._snake_widget_width = max(self.snake_widget_width, 620) self._snake_widget_height = max(self.snake_widget_height, 600) self.top = 150 self.left = 150 self.width = self._snake_widget_width + 700 + self.border[0] + self.border[2] self.height = self._snake_widget_height + self.border[1] + self.border[3] + 200 individuals: List[Individual] = [] #Load the snake/s from a pre-existing save #You need to go to the load snake function and do it from there for now #individual = load_snake(r'C:\Population',r'C:\Population\40') #individuals.append(individual) for _ in range(self.settings['num_parents']): if (save_load = 1): individual = load_snake(save_folder_location,save_folder_individual) individuals.append(individual) elif(save_load = 0): individual = Snake(self.board_size, hidden_layer_architecture=self.settings['hidden_network_architecture'], hidden_activation=self.settings['hidden_layer_activation'], output_activation=self.settings['output_layer_activation'], lifespan=self.settings['lifespan'], apple_and_self_vision=self.settings['apple_and_self_vision']) individuals.append(individual) self.best_fitness = 0 self.best_score = 0 self._current_individual = 0 self.population = Population(individuals) self.snake = self.population.individuals[self._current_individual] self.current_generation = 406 print(self.current_generation) self.init_window() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000./fps) if show: self.show()
def __init__(self): self._mutation_bins = np.cumsum([ settings['probability_gaussian'], settings['probability_random_uniform'] ]) self._crossover_bins = np.cumsum( [settings['probability_SBX'], settings['probability_SPBX']]) self._SPBX_type = settings['SPBX_type'].lower() self._SBX_eta = settings['SBX_eta'] self._mutation_rate = settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if settings['selection_type'].lower() == 'plus': self._next_gen_size = settings['num_parents'] + settings[ 'num_offspring'] elif settings['selection_type'].lower() == 'comma': self._next_gen_size = settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format( settings['selection_type'])) self.Window_Width = settings['Window_Width'] self.Window_Height = settings['Window_Height'] #### Pygame init #### pygame.init() self.screen = pygame.display.set_mode( (self.Window_Width, self.Window_Height)) pygame.display.set_caption('Flappy Bird') self.game_font = pygame.font.Font("04B_19.ttf", 40) individuals: List[Individual] = [] # Create initial generation for _ in range(settings['num_parents']): individual = Bird( hidden_layer_architecture=settings[ 'hidden_network_architecture'], hidden_activation=settings['hidden_layer_activation'], output_activation=settings['output_layer_activation']) individuals.append(individual) self.population = Population(individuals) self.current_generation = 0 # Best of single generation self.winner = None self.winner_index = -1 # Best paddle of all generations self.champion = None self.champion_index = -1 self.champion_fitness = -1 * np.inf #### Pygame #### # The loop will carry on until the user exit the game (e.g. clicks the close button). game_active = True # The clock will be used to control how fast the screen updates clock = pygame.time.Clock() # load assets self.bg_surface = pygame.image.load( "assets/background-day.png").convert() self.bg_surface = pygame.transform.scale2x(self.bg_surface) self.floor_surface = pygame.image.load("assets/base.png").convert() self.floor_surface = pygame.transform.scale2x(self.floor_surface) self.floor_x = 0 self.pipe_surface = pygame.image.load("assets/pipe-green.png") self.pipe_surface = pygame.transform.scale2x(self.pipe_surface) self.pipe_flip_surface = pygame.transform.flip(self.pipe_surface, False, True) self.pipe_list = [] self.pipe_list.extend(self.create_pipe()) # self.SPAWNPIPE = pygame.USEREVENT # pygame.time.set_timer(self.SPAWNPIPE, 1200) # don't use this because sometimes the game lags and reuslts in pipes spawning closer than intended self.spawn_pipe_counter = 0 # scores self.score = 0 self.high_score = 0 while game_active and self.current_generation <= 100: for event in pygame.event.get(): if event.type == pygame.QUIT: game_active = False pygame.quit() # sys.exit() // this or exit() exit() # if event.type == self.SPAWNPIPE and game_active: # self.pipe_list.extend(self.create_pipe()) # screen.fill(BLACK) self.screen.blit(self.bg_surface, (0, 0)) # Pipes self.spawn_pipe_counter += 1 # if self.spawn_pipe_counter % 72 == 0: if self.spawn_pipe_counter % settings[ 'pipe_interval_in_frames'] == 0: self.pipe_list.extend(self.create_pipe()) self.pipe_list = self.move_pipes(self.pipe_list) self.draw_pipes(self.pipe_list) # Floor self.floor_x = (self.floor_x - 6) % -self.Window_Width self.draw_floor() # TODO: should change this for better visibility font = pygame.font.Font('freesansbold.ttf', 18) generation_text = font.render( "Generation: %d" % self.current_generation, True, WHITE) score_text = font.render("Score: %d" % self.score, True, WHITE) best_score_text = font.render("Best: %d" % self.high_score, True, WHITE) self.screen.blit(generation_text, (self.Window_Width - 150, 30)) self.screen.blit(score_text, (self.Window_Width - 150, 60)) self.screen.blit(best_score_text, (self.Window_Width - 150, 90)) self.still_alive = 0 # Loop through the paddles in the generation for i, bird in enumerate(self.population.individuals): # Update paddel if still alive if bird.is_alive: self.still_alive += 1 #----------------------------------------inputs for neural network-------------------------------------------- # next_pipe = next(pipe for pipe in self.pipe_list if pipe.right > settings['init_bird_x_pos']) # next_next_pipe = next(pipe for pipe in self.pipe_list if pipe.right > next_pipe.right) next_pipe, next_next_pipe = self.get_next_pipes() bird.x_distance_to_next_pipe_center = next_pipe.right - settings[ 'init_bird_x_pos'] bird.y_distance_to_next_pipe_center = (next_pipe.top - 150) - bird.y_pos if next_next_pipe != None: bird.x_distance_to_next_next_pipe_center = next_next_pipe.right - settings[ 'init_bird_x_pos'] bird.y_distance_to_next_next_pipe_center = ( next_next_pipe.top - 150) - bird.y_pos else: bird.x_distance_to_next_next_pipe_center = None bird.y_distance_to_next_next_pipe_center = None inputs = np.array( [[bird.y_speed], [bird.y_pos], [bird.x_distance_to_next_pipe_center], [bird.y_distance_to_next_pipe_center], [bird.y_distance_to_next_next_pipe_center]]) # inputs = np.array([[paddle.x_pos], [ball_distance_left_wall], [ball_distance_right_wall], [balls[i].xspeed], [paddle.xspeed], [balls[i].y], [balls[i].yspeed]]) # inputs = np.array([[paddle.x_pos], [balls[i].xspeed], [paddle.xspeed], [balls[i].x]]) #----------------------------------------inputs for neural network-------------------------------------------- bird.update(inputs) bird.move(self.pipe_list) self.score = max(self.score, bird.score) self.high_score = max(self.score, self.high_score) # Draw every paddle except the best ones if bird.is_alive and bird != self.winner and bird != self.champion: bird.winner = False bird.champion = False bird.draw(self.screen) # Draw the winning and champion paddle last if self.winner is not None and self.winner.is_alive: self.winner.draw(self.screen, winner=True) if self.champion is not None and self.champion.is_alive: self.champion.draw(self.screen, champion=True) # Generate new generation when all have died out if self.still_alive == 0: self.next_generation() # --- Go ahead and update the screen with what we've drawn. pygame.display.update() # --- Limit to 60 frames per second clock.tick(60) #Once we have exited the main program loop we can stop the game engine: pygame.quit()
def __init__(self, NEW, old_ones, from_nr): self.new = NEW self.NR_OLD_ONES = old_ones self.from_nr = from_nr self.settings = settings self._SBX_eta = self.settings['SBX_eta'] self._mutation_bins = np.cumsum([ self.settings['probability_gaussian'], self.settings['probability_random_uniform'] ]) self._crossover_bins = np.cumsum([ self.settings['probability_SBX'], self.settings['probability_SPBX'] ]) self._SPBX_type = self.settings['SPBX_type'].lower() self._mutation_rate = self.settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if self.settings['selection_type'].lower() == 'plus': self._next_gen_size = self.settings['num_parents'] + self.settings[ 'num_offspring'] elif self.settings['selection_type'].lower() == 'comma': self._next_gen_size = self.settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format( self.settings['selection_type'])) self.board_size = settings['board_size'] self.nrGroupRange = settings['nrGroupRange'] self.nrBlocksRange = (settings['nrBlocksRange']) individuals: List[Individual] = [] if self.new: for _ in range(self.settings['num_parents']): nrG = random.randint(self.nrGroupRange[0], self.nrGroupRange[1]) nrC = random.randint(self.nrBlocksRange[0], self.nrBlocksRange[1]) individual = Puzzle( self.board_size, nrG, nrC, hidden_layer_architecture=self. settings['hidden_network_architecture'], hidden_activation=self.settings['hidden_layer_activation'], output_activation=self.settings['output_layer_activation']) individuals.append(individual) else: for i in range(self.NR_OLD_ONES): individual = load_puzzle('population', 'best_snake' + str(i + self.from_nr), self.settings) individuals.append(individual) self.best_fitness = np.inf self._current_individual = 0 self.population = Population(individuals) self.puzzle = self.population.individuals[self._current_individual] self.current_generation = 0
def __init__(self, config: Optional[Config] = None): super().__init__() global args self.config = config self.top = 150 self.left = 150 self.width = 1100 self.height = 700 self.title = 'Super Mario Bros AI' self.current_generation = 0 # This is the generation that is actual 0. If you load individuals then you might end up starting at gen 12, in which case # gen 12 would be the true 0 self._true_zero_gen = 0 self._should_display = True self._timer = QTimer(self) self._timer.timeout.connect(self._update) # Keys correspond with B, NULL, SELECT, START, U, D, L, R, A # index 0 1 2 3 4 5 6 7 8 self.keys = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0], np.int8) # I only allow U, D, L, R, A, B and those are the indices in which the output will be generated # We need a mapping from the output to the keys above self.ouput_to_keys_map = { 0: 4, # U 1: 5, # D 2: 6, # L 3: 7, # R 4: 8, # A 5: 0 # B } # Initialize the starting population individuals: List[Individual] = [] # Load any individuals listed in the args.load_inds num_loaded = 0 if args.load_inds: # Overwrite the config file IF one is not specified if not self.config: try: self.config = Config( os.path.join(args.load_file, 'settings.config')) except: raise Exception( f'settings.config not found under {args.load_file}') set_of_inds = set(args.load_inds) for ind_name in os.listdir(args.load_file): if ind_name.startswith('best_ind_gen'): ind_number = int(ind_name[len('best_ind_gen'):]) if ind_number in set_of_inds: individual = load_mario(args.load_file, ind_name, self.config) # Set debug stuff if needed if args.debug: individual.name = f'm{num_loaded}_loaded' individual.debug = True individuals.append(individual) num_loaded += 1 # Set the generation self.current_generation = max( set_of_inds) + 1 # +1 becauase it's the next generation self._true_zero_gen = self.current_generation # Load any individuals listed in args.replay_inds if args.replay_inds: # Overwrite the config file IF one is not specified if not self.config: try: self.config = Config( os.path.join(args.replay_file, 'settings.config')) except: raise Exception( f'settings.config not found under {args.replay_file}') for ind_gen in args.replay_inds: ind_name = f'best_ind_gen{ind_gen}' fname = os.path.join(args.replay_file, ind_name) if os.path.exists(fname): individual = load_mario(args.replay_file, ind_name, self.config) # Set debug stuff if needed if args.debug: individual.name = f'm_gen{ind_gen}_replay' individual.debug = True individuals.append(individual) else: raise Exception( f'No individual named {ind_name} under {args.replay_file}' ) # If it's not a replay then we need to continue creating individuals else: num_parents = max(self.config.Selection.num_parents - num_loaded, 0) for _ in range(num_parents): individual = Mario(self.config) # Set debug stuff if needed if args.debug: individual.name = f'm{num_loaded}' individual.debug = True individuals.append(individual) num_loaded += 1 self.best_fitness = 0.0 self._current_individual = 0 self.population = Population(individuals) self.mario = self.population.individuals[self._current_individual] self.max_distance = 0 # Track farthest traveled in level self.max_fitness = 0.0 self.env = retro.make(game='SuperMarioBros-Nes', state=f'Level{self.config.Misc.level}') # Determine the size of the next generation based off selection type self._next_gen_size = None if self.config.Selection.selection_type == 'plus': self._next_gen_size = self.config.Selection.num_parents + self.config.Selection.num_offspring elif self.config.Selection.selection_type == 'comma': self._next_gen_size = self.config.Selection.num_offspring # If we aren't displaying we need to reset the environment to begin with if args.no_display: self.env.reset() else: self.init_window() # Set the generation in the label if needed if args.load_inds: txt = "<font color='red'>" + str( self.current_generation + 1) + '</font>' # +1 because we switch from 0 to 1 index self.info_window.generation.setText(txt) # if this is a replay then just set current_individual to be 'replay' and set generation if args.replay_file: self.info_window.current_individual.setText('Replay') txt = f"<font color='red'>{args.replay_inds[self._current_individual] + 1}</font>" self.info_window.generation.setText(txt) self.show() if args.no_display: self._timer.start(1000 // 1000) else: self._timer.start(1000 // 60)
def __init__(self, settings, show=True, fps=1000): # tốc độ rắn và đồ hoạ super().__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QtGui.QColor(240, 240, 240)) self.setPalette(palette) self.settings = settings self._SBX_eta = self.settings['SBX_eta'] self._mutation_bins = np.cumsum([ self.settings['probability_gaussian'], # tỉ lệ lai ghép self.settings['probability_random_uniform'] # đột biến ]) self._crossover_bins = np.cumsum([ self.settings['probability_SBX'], self.settings['probability_SPBX'] ]) self._SPBX_type = self.settings['SPBX_type'].lower() self._mutation_rate = self.settings['mutation_rate'] # Determine size of next gen based off selection type self._next_gen_size = None if self.settings['selection_type'].lower() == 'plus': #chế độ plus self._next_gen_size = self.settings['num_parents'] + self.settings[ 'num_offspring'] elif self.settings['selection_type'].lower() == 'comma': #chế độ comma self._next_gen_size = self.settings['num_offspring'] else: raise Exception('Selection type "{}" is invalid'.format( self.settings['selection_type'])) self.board_size = settings['board_size'] self.border = (0, 10, 0, 10) # Left, Top, Right, Bottom self.snake_widget_width = SQUARE_SIZE[0] * self.board_size[0] self.snake_widget_height = SQUARE_SIZE[1] * self.board_size[1] # Cho phép đệm các yếu tố khác ngay cả khi chúng ta hạn chế kích thước của khu vực chơi self._snake_widget_width = max(self.snake_widget_width, 620) self._snake_widget_height = max(self.snake_widget_height, 600) self.top = 150 self.left = 150 self.width = self._snake_widget_width + 700 + self.border[ 0] + self.border[2] self.height = self._snake_widget_height + self.border[1] + self.border[ 3] + 200 individuals: List[Individual] = [] for _ in range(self.settings['num_parents']): individual = Snake( self.board_size, hidden_layer_architecture=self. settings['hidden_network_architecture'], hidden_activation=self.settings['hidden_layer_activation'], output_activation=self.settings['output_layer_activation'], lifespan=self.settings['lifespan'], apple_and_self_vision=self.settings['apple_and_self_vision']) individuals.append(individual) self.best_fitness = 0 self.best_score = 0 self._current_individual = 0 self.population = Population(individuals) self.snake = self.population.individuals[self._current_individual] self.current_generation = 0 self.init_window() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000. / fps) if show: self.show()
def next_generation(self): self._increment_generation() # Calculate fitness of individuals for individual in self.population.individuals: individual.calculate_fitness() self.population.individuals = elitism_selection( self.population, self.cfg['num_parents']) random.shuffle(self.population.individuals) next_pop: List[Player] = [] while len(next_pop) < self._next_gen_size: p1, p2 = roulette_wheel_selection(self.population, 2) L = p1.brain.layer_nodes c1_params = {} c2_params = {} # Each W_l and b_l are treated as their own chromosome. # Because of this I need to perform crossover/mutation on each chromosome between parents for l in range(0, L, 2): p1_W_l = p1.brain.net[l].weight.data.numpy() p2_W_l = p2.brain.net[l].weight.data.numpy() p1_b_l = np.array([p1.brain.net[l].bias.data.numpy()]) p2_b_l = np.array([p2.brain.net[l].bias.data.numpy()]) # Crossover # @NOTE: I am choosing to perform the same type of crossover on the weights and the bias. c1_W_l, c2_W_l, c1_b_l, c2_b_l = self._crossover( p1_W_l, p2_W_l, p1_b_l, p2_b_l) # Mutation # @NOTE: I am choosing to perform the same type of mutation on the weights and the bias. self._mutation(c1_W_l, c2_W_l, c1_b_l, c2_b_l) # Assign children from crossover/mutation c1_params['W' + str(l)] = c1_W_l c2_params['W' + str(l)] = c2_W_l c1_params['b' + str(l)] = c1_b_l c2_params['b' + str(l)] = c2_b_l # Clip to [-1, 1] np.clip(c1_params['W' + str(l)], -1, 1, out=c1_params['W' + str(l)]) np.clip(c2_params['W' + str(l)], -1, 1, out=c2_params['W' + str(l)]) np.clip(c1_params['b' + str(l)], -1, 1, out=c1_params['b' + str(l)]) np.clip(c2_params['b' + str(l)], -1, 1, out=c2_params['b' + str(l)]) # Create children from chromosomes generated above brain = NN() boat = Boat() brain.transform_weights(c1_params) p1 = Player(brain, boat) brain = NN() boat = Boat() brain.transform_weights(c2_params) p2 = Player(brain, boat) # Add children to the next generation next_pop.extend([p1, p2]) # Set the next generation random.shuffle(next_pop) self.group = next_pop self.population = Population(self.group)
def first_generation(self): chromosomes = [] for _ in range(self.SIZE): chromosomes.append(Chromosome.random()) return Population(chromosomes)
def run_algorithm(): global FILE if len(sys.argv) > 1: FILE = sys.argv[1] board_configuration = Config(FILE) best_fitness = [] worst_fitness = [] avg_fitness = [] population = Population(board_configuration, POPULATION_SIZE) start = time.time() population.init_population() population.calculate_fitness() #population.print_population() for i in range(GENERATIONS): population.select_and_crossover() population.calculate_fitness() if i % 10 == 0: population.save_best(i) best, worst, avg = population.evaluate_population() print("====== GENERATION {i} =======".format(i=i)) print("Best fitness: {}".format(best)) best_fitness.append(best) worst_fitness.append(worst) avg_fitness.append(avg) #population.print_population() population.save_best(GENERATIONS) stop = time.time() print("\nTime: {}".format(stop - start)) print("Worst: {}".format(worst_fitness[-1])) print("Best: {}".format(min(best_fitness))) print("Avg: {}".format(avg_fitness[-1])) make_chart(best_fitness, worst_fitness, avg_fitness)