예제 #1
0
    def test_bad_dijkstra_sp(self):
        from ch07.single_source_sp import dijkstra_sp

        DG = nx.DiGraph()
        DG.add_edge('a', 'b', weight=3)
        DG.add_edge('a', 'c', weight=1)
        DG.add_edge('c', 'd', weight=1)
        DG.add_edge('b', 'd', weight=-2)
        with self.assertRaises(ValueError):
            dijkstra_sp(DG, 'a')
예제 #2
0
def generate_bfs_and_dijkstra_figure(src, target):
    """Generate BFS solution overlaying Massachusetts highway."""
    if plt_error:
        return None
    import matplotlib.pyplot as plt

    (G, positions, _) = tmg_load(highway_map())
    (dist_to, edge_to) = dijkstra_sp(G, src)
    print('Dijkstra shortest distance is {} total steps with distance={:.1f}'.
          format(
              len(edges_path_to(edge_to, src, target)) - 1, dist_to[target]))
    path = edges_path_to(edge_to, src, target)
    plt.clf()
    plot_gps(positions)
    plot_highways(positions, G.edges())
    plot_path(positions, path)
    node_from = bfs_search(G, src)
    total = compute_distance(positions, node_from, src, target)

    plot_node_from(positions, src, target, node_from, color='purple')
    print(
        '{0} total steps for Breadth First Search with distance={1:.1f} miles'.
        format(len(path_to(node_from, src, target)) - 1, total))
    plt.axis('off')
    output_file = image_file('figure-mass-highway-bfs.svg')
    plt.savefig(output_file, format="svg")
    print(output_file)
    plt.clf()
    return output_file
예제 #3
0
def chained_dijkstra():
    """Generate Chained Dijkstra results with MA highway data."""
    from ch07.tmg_load import tmg_load, highway_map
    from ch07.dependencies import plt_error
    from ch07.single_source_sp import dijkstra_sp

    if not plt_error:
        (G, positions, _) = tmg_load(highway_map())

        start_time = time.time()
        longest_so_far = 0
        start = -1
        end = -1
        for i in range(G.number_of_nodes()):
            (dist_to, _) = dijkstra_sp(G, i)
            for j in range(i + 1, G.number_of_nodes()):
                if dist_to[j] > longest_so_far:
                    longest_so_far = dist_to[j]
                    start = i
                    end = j

        end_time = time.time()
        print(
            'start {} to end {} in longest shortest distance {} in time {:.3f} seconds'
            .format(positions[start], positions[end], longest_so_far,
                    end_time - start_time))
예제 #4
0
def avoid_interstate_90():
    """Find shortest path from westernmost-MA to easternmost-MA that avoids I-90."""
    if plt_error:
        return None
    import matplotlib.pyplot as plt
    from ch07.single_source_sp import dijkstra_sp, edges_path_to
    from ch07.tmg_load import tmg_load, plot_gps, plot_highways, bounding_ids
    from resources.highway import highway_map
    from ch07.plot_map import plot_path
    from algs.output import image_file
    (G,positions,labels) = tmg_load(highway_map())

    # Since graph is undirected, we will visit each edge twice. Make sure to
    # only remove when u < v to avoid deleting same edge twice
    edges_to_remove = []
    destination = None
    for u in G.nodes():
        if labels[u] == 'I-90@134&I-93@20&MA3@20(93)&US1@I-93(20)':       # SPECIAL LABEL in BOSTON
            destination = u
        for v in G.adj[u]:
            if 'I-90' in labels[u] and 'I-90' in labels[v] and u < v:
                edges_to_remove.append((u,v))

    (_,_,_,WEST) = bounding_ids(positions)
    (dist_to, edge_to) = dijkstra_sp(G, WEST)
    print('Original Dijkstra shortest distance is {} total steps with distance={:.1f}'.format(len(edges_path_to(edge_to, WEST, destination))-1, dist_to[destination]))

    print('num edges:', G.number_of_edges())
    for e in edges_to_remove:
        G.remove_edge(e[0], e[1])
    print('num edges:', G.number_of_edges())

    # create a new graph whose edges are not wholly on I-90
    (_,_,_,WEST) = bounding_ids(positions)
    (dist_to, edge_to) = dijkstra_sp(G, WEST)
    print('Dijkstra shortest distance avoiding I-90 is {} total steps with distance={:.1f}'.format(len(edges_path_to(edge_to, WEST, destination))-1, dist_to[destination]))
    path = edges_path_to(edge_to,WEST, destination)
    plt.clf()
    plot_gps(positions)
    plot_highways(positions, G.edges())
    plot_path(positions, path)

    output_file = image_file('figure-mass-no-I-90-dijkstra.svg')
    plt.savefig(output_file, format="svg")
    print(output_file)
    plt.clf()
    return output_file
