def test_two_by_two_graph(self):
        g = Graph()

        # The graph looks like this:
        # o - o
        #     |
        # o - o

        node_00 = "(0, 0)"
        node_01 = "(0, 1)"
        node_10 = "(1, 0)"
        node_11 = "(1, 1)"

        g.add_vertice(node_00)
        g.add_vertice(node_01)
        g.add_vertice(node_10)
        g.add_vertice(node_11)

        g.add_edge(node_00, node_01, 1)
        g.add_edge(node_10, node_11, 2)
        g.add_edge(node_01, node_11, 3)
        g.add_edge(node_00, node_11, 4)

        kruskal_edges = kruskal(g)

        self.assertEqual(3, len(kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_01, kruskal_edges))
        self.assertTrue(self.contains_edge(node_10, node_11, kruskal_edges))
        self.assertTrue(self.contains_edge(node_01, node_11, kruskal_edges))
Example #2
0
    def test_non_existent_node_neighbor(self):
        g = Graph()

        try:
            g.neighbors("lol")
            self.fail("Expected fail if no lol exists")
        except ValueError as e:
            self.assertEqual("Vertice not in graph", str(e))
Example #3
0
    def test_BFS_negative_depth(self):
        g = Graph()
        g.add_vertice("s")

        try:
            nodes_at_level(g, "s", -1)
            self.fail("Should not be able to use negative depth")
        except ValueError as e:
            self.assertEqual("Given invalid depth", str(e))
Example #4
0
    def test_shortest_path_not_dest_node(self):
        g = Graph()
        g.add_vertice("from")

        try:
            shortest_path(g, "from", "to")
            self.fail("Should not be able to find a path in non-existent node")
        except ValueError as e:
            self.assertEqual("Vertice not found in graph", str(e))
Example #5
0
    def test_simple_connection_BFS_depth(self):
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")
        g.add_vertice("three")

        g.add_edge("one", "two")
        g.add_edge("two", "three")
        self.assertEqual(["one"], nodes_at_level(g, "one", 0))
        self.assertEqual(["two"], nodes_at_level(g, "one", 1))
        self.assertEqual(["three"], nodes_at_level(g, "one", 2))
Example #6
0
    def test_BFS_invalid_root(self):
        g = Graph()

        try:
            nodes_at_level(g, "dog", 2)
            self.fail("Should not be able to use non-existent vertice")
        except ValueError as e:
            self.assertEqual("Root not found in graph", str(e))
Example #7
0
    def test_forked_BFS(self):
        g = Graph()

        v00 = "(0, 0)"
        v01 = "(0, 1)"
        v10 = "(1, 0)"
        v11 = "(1, 1)"

        g.add_vertice(v00)
        g.add_vertice(v01)
        g.add_vertice(v10)
        g.add_vertice(v11)

        g.add_edge(v00, v01)
        g.add_edge(v00, v10)

        g.add_edge(v10, v11)
        self.assertCountEqual([v00], nodes_at_level(g, v00, 0))
        self.assertCountEqual([v01, v10], nodes_at_level(g, v00, 1))
        self.assertCountEqual([v11], nodes_at_level(g, v00, 2))
Example #8
0
    def test_adding_edge_forces_connection(self):
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")

        self.assertFalse(g.contains_edge("one", "two"))
        g.add_edge("one", "two")
        self.assertTrue(g.contains_edge("two", "one"))
        self.assertTrue(g.contains_edge("one", "two"))

        vertices = g.vertices()
        vertice_one = self.find_vertice("one", vertices)
        vertice_two = self.find_vertice("two", vertices)

        self.assertTrue(vertice_one.is_neighbor(vertice_two))
        self.assertTrue(vertice_two.is_neighbor(vertice_one))
Example #9
0
    def test_add_self_reference_edge(self):
        g = Graph()
        g.add_vertice("single")

        try:
            g.add_edge("single", "single")
        except ValueError as e:
            self.assertEqual("Vertice cannot become it's own neighbor", str(e))

        self.assertFalse(g.contains_edge("single", "single"))
Example #10
0
    def test_shortest_path_forked_path(self):

        g = Graph()

        v00 = "(0, 0)"
        v01 = "(0, 1)"
        v10 = "(1, 0)"
        v11 = "(1, 1)"

        g.add_vertice(v00)
        g.add_vertice(v01)
        g.add_vertice(v10)
        g.add_vertice(v11)

        g.add_edge(v00, v01)
        g.add_edge(v00, v10)

        g.add_edge(v10, v11)

        self.assertCountEqual([v00, v10, v11], shortest_path(g, v00, v11))
        self.assertCountEqual([], shortest_path(g, v00, v00))
        self.assertCountEqual([v01, v00, v10, v11], shortest_path(g, v01, v11))
