Exemple #1
0
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]
Exemple #2
0
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)
Exemple #3
0
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)