Exemplo n.º 1
0
def edge_disjoint_shortest_pair(g, src, dst):
    '''Return list of two edge-disjoint paths w/shortest total cost.

    @param g: NetworkX Graph object
    @param src: src node label
    @param dst: dst node label
    @param paths: two-element list of path lists, arbitrary ordering
    '''
    # 1. Use BFS to get shortest path.
    shortest_path = BFS(g, src, dst)

    # 2. Replace each edge of the shortest path (equivalent to two oppositely
    # directed arcs) by a single arc directed toward the source vertex.
    # 3. Make the length of each of the above arcs negative.
    g2 = flip_and_negate_path(g, shortest_path)

    # 4. Run the modified Dijkstra or the BFS algorithm again and from the
    # source vertex to the destination vertex in the above modified graph.
    shortest_path_2 = BFS(g2, src, dst)
    first_pathtotal = pathlen(g, shortest_path) + pathlen(g2, shortest_path_2)

    # 5. Transform to the original graph, and erase any interlacing edges of
    # the two paths found.  Group the remaining edges to obtain the shortest
    # pair of edge-disjoint paths.
    path1, path2 = grouped_shortest_pair(g, shortest_path, shortest_path_2)

    path1len = pathlen(g, path1)
    path2len = pathlen(g, path2)
    second_pathtotal = path1len + path2len
    assert (first_pathtotal == second_pathtotal)

    return [path1, path2]
Exemplo n.º 2
0
def edge_disjoint_shortest_pair(g, src, dst):
    '''Return list of two edge-disjoint paths w/shortest total cost.

    @param g: NetworkX Graph object
    @param src: src node label
    @param dst: dst node label
    @param paths: two-element list of path lists, arbitrary ordering
    '''
    # 1. Use BFS to get shortest path.
    shortest_path = BFS(g, src, dst)

    # 2. Replace each edge of the shortest path (equivalent to two oppositely
    # directed arcs) by a single arc directed toward the source vertex.
    # 3. Make the length of each of the above arcs negative.
    g2 = flip_and_negate_path(g, shortest_path)

    # 4. Run the modified Dijkstra or the BFS algorithm again and from the
    # source vertex to the destination vertex in the above modified graph.
    shortest_path_2 = BFS(g2, src, dst)
    first_pathtotal = pathlen(g, shortest_path) + pathlen(g2, shortest_path_2)

    # 5. Transform to the original graph, and erase any interlacing edges of
    # the two paths found.  Group the remaining edges to obtain the shortest
    # pair of edge-disjoint paths.
    path1, path2 = grouped_shortest_pair(g, shortest_path, shortest_path_2)
    path1len = pathlen(g, path1)
    path2len = pathlen(g, path2)
    second_pathtotal = path1len + path2len
    assert(first_pathtotal == second_pathtotal)
    return [path1, path2]
Exemplo n.º 3
0
    def test_example_3_13_a_mod_2(self):
        '''Example 3.13a on pg 65, mod on pg 78.

        This example has two equally good path choices, so only check sum of
        paths.
        '''
        g = graph_fig_3_13_a_mod_2
        ed_paths = edge_disjoint_shortest_pair(g, 'A', 'Z')
        ed_paths_len = sum([pathlen(g, ed_paths[i]) for i in [0, 1]])
        exp_paths = [[i for i in 'ABCDEFZ'], [i for i in 'AGDHZ']]
        exp_paths_len = sum([pathlen(g, exp_paths[i]) for i in [0, 1]])
        self.assertEqual(ed_paths_len, exp_paths_len)
Exemplo n.º 4
0
    def test_example_3_13_a_mod_2(self):
        '''Example 3.13a on pg 65, mod on pg 78.

        This example has two equally good path choices, so only check sum of
        paths.
        '''
        g = graph_fig_3_13_a_mod_2
        ed_paths = edge_disjoint_shortest_pair(g, 'A', 'Z')
        ed_paths_len = sum([pathlen(g, ed_paths[i]) for i in [0, 1]])
        exp_paths = [[i for i in 'ABCDEFZ'], [i for i in 'AGDHZ']]
        exp_paths_len = sum([pathlen(g, exp_paths[i]) for i in [0, 1]])
        self.assertEqual(ed_paths_len, exp_paths_len)
