Ejemplo n.º 1
0
    def test_undirected_graph_dijkstra(self):
        """ Perform Dijkstra's algorithm on an undirected graph """

        """ 1_   E              1_   E
           | /                 | /
           A- 1 -B- 5 -D       A- 3 -B- 5 -D
             \   |               \   |
              2  0                2  -2
               \ |                 \ |
                 C                   C
        """
        g = UndirectedGraph()
        g.add_vertex(v_val='A')
        g.add_vertex(v_val='B')
        g.add_vertex(v_val='C')
        g.add_vertex(v_val='D')
        g.add_vertex(v_val='E')
        g.add_edge(('A', 'A'), attrs={'weight': 1})
        g.add_edge(('A', 'B'), attrs={'weight': 1})
        g.add_edge(('A', 'C'), attrs={'weight': 2})
        g.add_edge(('B', 'C'), attrs={'weight': 0})
        g.add_edge(('B', 'D'), attrs={'weight': 5})
        negative_weight_g = g.clone()
        negative_weight_g.get_edge(('A', 'B')).set('weight', 3)
        negative_weight_g.get_edge(('B', 'C')).set('weight', -2)
        missing_weight_g = g.clone()
        missing_weight_g.get_edge(('A', 'B')).set('weight', None)

        self.assertEqual(g.dijkstra('A', goal_val='A'), ['A'])
        self.assertEqual(g.dijkstra('A', goal_val='B'), ['A', 'B'])
        self.assertEqual(g.dijkstra('A', goal_val='C'), ['A', 'B', 'C'])
        self.assertEqual(g.dijkstra('A', goal_val='D'), ['A', 'B', 'D'])
        self.assertIsNone(g.dijkstra('A', goal_val='E'))
        # when returning all paths (no goal specified), paths aren't evaluated
        # until requested, to avoid the O(|V|^2) cost of backtracking |V| paths
        A_paths = g.dijkstra('A')
        # request each key
        _ = [A_paths[v.val] for v in g]
        self.assertEqual(dict(A_paths), {'A': ['A'],
                                         'B': ['A', 'B'],
                                         'C': ['A', 'B', 'C'],
                                         'D': ['A', 'B', 'D'],
                                         'E': None})
        self.assertEqual(g.dijkstra('A', goal_val='A', return_distances=True),
                         0)
        self.assertEqual(g.dijkstra('A', goal_val='B', return_distances=True),
                         1)
        self.assertEqual(g.dijkstra('A', goal_val='C', return_distances=True),
                         1)
        self.assertEqual(g.dijkstra('A', goal_val='D', return_distances=True),
                         6)
        self.assertEqual(g.dijkstra('A', goal_val='E', return_distances=True),
                         float('inf'))
        self.assertEqual(g.dijkstra('A', return_distances=True),
                         {'A': 0, 'B': 1, 'C': 1, 'D': 6, 'E': float('inf')})

        with self.assertRaises(ValueError):
            negative_weight_g.dijkstra('A')
        with self.assertRaises(ValueError):
            missing_weight_g.dijkstra('A')