Exemplo n.º 1
0
class BasicGraphTest(unittest.TestCase):
    def setUp(self):
        """Call before every test case."""
        self.graph_a = Graph(name="myGraph")

        # Simple graph with three nodes
        self.node1 = Node(label='node1')
        self.node2 = Node(label='node2')
        self.node3 = Node(label='node3')

        self.graph_a.add_node(self.node1)
        self.graph_a.add_node(self.node2, neighbors={self.node1})
        self.graph_a.add_node(self.node3, neighbors={self.node1})

    def tearDown(self):
        """Call after every test case."""

    def test_init(self):
        """
        Tests that everything done in the setUp method works correctly.
        This test includes
        - Confirming that the internal graph of form {<node1>:{<neighbor1>,<neighbor2>},...} is updated
        - Confirming that the internal weights of form {(<node1>,<node2>):weight),...} is updated
        - Confirming node.neighbors is updated.
        - Confirming that node.neighbors and node.weights always reflect each other.
        """
        self.assertEqual(len(self.graph_a._graph), 3,
                         "Node seems to be missing from _graph")
        self.assertEqual(len(self.graph_a._weights), 2,
                         "Weight seems to be missing from _weights ")

        self.assertEqual(
            self.node2.get_neighbors(), {self.node1},
            "Neighbor doesn't seem to be added at the node level")
        self.assertEqual(
            self.node3.get_neighbors(), {self.node1},
            "Neighbor doesn't seem to be added at the node level")

        for node in self.graph_a._graph.keys():
            neighbors = node.get_neighbors()
            if neighbors:
                for neighbor in neighbors:
                    self.assertIn(
                        (node, neighbor), self.graph_a._weights,
                        "Weights don't seem to have updated correctly")

    def test_has_node(self):
        """
        Test the has_node() method.
        The expectation is that passing any node that has been added to the graph returns True.
        :return:
        """

        # hasNode successful cases
        self.assertTrue(self.graph_a.has_node(self.node1),
                        "has_node() returning False when it should not")
        self.assertTrue(self.graph_a.has_node(self.node2),
                        "has_node() returning False when it should not")
        self.assertTrue(self.graph_a.has_node(self.node3),
                        "has_node() returning False when it should not")

        # hasNode failure cases
        fail_node1 = Node()

        # node that has been added as a neighbor outside of the graph
        fail_neighbor = Node()
        fail_node2 = Node(neighbors={fail_neighbor})
        self.graph_a.add_node(fail_node2)

        # make sure node that has not been added returns false
        self.assertFalse(
            self.graph_a.has_node(fail_node1),
            "has_node() returns True for a node that has not been added")

        self.assertTrue(self.graph_a.has_node(fail_node2),
                        "has_node() returning False when it should not")
        error_msg = "Returns True for node that has been added as a neighbor outside of the graph"
        self.assertFalse(self.graph_a.has_node(fail_neighbor), error_msg)

    def test_has_edge(self):
        """
        Tests the has_edge method.
        The expectation is that passing any edge (directed) that has been added to the graph returns True.
        - Tests that the function returns True when expected
        - Tests that the function returns False when expected
        - Tests that the function raises an exception when either of the nodes are not in the graph
        :return:
        """

        # hasEdge successful cases
        self.assertTrue(self.graph_a.has_edge(self.node2, self.node1),
                        "has_edge() returning False when it should not")
        self.assertTrue(self.graph_a.has_edge(self.node3, self.node1),
                        "has_edge() returning False when it should not")

        # hasEdge fail cases
        self.assertFalse(self.graph_a.has_edge(self.node1, self.node2),
                         "has_edge() returning True when it should not")
        self.assertFalse(self.graph_a.has_edge(self.node1, self.node3),
                         "has_edge() returning True when it should not")
        self.assertFalse(self.graph_a.has_edge(self.node3, self.node3),
                         "has_edge() returning True for not-added self-edge")

        self.assertRaises(AssertionError, self.graph_a.has_edge, self.node1,
                          Node())
        self.assertRaises(AssertionError, self.graph_a.has_edge, Node(),
                          self.node1)
        self.assertRaises(AssertionError, self.graph_a.has_edge, self.node2,
                          Node({self.node2}))

        fail_node1 = Node()
        fail_neighbor = Node({fail_node1})
        self.assertRaises(AssertionError, self.graph_a.has_edge, fail_node1,
                          fail_neighbor)
        self.assertRaises(AssertionError, self.graph_a.has_edge, fail_neighbor,
                          fail_node1)

    def test_add_node(self):
        """
        Tests the add_node() method
        :return:
        """
        # true cases
        self.assertIn(self.node1, self.graph_a._graph,
                      "has_node failed to add nodes")
        self.assertIn(self.node2, self.graph_a._graph,
                      "has_node failed to add nodes")
        self.assertIn(self.node3, self.graph_a._graph,
                      "has_node failed to add nodes")

        # fail cases
        node4 = Node()
        node5 = Node()
        # incorrectly passed node
        #self.assertRaises(AssertionError,self.graph_a.add_node,(node4,node5))
        self.assertRaises(AssertionError, self.graph_a.add_node, None)
        # incorrectly passed neighbors
        self.assertRaises(AssertionError, self.graph_a.add_node, node4, node5)
        self.assertRaises(AssertionError, self.graph_a.add_node, node5, node5)

    def test_add_edge(self):
        """
        Tests adding edges between two existing nodes using the add_edge() method
        :return:
        """
        # generic/correct use
        self.graph_a.add_edge(self.node2, self.node3)
        self.assertIn(
            (self.node2, self.node3),
            self.graph_a._weights)  # tests that it was added to weights
        self.assertIn(self.node3, self.graph_a._graph[
            self.node2])  # tests that it was added to _graph
        # adding multiple edges
        neighbor_list = []
        for _ in range(400):
            temp_node = Node()
            neighbor_list.append(temp_node)
            self.graph_a.add_node(temp_node)
            self.graph_a.add_edge(self.node3, temp_node)

        for neighbor in neighbor_list:
            self.assertIn((self.node3, neighbor), self.graph_a._weights.keys()
                          )  # tests that it was added to weights
            self.assertIn(neighbor, self.graph_a._graph[
                self.node3])  # tests that it was added to _graph

        # add a -> b and b -> a
        for neighbor in neighbor_list:
            self.graph_a.add_edge(neighbor, self.node3)

        for neighbor in neighbor_list:
            self.assertIn((neighbor, self.node3), self.graph_a._weights.keys()
                          )  # tests that it was added to weights
            self.assertIn(self.node3, self.graph_a._graph[neighbor]
                          )  # tests that it was added to _graph

    def test_delete_node(self):
        """ test the delete_node method"""
        self.graph_a.add_edge(self.node1, self.node3)
        self.assertIn((self.node1, self.node3), self.graph_a._weights)
        self.assertIn((self.node3, self.node1), self.graph_a._weights)

        self.assertTrue(self.graph_a.has_node(self.node1))

        self.graph_a.delete_node(self.node1)

        print(self.graph_a.get_all_edges(stringify=True))

        self.assertFalse(self.graph_a.has_node(self.node1))

        # confirm that the internal methods for clearing out the relationships were successful
        self.assertNotIn((self.node1, self.node3), self.graph_a._weights)
        self.assertNotIn((self.node3, self.node1), self.graph_a._weights)
        self.assertRaises(KeyError, self.graph_a._graph.__getitem__,
                          self.node1)

        # confirm _graph neighbors have been deleted

        for node, neighbors in self.graph_a._graph.items():
            print(self.node1, "|||", node)
            self.assertNotIn(self.node1, neighbors)

        self.assertNotIn(self.node1, self.graph_a._graph.keys())

    def test_incoming_node_neighbors(self):
        self.assertEqual(self.graph_a.get_incoming_neighbors(self.node1),
                         {self.node2, self.node3})

    def test_thresholding(self):
        self.graph_a.add_edge(self.node1, self.node3, 4)
        self.graph_a.add_edge(self.node1, self.node2, 2)
        print(self.graph_a.get_threshold(25))

    def test_save_graph(self):
        self.graph_a.load_save(self.graph_a.get_save())
