def breed(parent_a, parent_b): """Performs sub-tree crossover on parent_a and parent_b returning the child tree.""" def crossover_recursive(receiver_index, donator_index): if receiver_index < len( child_pacman_cont.state_evaluator ) and donator_index < len(parent_pacman_cont.state_evaluator): return child_pacman_cont.state_evaluator[ receiver_index] = tree.TreeNode( receiver_index, parent_pacman_cont. state_evaluator[donator_index].value) crossover_recursive( child_pacman_cont.state_evaluator.get_left_child_index( receiver_index), parent_pacman_cont.state_evaluator.get_left_child_index( donator_index)) crossover_recursive( child_pacman_cont.state_evaluator.get_right_child_index( receiver_index), parent_pacman_cont.state_evaluator.get_right_child_index( donator_index)) # Choose a random node (crossover point) from each state evaluator node list crossover_node_a = parent_a.pacman_cont.state_evaluator[ random.choices([ n for n in parent_a.pacman_cont.state_evaluator if n.value ])[0].index] crossover_node_b = parent_b.pacman_cont.state_evaluator[ random.choices([ n for n in parent_b.pacman_cont.state_evaluator if n.value ])[0].index] child_pacman_cont = copy.copy(parent_a.pacman_cont) parent_pacman_cont = parent_b.pacman_cont # Extend the child's state evaluator if necessary if len(child_pacman_cont.state_evaluator) < len( parent_a.pacman_cont.state_evaluator): child_pacman_cont.state_evaluator = child_pacman_cont.state_evaluator + [ tree.TreeNode(index, None) for index in range( len(child_pacman_cont.state_evaluator), len(parent_a.pacman_cont.state_evaluator)) ] # Perform sub-tree crossover crossover_recursive(crossover_node_a.index, crossover_node_b.index) # Finish generating the child world = gpac_world_class.GPacWorld(self.config) game_state = game_state_class.GameState( world.pacman_coords, world.ghost_coords, world.pill_coords, self.get_num_adj_walls(world, world.pacman_coords[0])) pacman_cont = child_pacman_cont ghosts_cont = parent_a.ghosts_cont game_state.update_walls(world.wall_coords) child = gpac_world_individual_class.GPacWorldIndividual( world, game_state, pacman_cont, ghosts_cont) return child
def crossover_recursive(receiver_index, donator_index): # BONUS2 if receiver_index < len(child_pacman_conts[cont_index].state_evaluator) and donator_index < len(parent_pacman_cont.state_evaluator): return child_pacman_conts[cont_index].state_evaluator[receiver_index] = tree.TreeNode(receiver_index, parent_pacman_cont.state_evaluator[donator_index].value) crossover_recursive(child_pacman_conts[cont_index].state_evaluator.get_left_child_index(receiver_index), parent_pacman_cont.state_evaluator.get_left_child_index(donator_index)) crossover_recursive(child_pacman_conts[cont_index].state_evaluator.get_right_child_index(receiver_index), parent_pacman_cont.state_evaluator.get_right_child_index(donator_index))
def __copy__(self): """Performs a deep copy of this object, except for the state evaluator.""" other = type(self)(self.config) super(base_controller_class.BaseController, other).__init__() other.config = self.config other.max_fp_constant = float(self.config.settings['max fp constant']) other.state_evaluator = tree_class.Tree(self.config) other.state_evaluator.list[:] = [tree_class.TreeNode(node.index, node.value) if node else None for node in self.state_evaluator] return other
def breed(parent_a, parent_b, unit_id): """Performs sub-tree crossover on parent_a and parent_b returning the child tree.""" def crossover_recursive(receiver_index, donator_index): # BONUS1, BONUS2 if receiver_index < len(child_conts[cont_index].state_evaluator ) and donator_index < len( parent_cont.state_evaluator): return child_conts[cont_index].state_evaluator[ receiver_index] = tree.TreeNode( receiver_index, parent_cont.state_evaluator[donator_index].value) crossover_recursive( child_conts[cont_index].state_evaluator. get_left_child_index(receiver_index), parent_cont.state_evaluator.get_left_child_index( donator_index)) crossover_recursive( child_conts[cont_index].state_evaluator. get_right_child_index(receiver_index), parent_cont.state_evaluator.get_right_child_index( donator_index)) # BONUS1, BONUS2 if unit_id == self.PACMAN_ID: if self.config.settings.getboolean( 'use single pacman controller'): num_conts = 1 else: num_conts = self.num_pacmen else: # Default to self.GHOST_ID if self.config.settings.getboolean( 'use single ghost controller'): num_conts = 1 else: num_conts = self.num_ghosts child_conts = [None] * num_conts for cont_index in range(num_conts): # Choose a random node (crossover point) from each state evaluator node list crossover_node_a = parent_a.conts[cont_index].state_evaluator[ random.choice([ n for n in parent_a.conts[cont_index].state_evaluator if n.value ]).index] crossover_node_b = parent_b.conts[cont_index].state_evaluator[ random.choice([ n for n in parent_b.conts[cont_index].state_evaluator if n.value ]).index] child_conts[cont_index] = copy.copy(parent_a.conts[cont_index]) parent_cont = parent_b.conts[cont_index] # Extend the child's state evaluator if necessary if len(child_conts[cont_index].state_evaluator) < len( parent_a.conts[cont_index].state_evaluator): child_conts[cont_index].state_evaluator = child_conts[ cont_index].state_evaluator + [ tree.TreeNode(index, None) for index in range( len(child_conts[cont_index].state_evaluator), len(parent_a.conts[cont_index].state_evaluator) ) ] # Perform sub-tree crossover crossover_recursive(crossover_node_a.index, crossover_node_b.index) # Finish generating the child child = cont_class.ControllerIndividual(child_conts) return child