예제 #5
0
 def test_dag_shortest(self):
     """Validate same answer from Dijkstra and Topological shortest path on sample mesh."""
     from ch07.challenge import mesh_graph, topological_sp
     from ch07.single_source_sp import dijkstra_sp
     N = 10
     DAG = mesh_graph(N)
     (dist_to, _) = dijkstra_sp(DAG, 1)
     (dist_to_topol, _) = topological_sp(DAG, 1)
     self.assertEqual(dist_to[N * N], dist_to_topol[N * N])
예제 #6
0
    def test_imqp_example(self):
        from ch07.single_source_sp import dijkstra_sp
        G = nx.DiGraph()
        G.add_edge('a', 'b', weight=6)
        G.add_edge('a', 'c', weight=10)
        G.add_edge('b', 'c', weight=2)

        (dist_to, edge_to) = dijkstra_sp(G, 'a')
        self.assertEqual(8, dist_to['c'])
        self.assertEqual('b', edge_to['c'][0])
        self.assertEqual('a', edge_to['b'][0])
예제 #7
0
    def test_dijkstra_replacement(self):
        from ch07.replacement import WEIGHT, DiGraph
        DG = DiGraph()
        DG.add_edge('a', 'b', weight=6)
        DG.add_edge('a', 'c', weight=10)
        DG.add_edge('b', 'c', weight=2)

        from ch07.single_source_sp import dijkstra_sp
        (dist_to, edge_to) = dijkstra_sp(DG, 'a')
        self.assertEqual(8, dist_to['c'])
        self.assert_equal_edges_weights(('b', 'c', {WEIGHT: 2}), edge_to['c'])
예제 #8
0
    def test_dijkstra_sp(self):
        from ch07.single_source_sp import dijkstra_sp, edges_path_to, bellman_ford

        DG = nx.DiGraph()
        DG.add_edge('a', 'b', weight=3)
        DG.add_edge('a', 'c', weight=9)
        DG.add_edge('b', 'c', weight=4)
        DG.add_edge('b', 'd', weight=2)
        DG.add_edge('d', 'c', weight=1)
        DG.add_edge('e', 'f', weight=1)  # separate and disconnected edge...
        (dist_to, edge_to) = dijkstra_sp(DG, 'a')
        path = edges_path_to(edge_to, 'a', 'c')
        self.assertEqual(6, dist_to['c'])
        self.assertEqual(['a', 'b', 'd', 'c'], path)

        with self.assertRaises(ValueError):  # NO PATH!
            edges_path_to(edge_to, 'a', 'f')

        (dist_to_bf, edge_to_bf) = bellman_ford(DG, 'a')
        path = edges_path_to(edge_to_bf, 'a', 'c')
        self.assertEqual(6, dist_to_bf['c'])
        self.assertEqual(['a', 'b', 'd', 'c'], path)
예제 #9
0
def single_source_shortest_path(graph, src):
    """
    Act on Single Source Shortest Path and return path as dictionary, where
    each node is expanded to have its
    """
    from ch07.single_source_sp import dijkstra_sp
    (_, edge_to) = dijkstra_sp(graph, src)

    expanded = {}
    for n in graph.nodes():
        if n == src:
            expanded[src] = []
        else:
            path = []
            t = n
            while t != src:
                path.insert(0, t)
                t = edge_to[t][0]
            path.insert(0, src)
            expanded[n] = path

    return expanded
예제 #10
0
    return (G, positions, labels)


#######################################################################
if __name__ == '__main__':
    if not plt_error:
        import matplotlib.pyplot as plt

        (G, positions, _) = tmg_load(highway_map())
        print(G.number_of_nodes(), G.number_of_edges())
        print(bounding_ids(positions))

        src = 389
        target = 2256

        paths = nx.single_source_shortest_path(G, src)
        path = paths[target]

        total = 0
        for i in range(len(path) - 1):
            total += G[path[i]][path[i + 1]][WEIGHT]
        print(total)
        print(G.edges(src, data=True))

        (dist_to, edge_to) = dijkstra_sp(G, src)
        print(dist_to[target])

        plot_gps(positions)
        plot_highways(positions, G.edges())
        plt.show()