コード例 #1
0
ファイル: astar_search.py プロジェクト: cas4ey/graph_test
def astar_search(begin, end, graph):

    global _infinite_weight

    start = graph.node(begin)
    if start is None:
        return Path()

    finish = graph.node(end)
    if finish is None or finish.id() == start.id():
        return Path()

    nodes = {}
    for node_id in graph.nodes():
        node = graph.node(node_id)
        cost = 0 if node_id == begin else _infinite_weight
        nodes[node_id] = _AstarNode(node, cost, None, None)

    visited_nodes = []
    priority_queue = sortedList([nodes[start.id()]], key=lambda x: x.cost, load=len(nodes))
    iterations = 0

    while priority_queue:

        iterations += 1

        current = priority_queue.pop(0)
        visited_nodes.append(current.id)
        edges = current.node.edges()

        for edge_id in edges:

            edge = graph.edge(edge_id)
            if edge is None:
                continue

            edge_info = edges[edge_id]
            if edge_info.tail() in visited_nodes:
                continue

            tail = nodes.get(edge_info.tail(), None)
            if tail is None:
                continue

            if tail.heuristics_cost is None:
                tail.heuristics_cost = astar_heuristics(tail.node, finish)

            cost = current.cost + edge.weight() + tail.node.weight() + tail.heuristics_cost
            if cost < tail.cost:
                tail.cost = cost
                tail.parent_id = current.id
                tail.parent = current.node
                tail.edge = edge
                priority_queue.discard(tail)
                priority_queue.add(tail)
            elif tail not in priority_queue:
                priority_queue.add(tail)

            if tail.id == end:
                del priority_queue[:]
                break

    path = []
    current = nodes[end]
    while current.parent_id != 0 and current.edge is not None:
        path.append((current.parent, current.node, current.edge))
        current = nodes[current.parent_id]

    if path and current.id == begin:
        path.reverse()
        return Path(path, iterations)

    return Path()
コード例 #2
0
ファイル: dijkstra_search.py プロジェクト: cas4ey/graph_test
def dijkstra_search(begin, end, graph):

    global _infinite_weight

    start = graph.node(begin)
    if start is None:
        return Path()

    finish = graph.node(end)
    if finish is None or finish.id() == start.id():
        return Path()

    nodes = {}
    for node_id in graph.nodes():
        node = graph.node(node_id)
        cost = 0 if node_id == begin else _infinite_weight
        nodes[node_id] = _DijkstraNode(node, cost, None, None)

    visited_nodes = []
    priority_queue = sortedList([nodes[start.id()]], key=lambda x: x.cost, load=len(nodes))
    iterations = 0

    # "resulting_cost" is used to reduce total number of visited nodes.
    # Explanation: when you have already found target node you can check if other search paths are shorter than
    # the found one, and if not then there is no need to explore such path further.
    resulting_cost = _infinite_weight

    while priority_queue:

        iterations += 1

        current = priority_queue.pop(0)
        visited_nodes.append(current.id)
        edges = current.node.edges()

        for edge_id in edges:

            edge = graph.edge(edge_id)
            if edge is None:
                continue

            edge_info = edges[edge_id]
            if edge_info.tail() in visited_nodes:
                continue

            tail = nodes.get(edge_info.tail(), None)
            if tail is None:
                continue

            cost = current.cost + edge.weight() + tail.node.weight()
            if tail.id == end:
                resulting_cost = min(cost, resulting_cost)

            if cost < tail.cost:
                tail.cost = cost
                tail.parent_id = current.id
                tail.parent = current.node
                tail.edge = edge
                priority_queue.discard(tail)
                if cost < resulting_cost:
                    priority_queue.add(tail)
            elif cost < resulting_cost and tail not in priority_queue:
                priority_queue.add(tail)

    path = []
    current = nodes[end]
    while current.parent_id != 0 and current.edge is not None:
        path.append((current.parent, current.node, current.edge))
        current = nodes[current.parent_id]

    if path and current.id == begin:
        path.reverse()
        return Path(path, iterations)

    return Path()