Exemplo n.º 5
0
    def test_example_3_13_a_mod_2(self):
        '''Example 3.13a on pg 65, mod 2 on pg 78.

        This example has two equally good path choices (ABIFZ / AGDHZ and
        ABCDEFZ / AGDHZ), so only check sum of paths.
        '''
        g = graph_fig_3_13_a_mod_2
        vd_paths = vertex_disjoint_shortest_pair(g, 'A', 'Z')
        vd_paths_len = sum([pathlen(g, vd_paths[i]) for i in [0, 1]])
        exp_paths = [[i for i in 'ABIFZ'], [i for i in 'AGDHZ']]
        exp_paths_len = sum([pathlen(g, exp_paths[i]) for i in [0, 1]])
        compare_path_lists(self, vd_paths, exp_paths, g, 14)
        self.assertEqual(vd_paths_len, exp_paths_len)
Exemplo n.º 6
0
    def test_example_3_13_a_mod_2(self):
        '''Example 3.13a on pg 65, mod 2 on pg 78.

        This example has two equally good path choices (ABIFZ / AGDHZ and
        ABCDEFZ / AGDHZ), so only check sum of paths.
        '''
        g = graph_fig_3_13_a_mod_2
        vd_paths = vertex_disjoint_shortest_pair(g, 'A', 'Z')
        vd_paths_len = sum([pathlen(g, vd_paths[i]) for i in [0, 1]])
        exp_paths = [[i for i in 'ABIFZ'], [i for i in 'AGDHZ']]
        exp_paths_len = sum([pathlen(g, exp_paths[i]) for i in [0, 1]])
        compare_path_lists(self, vd_paths, exp_paths, g, 14)
        self.assertEqual(vd_paths_len, exp_paths_len)
Exemplo n.º 7
0
def compare_path_lists(test, one, two, g = None, total = None):
    '''Compare two path lists.

    Useful because shortest path algorithms yield paths in arbitrary orders.
    @param test: instance of unittest.TestCase
    @param one: list of path nodes
    @param two: list of path nodes
    @param g: optional NetworkX graph for path length verification
    @param total: optional total length of both paths
    '''
    def make_tuple_set(path_list):
        return set([tuple(path) for path in path_list])

    test.assertEqual(make_tuple_set(one), make_tuple_set(two))
    if g:
        test.assertEqual(total, pathlen(g, one[0]) + pathlen(g, one[1]))
Exemplo n.º 8
0
def compare_path_lists(test, one, two, g=None, total=None):
    '''Compare two path lists.

    Useful because shortest path algorithms yield paths in arbitrary orders.
    @param test: instance of unittest.TestCase
    @param one: list of path nodes
    @param two: list of path nodes
    @param g: optional NetworkX graph for path length verification
    @param total: optional total length of both paths
    '''
    def make_tuple_set(path_list):
        return set([tuple(path) for path in path_list])

    test.assertEqual(make_tuple_set(one), make_tuple_set(two))
    if g:
        test.assertEqual(total, pathlen(g, one[0]) + pathlen(g, one[1]))
Exemplo n.º 9
0
 def test_example_3_16_a(self):
     '''Example 3.16a on pg 74.'''
     g = graph_fig_3_16_a
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ABCDEFZ'])
     self.assertEqual(pathlen(g, path), 6)
Exemplo n.º 10
0
 def test_example_3_1_a(self):
     '''Example 3.1a on pg. 41.'''
     g = graph_fig_3_1_a
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ABCDZ'])
     self.assertEqual(pathlen(g, path), 4)
Exemplo n.º 11
0
 def test_example_2_6(self):
     '''Example 2.6 on pg. 35.'''
     g = graph_fig_2_3
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ADECBZ'])
     self.assertEqual(pathlen(g, path), 12)
Exemplo n.º 12
0
 def test_example_3_16_a(self):
     '''Example 3.16a on pg 74.'''
     g = graph_fig_3_16_a
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ABCDEFZ'])
     self.assertEqual(pathlen(g, path), 6)
Exemplo n.º 13
0
 def test_example_3_1_a(self):
     '''Example 3.1a on pg. 41.'''
     g = graph_fig_3_1_a
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ABCDZ'])
     self.assertEqual(pathlen(g, path), 4)
Exemplo n.º 14
0
 def test_example_2_6(self):
     '''Example 2.6 on pg. 35.'''
     g = graph_fig_2_3
     path = BFS(g, 'A', 'Z')
     self.assertEqual(path, [i for i in 'ADECBZ'])
     self.assertEqual(pathlen(g, path), 12)