Example #11
0
    def test_shortest_path_one_path(self):
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")
        g.add_edge("one", "two")

        self.assertCountEqual(["one", "two"], shortest_path(g, "one", "two"))
Example #12
0
    def test_adding_existent_edge(self):
        g = Graph()

        g.add_vertice("one")

        try:
            g.add_vertice("one")
            self.fail("Should not be able to add another vertice")
        except ValueError as e:
            self.assertEqual("Vertice already in the graph", str(e))

        self.assertTrue(g.contains_vertice("one"))
Example #13
0
    def test_both_non_existent_edge(self):
        g = Graph()
        g.add_vertice("other")

        try:
            g.add_edge("nil", "nope")
            self.fail("Should not be able to add edge if both vertices exist")
        except ValueError as e:
            self.assertEqual("Vertice contained in edge not in graph", str(e))
Example #14
0
    def test_one_direction_vertical_connection(self):
        g = Graph()

        node_00 = "(0, 0)"
        node_10 = "(1, 0)"
        node_20 = "(2, 0)"

        g.add_vertice(node_00)
        g.add_vertice(node_10)
        g.add_vertice(node_20)

        g.add_edge(node_00, node_10, 1)
        g.add_edge(node_10, node_20, 2)

        kruskal_edges = kruskal(g)
        self.assertEqual(2, len(kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_10, kruskal_edges))
        self.assertTrue(self.contains_edge(node_10, node_20, kruskal_edges))
Example #15
0
    def test_one_direction_horizontal_connection(self):
        g = Graph()
        # The graph looks like this:
        # o - o - o

        node_00 = "(0, 0)"
        node_01 = "(0, 1)"
        node_02 = "(0, 2)"
        g.add_vertice(node_00)
        g.add_vertice(node_01)
        g.add_vertice(node_02)

        g.add_edge(node_00, node_01, 1)
        g.add_edge(node_01, node_02, 2)

        kruskal_edges = kruskal(g)
        self.assertEqual(2, len(kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_01, kruskal_edges))
        self.assertTrue(self.contains_edge(node_01, node_02, kruskal_edges))
Example #16
0
    def test_removing_edges_with_no_added_edge(self):
        """Expected behavior is to interact with the graph by using
        edges. By mutating the vertices and add neighbors manually,
        the edges will not be correctly connected"""
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")

        vertices = g.vertices()
        vertice_one = self.find_vertice("one", vertices)
        vertice_two = self.find_vertice("two", vertices)

        vertice_one.add_neighbor(vertice_two)
        self.assertTrue(vertice_one.is_neighbor(vertice_two))
        self.assertFalse(vertice_two.is_neighbor(vertice_one))

        g.remove_edge("one", "two")
        # There was initially no edge and thus nothing was changed
        self.assertTrue(vertice_one.is_neighbor(vertice_two))
        self.assertFalse(vertice_two.is_neighbor(vertice_one))
Example #17
0
    def test_three_by_three_graph(self):
        g = Graph()

        # The graph looks like this:
        # o - o - o
        #     |
        # o - o - o
        # |
        # o - o - o

        node_00 = "(0, 0)"
        node_01 = "(0, 1)"
        node_02 = "(0, 2)"
        node_10 = "(1, 0)"
        node_11 = "(1, 1)"
        node_12 = "(1, 2)"
        node_20 = "(2, 0)"
        node_21 = "(2, 1)"
        node_22 = "(2, 2)"

        g.add_vertice(node_00)
        g.add_vertice(node_01)
        g.add_vertice(node_02)
        g.add_vertice(node_10)
        g.add_vertice(node_11)
        g.add_vertice(node_12)
        g.add_vertice(node_20)
        g.add_vertice(node_21)
        g.add_vertice(node_22)

        g.add_edge(node_00, node_01, 0)
        g.add_edge(node_01, node_02, 1)
        g.add_edge(node_00, node_10, 10)
        g.add_edge(node_01, node_11, 2)
        g.add_edge(node_02, node_12, 11)
        g.add_edge(node_10, node_11, 3)
        g.add_edge(node_11, node_12, 4)
        g.add_edge(node_10, node_20, 5)
        g.add_edge(node_11, node_21, 12)
        g.add_edge(node_12, node_22, 13)
        g.add_edge(node_20, node_21, 6)
        g.add_edge(node_21, node_22, 7)

        kruskal_edges = kruskal(g)
        self.assertEqual(8, len(kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_01, kruskal_edges))
        self.assertTrue(self.contains_edge(node_01, node_02, kruskal_edges))
        self.assertTrue(self.contains_edge(node_01, node_11, kruskal_edges))
        self.assertTrue(self.contains_edge(node_10, node_11, kruskal_edges))
        self.assertTrue(self.contains_edge(node_11, node_12, kruskal_edges))
        self.assertTrue(self.contains_edge(node_10, node_20, kruskal_edges))
        self.assertTrue(self.contains_edge(node_20, node_21, kruskal_edges))
        self.assertTrue(self.contains_edge(node_21, node_22, kruskal_edges))
