def get_next_vertex(current_vertex: Vertex, edge_name: str, step_cost: Callable, env_config: EnvironmentConfiguration) -> Vertex: """ :param current_vertex: the current state :param edge_name: edge name from current vertex to the next vertex :param step_cost: function that receives parent_vertex, action, new_node and returns the step cost. :param env_config: environment configuration :return: The new vertex """ current_state = current_vertex.get_state() current_vertex_name = current_vertex.get_vertex_name() edges_dict = env_config.get_edges() vertexes_dict = env_config.get_vertexes() if edge_name not in edges_dict: current_vertex.set_state(current_state) print("No operation for this agent") current_vertex.set_cost( current_vertex.get_cost() + step_cost(current_vertex, Edge("", 0, ("", "")), current_vertex)) return current_vertex # No operation edge = edges_dict[edge_name] first_vertex, sec_vertex = edge.get_vertex_names() next_vertex_name = first_vertex if sec_vertex == current_vertex_name else sec_vertex next_vertex = vertexes_dict[next_vertex_name] next_state = State(next_vertex_name, copy.deepcopy(current_state.get_required_vertexes())) if next_vertex_name in current_state.get_required_vertexes(): next_state.set_visited_vertex(next_vertex_name) next_vertex.set_state(next_state) people_in_next_vertex = next_vertex.get_people_num() new_next_vertex = Vertex(people_in_next_vertex, next_state, next_vertex.get_edges(), current_vertex, edge.get_edge_name(), current_vertex.get_depth(), EnvironmentUtils.g(current_vertex, env_config) + step_cost(current_vertex, edge, next_vertex)) return new_next_vertex
def get_next_vertex(current_vertex: Vertex, edge_name: str, step_cost: Callable, env_config: EnvironmentConfiguration, is_max_player: bool = True) -> Vertex: """ :param current_vertex: the current state :param edge_name: edge name from current vertex to the next vertex :param step_cost: function that receives parent_vertex, action, new_node and returns the step cost. :param is_max_player: True if this is the max player, false otherwise :param env_config: environment configuration :return: The new vertex """ current_state = current_vertex.get_state() current_vertex_name = current_vertex.get_vertex_name() edges_dict = env_config.get_edges() vertexes_dict = env_config.get_vertexes() if edge_name not in edges_dict: current_vertex.set_state(current_state) print("edge_name= ", edge_name) print("No operation for this agent") current_vertex.set_cost(current_vertex.get_cost() + step_cost( current_vertex, Edge("", 0, ("", "")), current_vertex)) return current_vertex # No operation edge = edges_dict[edge_name] first_vertex, sec_vertex = edge.get_vertex_names() next_vertex_name = first_vertex if sec_vertex == current_vertex_name else sec_vertex next_vertex = vertexes_dict[next_vertex_name] scores_of_agents = current_state.get_scores_of_agents() if next_vertex_name in current_state.get_required_vertexes( ) and not current_state.get_required_vertexes()[next_vertex_name]: scores_of_agents = (scores_of_agents[0] + next_vertex.get_people_num(), scores_of_agents[1]) if is_max_player else ( scores_of_agents[0], scores_of_agents[1] + next_vertex.get_people_num()) next_state = State( next_vertex_name, scores_of_agents, copy.deepcopy(current_state.get_required_vertexes()), current_state.get_cost() + step_cost(current_vertex, edge, next_vertex)) if next_vertex_name in current_state.get_required_vertexes(): next_state.set_visited_vertex(next_vertex_name) next_vertex.set_state(next_state) people_in_next_vertex = next_vertex.get_people_num() next_state.set_parent_state(current_state) new_next_vertex = Vertex( people_in_next_vertex, next_state, next_vertex.get_edges(), current_vertex, edge.get_edge_name(), current_vertex.get_depth(), EnvironmentUtils.g(current_vertex, env_config) + step_cost(current_vertex, edge, next_vertex)) return new_next_vertex
def step_cost(self, parent_node: Vertex, action: Edge, new_node: Vertex) -> int: g_value = action.get_weight( ) # weights until g was calculated within get_next_vertex h_value = self.__heuristic_func.calc_estimation_from_goal( new_node.get_state(), None) return g_value + h_value
def __should_expand(self, closed_list, current_node: Vertex): current_state = current_node.get_state() current_cost = current_node.get_cost() is_exist = False # check if this node is exist in the closed list for element in closed_list: state, cost = element if current_state.get_required_vertexes( ) == state.get_required_vertexes() and current_state == state: is_exist = True if not is_exist: return True # this node doesnt exist in the closed list. # check if this cost lower than the current cost in the closed list. for element in closed_list: state, cost = element if current_state == state: if current_cost < cost: return True return False
def create_vertex(input_line: str) -> Optional[Tuple[str, Vertex]]: parts = input_line.split(ConfigurationReader.SPACE_SEPARATOR) parts_length = len(parts) peoples_in_vertex = 0 if parts_length > 2 or parts_length == 0: print( f'input line: {input_line} is invalid. Correct format: #V4 P2 or #V4' ) return None if parts_length == 2: peoples_in_vertex = int(parts[1].replace("P", "")) name = parts[0].replace("#V", "") return name, Vertex(peoples_in_vertex, State(name, (0, 0)), [])
def __successor_func( self, node: Vertex, env_conf: EnvironmentConfiguration) -> List[Tuple[str, Vertex]]: current_state = node.get_state() edges_list = EnvironmentUtils.get_possible_moves( current_state, env_conf) self._expansions_num += 1 names_of_edges = [edge.get_edge_name() for edge in edges_list] edge_to_next_state_list = [] for edge_name in names_of_edges: next_vertex = EnvironmentUtils.get_next_vertex( node, edge_name, self.step_cost, env_conf) env_conf.get_vertexes()[ next_vertex.get_vertex_name()] = next_vertex edge_to_next_state_list.append((edge_name, next_vertex)) return edge_to_next_state_list
def __print_vertex(vertex: Vertex): print( EnvironmentUtils._VERTEX_PREFIX + vertex.get_vertex_name() + EnvironmentUtils._SPACE_SEPARATOR + EnvironmentUtils._PERSONS_NUM_PREFIX + str(vertex.get_people_num()))
def step_cost(self, parent_node: Vertex, action: Edge, new_node: Vertex) -> int: return self.__heuristic_func.calc_estimation_from_goal( new_node.get_state(), None)