Exemplo n.º 2
0
class BasicGraphTest(unittest.TestCase):
    def setUp(self):
        """Call before every test case."""
        self.basic_graph = Graph(name="myGraph")

        # Simple graph with three nodes
        self.node1 = Node(label='node1')
        self.node2 = Node(label='node2')
        self.node3 = Node(label='node3')

        self.basic_graph.add_node(self.node1)
        self.basic_graph.add_node(self.node2, neighbors={self.node1})
        self.basic_graph.add_node(self.node3, neighbors={self.node1})

        self.graph_algorithms = GraphAlgorithms()

    def tearDown(self):
        """Call after every test case."""

    def test_node_count(self):
        node_count = self.graph_algorithms.node_count(self.basic_graph)
        self.assertEqual(node_count, 3)
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(self.graph_algorithms.node_count(sample_graph_a), 5)

    def test_edge_count(self):
        edge_count = self.graph_algorithms.edge_count(self.basic_graph)
        self.assertEqual(edge_count, 2)
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(self.graph_algorithms.edge_count(sample_graph_a), 5)

    def test_shortest_path(self):
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        paths = {}
        for source_node in sample_graph_a.get_all_nodes():
            shortest_dist, prev = self.graph_algorithms.shortest_path_length(
                sample_graph_a, source_node)
            source_label = source_node.label
            length_list = [None] * 5
            for node in shortest_dist.keys():
                # print(source_label+'>'+node.label+':'+str(shortest_dist[node]))
                length_list.__setitem__(int(node.label), shortest_dist[node])
            paths[source_label] = length_list
        # print(paths)
        # print(sample_graphs.graph_a['minpath'])
        self.assertEqual(paths, sample_graphs.graph_a['minpath'])

    def test_average_path(self):
        self.assertEqual(
            self.graph_algorithms.minimum_average_path(self.basic_graph), 1,
            "minimum average path failed")
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(
            self.graph_algorithms.minimum_average_path(sample_graph_a),
            sample_graphs.graph_a['avgpath'])

    def test_diameter(self):
        self.assertEqual(self.graph_algorithms.diameter(self.basic_graph), 1,
                         'diameter algorithm failed for basic graph')
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(self.graph_algorithms.diameter(sample_graph_a),
                         sample_graphs.graph_a['diameter'],
                         'diameter algorithm failed for sample graph a')

    def test_mode_path(self):
        self.assertEqual(
            self.graph_algorithms.mode_path_length(self.basic_graph), (1, 2),
            'mode_path_length algorithm failed for basic graph')
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(
            self.graph_algorithms.mode_path_length(sample_graph_a),
            sample_graphs.graph_a['mode_path_length'],
            'mode_path_length algorithm failed for sample graph a')

    def test_median_path(self):
        self.assertEqual(
            self.graph_algorithms.median_path_length(self.basic_graph), 1,
            'median_path_length algorithm failed for basic graph')
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(
            self.graph_algorithms.median_path_length(sample_graph_a),
            sample_graphs.graph_a['median_path_length'],
            'median_path_length algorithm failed for sample graph a')

    def test_average_edges_per_node(self):
        self.assertEqual(
            self.graph_algorithms.average_edges_per_node(self.basic_graph),
            0.67, 'average_edges_per_node algorithm failed for sample graph a')
        sample_graph_a = initialise_sample_graph(sample_graphs.graph_a)
        self.assertEqual(
            self.graph_algorithms.average_edges_per_node(sample_graph_a), 1.0,
            'average_edges_per_node algorithm failed for sample graph a')

    def test_dfs(self):  # todo finish test_dfs
        print(
            self.graph_algorithms.depth_first_search(self.basic_graph,
                                                     self.node1))

    def test_discover_components(self):  # todo finish test_clustering
        sample_graph_b = initialise_sample_graph(sample_graphs.graph_b)
        print(self.graph_algorithms.discover_components(sample_graph_b))

    def test_edmonds(self):
        sample_graph_c = initialise_sample_graph(sample_graphs.graph_c)
        source = sample_graph_c.get_node_from_label('0')
        sink = sample_graph_c.get_node_from_label('11')
        print(self.graph_algorithms.edmonds_karp(sample_graph_c, source, sink))

    def test_local_clustering_coefficient(self):
        print(
            self.graph_algorithms.local_clustering_coefficient(
                self.basic_graph, self.node1))

    def test_global_clustering_coefficient(self):
        print(
            self.graph_algorithms.average_clustering_coefficient(
                self.basic_graph))

    def test_save_graph_agls(self):
        test_graph = Graph('test')
        test_graph.load_save(self.basic_graph.get_save())
        print(self.graph_algorithms.node_count(test_graph))

    def test_structural_holes(self):
        sample_graph_c = initialise_sample_graph(sample_graphs.graph_c)

        print(sample_graph_c.get_save())
        print(self.graph_algorithms.structural_holes(sample_graph_c))