Example #18
0
    def test_adding_vertice_basic_add(self):
        g = Graph()

        self.assertFalse(g.contains_vertice("one"))
        g.add_vertice("one")
        self.assertTrue(g.contains_vertice("one"))
Example #19
0
    def test_shortest_path_empty_case(self):
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")
        self.assertEqual([], shortest_path(g, "one", "two"))
Example #20
0
    def test_simple_case_BFS_depth(self):
        g = Graph()

        g.add_vertice("one")
        self.assertEqual(["one"], nodes_at_level(g, "one", 0))
Example #21
0
    def test_no_neighbors(self):
        g = Graph()

        g.add_vertice("hi")

        self.assertEqual([], g.neighbors("hi"))
Example #22
0
    def test_two_by_three_graph(self):
        g = Graph()

        # The graph should look like this:
        # o - o - o
        # |       |
        # o - o   o

        node_00 = "(0, 0)"
        node_01 = "(0, 1)"
        node_02 = "(0, 2)"
        node_10 = "(1, 0)"
        node_11 = "(1, 1)"
        node_12 = "(1, 2)"

        g.add_vertice(node_00)
        g.add_vertice(node_01)
        g.add_vertice(node_02)
        g.add_vertice(node_10)
        g.add_vertice(node_11)
        g.add_vertice(node_12)

        g.add_edge(node_00, node_01, 0)
        g.add_edge(node_01, node_02, 1)
        g.add_edge(node_10, node_11, 2)
        g.add_edge(node_11, node_12, 9)
        g.add_edge(node_00, node_10, 3)
        g.add_edge(node_01, node_11, 10)
        g.add_edge(node_02, node_12, 4)

        kruskal_edges = kruskal(g)
        self.assertEqual(5, len(kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_01, kruskal_edges))
        self.assertTrue(self.contains_edge(node_01, node_02, kruskal_edges))
        self.assertTrue(self.contains_edge(node_00, node_10, kruskal_edges))
        self.assertTrue(self.contains_edge(node_02, node_12, kruskal_edges))
        self.assertTrue(self.contains_edge(node_10, node_11, kruskal_edges))
Example #23
0
    def __construct_maze(self, width, height, length):
        """Given a length on which to construct the length of the solution to
        the maze, constructs a maze with hints towards the size of the maze.
        By the constraints of our maze, the bare minimum dimensions of this
        maze must necessarily be (width + height) >= length - 1 to find a
        path such that a path of the appropriate length can be found.

        Args:
            width(int): the width of the maze.
            height(int): the height of the maze.
            length(int): the length of the maze.
        Returns:
            Graph: a resulting graph
            """
        weight_lower_bound = 0
        weight_upper_bound = 10000

        graph = Graph()

        def add_vertices():
            for row in range(height):
                for col in range(width):
                    graph.add_vertice(cell_format.format(row, col))

        def add_edges():
            # the edges are added in sequence of each row connected first,
            # then all rows are joined.

            # e. g. o - o - o

            # then o o o
            #      | | |
            #      o o o
            for row in range(height):
                for col in range(width - 1):
                    graph.add_edge(
                        cell_format.format(row, col),
                        cell_format.format(row, col + 1),
                        random.randint(weight_lower_bound, weight_upper_bound))

            for row in range(height - 1):
                for col in range(width):
                    graph.add_edge(
                        cell_format.format(row, col),
                        cell_format.format(row + 1, col),
                        random.randint(weight_lower_bound, weight_upper_bound))

        def remove_non_mst_edges():
            kruskal_edges = set(kruskal(graph))
            for edge in graph.edges():
                if edge not in kruskal_edges:
                    graph.remove_edge(edge.from_vertice().name(),
                                      edge.to_vertice().name())

        def set_starting_position():
            # arbitrarily picks the first starting point
            # length - 1 because 0 denotes the starting position
            potential_starting_points = nodes_at_level(
                graph, cell_format.format(self.__end_pos[0],
                                          self.__end_pos[1]), length - 1)

            # always works given that the width/height invariant is satisfied
            initial_starting_point_str = potential_starting_points[0]

            # Since the string is of the form (x, y)
            self.__starting_pos = tuple(
                [int(x) for x in initial_starting_point_str[1:-1].split(',')])

        add_vertices()
        add_edges()
        remove_non_mst_edges()
        set_starting_position()
        return graph
