def after_work(graph: Graph, end: str, edges: Dict, parents: Dict, distance: np.array): if distance[int(end) - 1] < np.inf: p = __get_path(parents, end) graph.path = p graph.edge_path = __get_edges(p, edges, graph.oriented) for v in graph.path: graph.vertexes_coordinates[v].color = QColor(68, 133, 255) else: graph.path = [] graph.edge_path = {} return distance[int(end) - 1]
def A_star(graph: Graph, begin: str, end: str) -> Union[None, int]: def get_min(d: dict): key = min(d.items(), key=lambda el: el[1] + __cost(graph, el[0], end))[0] d.pop(key) return key size = graph.size() if size <= 0 or begin not in graph.vertexes or end not in graph.vertexes: return None clear_color(graph) opened, closed, parents, edges, queue = {}, {}, {}, {}, {} opened[begin] = True distance = np.repeat([np.inf], size) distance[int(begin) - 1] = 0 parents[begin] = None queue[begin] = 0 while queue: current_vertex = get_min(queue) graph.vertexes_coordinates[current_vertex].color = viewed_color if current_vertex == end: p = __get_path(parents, end) graph.path = p graph.edge_path = __get_edges(p, edges, graph.oriented) return after_work(graph, end, edges, parents, distance) for v_to in graph.vertexes[current_vertex]: new_cost = distance[int(current_vertex) - 1] + graph.vertexes[current_vertex][v_to][0][0] if v_to in closed and new_cost >= distance[int(v_to) - 1]: continue if v_to not in queue or new_cost < distance[int(v_to) - 1]: parents[v_to] = current_vertex distance[int(v_to) - 1] = distance[int(current_vertex) - 1] + graph.vertexes[current_vertex][v_to][0][0] edges[f'{current_vertex}_{v_to}'] = graph.vertexes[current_vertex][v_to][0][1] if v_to not in queue: queue[v_to] = distance[int(v_to) - 1] closed[current_vertex] = True return after_work(graph, end, edges, parents, distance)
def IDA_star(graph: Graph, begin: str, end: str) -> Union[None, int]: def successors(g, d: Dict[str, List[Tuple[int, Any]]], b: int) -> List[Tuple[str, int]]: names = list(d.keys()) return sorted(list([ (name, g + int(__cost(graph, name, end))) for name in names # if g + int(__cost(graph, name, end)) < b ]), key=lambda el: el[1]) def IDA_search(p: List, g: int, b: int, finish: str) -> int: node = p[-1] graph.vertexes_coordinates[node].color = viewed_color f = g + int(__cost(graph, node, finish)) if f > 1.25 * bound: return f if node == finish: return Flags.FOUND less = np.inf found = False for v_to, _ in successors(g, graph.vertexes[node], b): if v_to not in p and v_to not in visited: p.append(v_to) t = IDA_search(p, g + graph.vertexes[node][v_to][0][0], b, finish) if t == Flags.FOUND: return Flags.FOUND if t < less: less = t visited.add(v_to) p.pop() return Flags.FOUND if found else less size = graph.size() if size <= 0 or begin not in graph.vertexes or end not in graph.vertexes: return None clear_color(graph) bound = int(__cost(graph, begin, end)) path = [begin] visited = {begin} status = None while status is None: try: t = IDA_search(path, 0, bound, end) except Exception as e: print(e) if t == Flags.FOUND: status = Flags.FOUND if t == np.inf: status = Flags.NOT_FOUND bound = t if status == Flags.NOT_FOUND: return None else: graph.path = path for v in graph.path: graph.vertexes_coordinates[v].color = QColor(68, 133, 255) graph.edge_path = __find_edge(graph, path) return __get_distance(graph, path)