Example #24
0
 def test_remove_edges_with_no_existing_vertices(self):
     g = Graph()
     g.remove_edge("dog", "fad")
Example #25
0
    def test_complex_graph_shortest_path(self):

        g = Graph()

        v00 = "(0, 0)"
        v01 = "(0, 1)"
        v02 = "(0, 2)"
        v10 = "(1, 0)"
        v11 = "(1, 1)"
        v12 = "(1, 2)"
        v20 = "(2, 0)"
        v21 = "(2, 1)"
        v22 = "(2, 2)"

        g.add_vertice(v00)
        g.add_vertice(v01)
        g.add_vertice(v02)
        g.add_vertice(v10)
        g.add_vertice(v11)
        g.add_vertice(v12)
        g.add_vertice(v20)
        g.add_vertice(v21)
        g.add_vertice(v22)

        # o - o - o
        #     |
        # o   o   o
        # |   |   |
        # o - o - o

        g.add_edge(v00, v01)
        g.add_edge(v01, v02)
        g.add_edge(v01, v11)
        g.add_edge(v10, v20)
        g.add_edge(v11, v21)
        g.add_edge(v12, v22)
        g.add_edge(v20, v21)
        g.add_edge(v21, v22)

        self.assertCountEqual([v00, v01, v11, v21, v22, v12],
                              shortest_path(g, v00, v12))
        self.assertCountEqual([v00, v01, v02],
                              shortest_path(g, v00, v02))
        self.assertCountEqual([v10, v20, v21, v11, v01, v00],
                              shortest_path(g, v10, v00))
        self.assertCountEqual([v21, v11, v01, v02],
                              shortest_path(g, v21, v02))
        self.assertCountEqual([v12, v22, v21, v20, v10],
                              shortest_path(g, v12, v10))
Example #26
0
    def test_multiple_neighbors(self):
        g = Graph()

        g.add_vertice("one")
        g.add_vertice("two")
        g.add_vertice("three")
        g.add_vertice("four")

        g.add_edge("one", "two")
        g.add_edge("one", "three")

        g.add_edge("two", "three")
        g.add_edge("two", "four")

        self.assertCountEqual(["two", "three"], g.neighbors("one"))
        self.assertCountEqual(["one", "three", "four"], g.neighbors("two"))
        self.assertCountEqual(["one", "two"], g.neighbors("three"))
        self.assertCountEqual(["two"], g.neighbors("four"))
Example #27
0
    def test_complex_graph_BFS(self):

        g = Graph()

        v00 = "(0, 0)"
        v01 = "(0, 1)"
        v02 = "(0, 2)"
        v10 = "(1, 0)"
        v11 = "(1, 1)"
        v12 = "(1, 2)"
        v20 = "(2, 0)"
        v21 = "(2, 1)"
        v22 = "(2, 2)"

        g.add_vertice(v00)
        g.add_vertice(v01)
        g.add_vertice(v02)
        g.add_vertice(v10)
        g.add_vertice(v11)
        g.add_vertice(v12)
        g.add_vertice(v20)
        g.add_vertice(v21)
        g.add_vertice(v22)

        # o - o - o
        #     |
        # o   o   o`
        # |   |   |
        # o - o - o

        g.add_edge(v00, v01)
        g.add_edge(v01, v02)
        g.add_edge(v01, v11)
        g.add_edge(v10, v20)
        g.add_edge(v11, v21)
        g.add_edge(v12, v22)
        g.add_edge(v20, v21)
        g.add_edge(v21, v22)

        self.assertCountEqual([v00], nodes_at_level(g, v00, 0))
        self.assertCountEqual([v01], nodes_at_level(g, v00, 1))
        self.assertCountEqual([v02, v11], nodes_at_level(g, v00, 2))
        self.assertCountEqual([v21], nodes_at_level(g, v00, 3))
        self.assertCountEqual([v20, v22], nodes_at_level(g, v00, 4))
        self.assertCountEqual([v10, v12], nodes_at_level(g, v00, 5))

        self.assertCountEqual([v21], nodes_at_level(g, v21, 0))
        self.assertCountEqual([v20, v22, v11], nodes_at_level(g, v21, 1))
        self.assertCountEqual([v10, v12, v01], nodes_at_level(g, v21, 2))
        self.assertCountEqual([v00, v02], nodes_at_level(g, v21, 3))