Beispiel #1
0
    def test_all_in_edges_of_node(self):
        graph = DiGraph()

        tuple0 = (0, 30, 2)
        tuple1 = (50, 50, 50)
        node0 = NodeData(0, tuple0)  # node: key=0 tuple=(0, 30, 2)
        node1 = NodeData(1, tuple0)  # node: key=1 tuple=(0, 30, 2)
        node2 = NodeData(2, tuple1)  # node: key=2 tuple=(50, 50, 50)
        node3 = NodeData(3, tuple1)  # node: key=3 tuple=(50, 50, 50)

        graph.add_node(node0.get_key(), tuple0)  # add node0
        self.assertEqual({}, graph.all_in_edges_of_node(
            node0.get_key()))  # check the list In empty
        graph.add_node(node1.get_key(), tuple0)  # add node1
        graph.add_node(node2.get_key(), tuple1)  # add node2
        graph.add_node(node3.get_key(), tuple1)  # add node3

        graph.add_edge(node1.get_key(), node0.get_key(), 10)  # connect 1->0
        graph.add_edge(node2.get_key(), node0.get_key(), 15)  # connect 2->0
        graph.add_edge(node3.get_key(), node0.get_key(), 20)  # connect 3->0

        ans_list_keys = [node1.get_key(), node2.get_key(), node3.get_key()]
        for i in graph.all_in_edges_of_node(node0.get_key()).keys():
            self.assertIn(i, ans_list_keys)
        graph.remove_node(node2.get_key())  # remove node2
        graph.remove_node(node3.get_key())  # remove node3

        ans_list_keys = [node1.get_key()]
        for i in ans_list_keys:
            self.assertIn(i,
                          graph.all_in_edges_of_node(node0.get_key()).keys())
Beispiel #2
0
 def test_all_edges(self):
     G = DiGraph()
     G.add_node(0)
     G.add_node(1)
     G.add_node(2)
     G.add_edge(0, 1, 10)
     G.add_edge(2, 1, 10)
     self.assertEqual(len(G.all_in_edges_of_node(1)), 2)
     self.assertEqual(len(G.all_out_edges_of_node(1)), 0)
     self.assertEqual(len(G.all_in_edges_of_node(0)), 0)
     self.assertEqual(len(G.all_out_edges_of_node(0)), 1)
 def test_all_out_edges_of_node(self):
     graph = DiGraph()
     self.assertTrue(graph.add_node(0))
     self.assertTrue(graph.add_node(1))
     self.assertTrue(graph.add_node(2))
     self.assertTrue(graph.add_node(3))
     self.assertTrue(graph.add_edge(1, 2, 0))
     self.assertTrue(graph.add_edge(2, 1, 1))
     edge = graph.all_in_edges_of_node(1)
     self.assertEqual(edge[2], 1)
     edge = graph.all_in_edges_of_node(2)
     self.assertEqual(edge[1], 0)
Beispiel #4
0
 def test_all_in_edges_of_node(self):
     g = DiGraph()
     g.add_node(1)
     g.add_node(2)
     g.add_node(3)
     g.add_node(4)
     g.add_edge(1, 2, 3)
     g.add_edge(2, 3, 2)
     g.add_edge(3, 4, 3)
     g.add_edge(4, 1, 2.5)
     self.assertDictEqual({4: 2.5}, g.all_in_edges_of_node(1))
     g.add_edge(2, 1, 0.5)
     self.assertDictEqual({2: 0.5, 4: 2.5}, g.all_in_edges_of_node(1))
Beispiel #5
0
 def test_remove_edge(self):
     graph = DiGraph()
     graph.add_node(1)
     graph.add_node(2)
     graph.add_node(3)
     graph.add_edge(1, 2, 1)
     graph.add_edge(1, 3, 1)
     self.assertEqual(graph.all_in_edges_of_node(2).get(1), 1)
     self.assertEqual(graph.all_out_edges_of_node(1).get(2), 1)
     graph.remove_edge(1, 2)
     self.assertEqual(graph.all_in_edges_of_node(2).get(1), None)
     self.assertEqual(graph.all_out_edges_of_node(1).get(2), None)
     self.assertEqual(graph.e_size(), 1)
Beispiel #6
0
 def test_v_e_size_removes_and_add(self):
     graph = DiGraph()
     self.assertEqual(False, self.graph.add_edge(1, 7, -1))
     self.assertEqual(0, graph.e_size())
     self.assertEqual(0, graph.v_size())
     self.assertEqual(0, graph.get_mc())
     self.assertEqual(False, graph.remove_edge(1, 3))
     self.assertEqual({}, graph.all_out_edges_of_node(3))
     self.assertEqual({}, graph.all_in_edges_of_node(3))
     self.assertEqual(14, self.graph.v_size())
     self.assertEqual(24, self.graph.e_size())
     self.assertEqual(38, self.graph.get_mc())
     self.assertEqual(True, self.graph.remove_node(4))
     self.assertEqual(39, self.graph.get_mc())
     self.assertEqual(True, self.graph.remove_edge(1, 2))
     self.graph.remove_edge(11, 10)
     self.assertEqual(False, self.graph.remove_node(15))
     self.assertEqual(False, self.graph.remove_node(0))
     self.assertEqual(False, self.graph.remove_node(-1))
     self.assertEqual(False, self.graph.remove_edge(11, 11))
     self.assertEqual(False, self.graph.remove_edge(6, 5))
     self.assertEqual(17, self.graph.e_size())
     self.assertEqual(13, self.graph.v_size())
     self.graph.add_node(99)
     self.assertEqual(14, self.graph.v_size())
     self.graph.add_edge(99, 10, 5)
     self.graph.add_edge(99, 5, 5)
     self.graph.add_edge(99, 10, 5)
     self.graph.add_edge(99, 99, 5)
     self.graph.add_edge(10, 99, 5)
     self.graph.add_edge(10, 99, 5)
     self.assertEqual(20, self.graph.e_size())
     self.assertEqual(45, self.graph.get_mc())
Beispiel #7
0
    def test_add_node1(self):
        graph = DiGraph()
        graph.add_node(1)
        graph.add_node(2)
        graph.add_node(3)
        graph.add_node(4)
        graph.add_node(5)
        graph.add_edge(1, 2, 3)
        graph.add_edge(2, 3, 4)
        graph.add_edge(3, 4, 10)
        graph.add_edge(4, 3, 1)
        graph.add_edge(3, 5, 7)
        graph.add_edge(5, 1, 1)
        graph.add_edge(1, 5, 2)

        self.assertEqual(12, graph.get_mc())
        self.assertEqual(5, graph.v_size())
        self.assertEqual(7, graph.e_size())

        keys = [1, 2, 3, 4, 5]
        self.assertEqual(keys, list(graph.get_all_v().keys()))
        self.assertEqual({2: 4, 4: 1}, graph.all_in_edges_of_node(3))
        self.assertEqual({4: 10, 5: 7}, graph.all_out_edges_of_node(3))

        graph.remove_edge(5, 1)
        self.assertEqual(6, graph.e_size())
        self.assertEqual(0, len(graph.all_out_edges_of_node(5)))
        self.assertEqual(13, graph.get_mc())

        graph.remove_node(3)
        self.assertEqual(4, graph.v_size())
        self.assertEqual(2, graph.e_size())

        self.assertEqual(0, len(graph.all_out_edges_of_node(4)))
        self.assertEqual(14, graph.get_mc())
Beispiel #8
0
def check0():
    """
    This function tests the naming (main methods of the DiGraph class, as defined in GraphInterface.
    :return:
    """
    g = DiGraph()  # creates an empty directed graph
    for n in range(4):
        g.add_node(n)
    g.add_edge(0, 1, 1)
    g.add_edge(1, 0, 1.1)
    g.add_edge(1, 2, 1.3)
    g.add_edge(2, 3, 1.1)
    g.add_edge(1, 3, 1.9)
    g.remove_edge(1, 3)
    g.add_edge(1, 3, 10)
    print(g)  # prints the __repr__ (func output)
    print(g.get_all_v())  # prints a dict with all the graph's vertices.
    print(g.all_in_edges_of_node(1))
    print(g.all_out_edges_of_node(1))

    g_algo = GraphAlgo(g)
    g_algo.save_to_json('graph.json')

    g_algo2 = GraphAlgo()
    g_algo2.load_from_json('graph.json')
    g_algo2.save_to_json('graphAlgo2.json')

    print(g_algo.shortest_path(0, 3))
    g_algo.plot_graph()
Beispiel #9
0
 def test_all_out_edges_of_node(self):
     graph = DiGraph()
     for i in range(0, 20):
         graph.add_node(i)
     for i in range(0, 10):
         graph.add_edge(i, i + 1, 2)
     for i in graph.all_in_edges_of_node(10):
         self.assertTrue(10 in graph.all_out_edges_of_node(i))
Beispiel #10
0
 def test_all_in_edges_of_node(self):
     g0 = DiGraph()
     for i in range(0, 10):
         g0.add_node(i)
     g0.add_edge(4, 3, 1)
     g0.add_edge(4, 2, 1)
     g0.add_edge(2, 4, 1)
     g0.add_edge(1, 2, 1)
     g0.add_edge(5, 3, 1)
     g0.add_edge(2, 5, 1)
     self.assertEqual(2, len(g0.all_in_edges_of_node(3)))
     g0.add_edge(1, 3, 1)
     self.assertEqual(3, len(g0.all_in_edges_of_node(3)))
     g0.add_edge(1, 3, 1)  # already existed
     self.assertEqual(3, len(g0.all_in_edges_of_node(3)))
     g0.remove_edge(1, 3)  # check if this dict updates after removing edge
     self.assertEqual(2, len(g0.all_in_edges_of_node(3)))
class TestDiGraph(TestCase):
    def setUp(self) -> None:
        self.g = DiGraph()
        for i in range(5):
            self.g.add_node(i)
        self.g.add_edge(1, 2, 1)
        self.g.add_edge(1, 3, 1)
        self.g.add_edge(1, 4, 1)
        self.g.add_edge(2, 1, 1)
        self.g.add_edge(2, 0, 1.5)
        self.g.add_edge(3, 1, 1)
        self.g.add_edge(4, 0, 4.8)
        self.g.add_edge(4, 2, 1)

    def test_v_size(self):
        self.assertEqual(5, self.g.v_size())

    def test_e_size(self):
        self.assertEqual(8, self.g.e_size())

    def test_get_mc(self):
        self.assertEqual(13, self.g.get_mc())

    def test_add_edge(self):
        self.assertFalse(self.g.add_edge(9, 5, 0.35))
        self.assertTrue(self.g.add_edge(0, 2, 0.93))

    def test_add_node(self):
        self.assertFalse(self.g.add_node(0))
        self.assertTrue(self.g.add_node(5))
        self.assertFalse(self.g.add_node(5))

    def test_remove_node(self):
        self.assertFalse(self.g.remove_node(6))
        self.assertTrue(self.g.remove_node(4))
        self.assertEqual(5, self.g.e_size())

    def test_remove_edge(self):
        self.assertFalse(self.g.remove_edge(0, 7))
        self.assertTrue(self.g.remove_edge(1, 2))
        self.assertEqual(7, self.g.e_size())

    def test_all_in_edges_of_node(self):
        self.assertEqual({2: 1.5, 4: 4.8}, self.g.all_in_edges_of_node(0))

    def test_all_out_edges_of_node(self):
        self.assertEqual({2: 1, 3: 1, 4: 1}, self.g.all_out_edges_of_node(1))

    def test_get_all_v(self):
        self.assertEqual(5, len(self.g.get_all_v()))
        d = {
            0: self.g.get_all_v()[0],
            1: self.g.get_all_v()[1],
            2: self.g.get_all_v()[2],
            3: self.g.get_all_v()[3],
            4: self.g.get_all_v()[4]
        }
        self.assertEqual(d, self.g.get_all_v())
Beispiel #12
0
 def test_all_in_edges_of_node(self):
     graph = DiGraph()
     graph.add_node(1)
     graph.add_node(2)
     graph.add_edge(1, 2, 1)
     graph.add_edge(2, 1, 1)
     edges_in = graph.all_in_edges_of_node(1)
     self.assertEqual(len(edges_in.values()), 1, 'not all nodes returned')
     self.assertEqual(edges_in.get(2), 1, 'Doesn\'t contain all edges')
Beispiel #13
0
 def test_all_in_edges_of_node(self):
     g = DiGraph()
     g.add_node(1)
     g.add_node(2)
     g.add_node(3)
     g.add_edge(1, 2, 3.3)
     g.add_edge(2, 1, 3.3)
     g.add_edge(3, 1, 2.2)
     self.assertEqual(g.all_in_edges_of_node(2), {1: 3.3})
Beispiel #14
0
 def test_all_in_edges_of_node(self):
     graph = DiGraph()
     graph.add_node(0)
     graph.add_node(1)
     graph.add_node(2)
     graph.add_node(3)
     graph.add_edge(0, 1, 5)
     graph.add_edge(1, 2, 3)
     graph.add_edge(2, 0, 1)
     graph.add_edge(2, 1, 4)
     graph.add_edge(2, 3, 3)
     graph.add_edge(3, 2, 2)
     edges_in = graph.all_in_edges_of_node(1)
     self.assertEqual(len(edges_in.values()), 2,
                      "the number of the edges that in to the node 1")
     graph.remove_node(2)
     edges_in = graph.all_in_edges_of_node(1)
     self.assertEqual(len(edges_in.values()), 1,
                      "the new number of the edges that in to the node 1")
Beispiel #15
0
def check():
    """
    This function tests the naming (main methods of the DiGraph class, as defined in GraphInterface.
    :return:


    """
    g = DiGraph()  # creates an empty directed graph

    for n in range(100):
        g.add_node(n)

    b = g.add_node(1)
    print("add test (false):" + str(b))  # should return false

    g.add_edge(0, 1, 1)
    g.add_edge(1, 0, 1.1)

    g.add_edge(1, 2, 1.3)
    g.add_edge(2, 3, 1.1)

    g.add_edge(1, 3, 1.9)
    b = g.add_edge(1, 3, 10)
    print("add update weight (false): ", b)

    b = g.remove_edge(1, 3)
    print("remove (true): " + str(b))  # should return true

    b = g.add_edge(1, 3, 10)
    print("add after remove (true): ", b)

    b = g.remove_node(2)
    print("remove node (true): ", b)

    b = g.remove_node(12)
    print("remove node that doesnt exist(false): ", b)

    b = g.add_edge(2, 3, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 2, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 3, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 13, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    print(g)  # prints the __repr__ (func output)

    print(g.get_all_v())  # prints a dict with all the graph's vertices.
    print(g.all_in_edges_of_node(1))
    print(g.all_out_edges_of_node(1))
    """
Beispiel #16
0
    def test_all_in_edges_of_node(self):
        graph = DiGraph()
        for i in range(10):
            graph.add_node(i)
        graph.add_edge(1, 2, 1.2)
        graph.add_edge(1, 3, 1.2)
        graph.add_edge(1, 4, 1.2)
        graph.add_edge(1, 5, 1.2)
        graph.add_edge(1, 5, 1.2)

        graph.add_edge(9, 1, 14.0)
        graph.add_edge(9, 1, 14.0)
        graph.add_edge(8, 1, 15.0)
        self.assertEqual(2, len(graph.all_in_edges_of_node(1)))
Beispiel #17
0
 def test_get_all_funcs(self):
     graph = DiGraph()
     self.assertEqual({}, graph.all_in_edges_of_node(1))
     self.assertEqual({}, graph.all_out_edges_of_node(1))
     self.assertEqual([], list(graph.get_all_v().keys()))
     self.assertEqual([], list(self.graph.all_out_edges_of_node(15)))
     self.assertEqual([], list(self.graph.all_in_edges_of_node(15)))
     self.assertEqual({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, self.graph.get_all_v().keys())
     self.assertEqual({1, 9, 13}, self.graph.all_in_edges_of_node(5).keys())
     self.assertEqual({3, 7, 4}, self.graph.all_in_edges_of_node(9).keys())
     self.assertEqual([], list(self.graph.all_in_edges_of_node(1).keys()))
     self.assertEqual({2, 5}, self.graph.all_out_edges_of_node(1).keys())
     self.graph.remove_node(5)
     self.assertEqual({1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14}, self.graph.get_all_v().keys())
Beispiel #18
0
    def test_add_edge(self):
        graph = DiGraph()
        graph.add_node(1)
        graph.add_node(2)
        graph.add_edge(1, 2, 1)
        self.assertEqual(graph.all_in_edges_of_node(2).get(1), 1, "yalla")
        self.assertEqual(graph.all_out_edges_of_node(1).get(2), 1, "yalla")
        graph.add_edge(1, 2, 1)
        self.assertEqual(
            graph.all_out_edges_of_node(1).get(2), 1,
            "failed in add duplicate test")
        self.assertEqual(
            graph.all_in_edges_of_node(2).get(1), 1,
            "failed in add duplicate test")
        self.assertEqual(graph.e_size(), 1, "failed in add duplicate test")

        graph.add_edge(1, 1, 1)
        self.assertEqual(
            graph.all_out_edges_of_node(1).get(1), None,
            "failed in add duplicate test")
        self.assertEqual(
            graph.all_in_edges_of_node(1).get(1), None,
            "failed in add duplicate test")
        self.assertEqual(graph.e_size(), 1, "failed in add duplicate test")
Beispiel #19
0
 def test_all_in_edges_of_node(self):
     graph = DiGraph()
     edges_list_tuple = []
     for i in range(5):
         graph.add_node(i)
     for s in graph.get_all_v().keys():
         for d in graph.get_all_v().keys():
             w = random.random()
             graph.add_edge(s, d, w)
             edges_list_tuple.append((s, d, w))
     for v in graph.get_all_v().keys():
         edges_list = [(s, d, w) for s, d, w in edges_list_tuple
                       if d != s and d == v]
         edge_dict = graph.all_in_edges_of_node(v)
         for s, d, w in edges_list:
             self.assertEqual(edge_dict[s], w)
Beispiel #20
0
    def test_get_edges(self):  # check for correct edges' dict values
        graph = DiGraph()
        for i in range(6):
            graph.add_node(i)
        graph.add_edge(0, 1, 1)
        graph.add_edge(2, 1, 3)
        graph.add_edge(3, 1, 4)
        graph.add_edge(1, 2, 3)
        graph.add_edge(1, 5, 6)

        # estimated values
        check_out = {2: 3, 5: 6}
        edges_out = graph.all_out_edges_of_node(1)
        check_in = {0: 1, 2: 3, 3: 4}
        edges_in = graph.all_in_edges_of_node(1)

        # check every dictionary values
        for e in edges_out:
            self.assertEqual(check_out[e], edges_out[e])
        for e in edges_in:
            self.assertEqual(check_in[e], edges_in[e])
Beispiel #21
0
class Test(TestCase):
    def setUp(self):
        # graph creator, |V|=7, |E|=18
        self.graph = DiGraph()
        for i in range(7):
            self.graph.add_node(i)
        self.graph.add_edge(0, 1, 1)
        self.graph.add_edge(0, 2, 1)
        self.graph.add_edge(0, 3, 1)
        self.graph.add_edge(0, 4, 1)
        self.graph.add_edge(0, 5, 1)
        self.graph.add_edge(0, 6, 1)
        self.graph.add_edge(1, 0, 1)
        self.graph.add_edge(1, 2, 1)
        self.graph.add_edge(2, 1, 1)
        self.graph.add_edge(2, 4, 1)
        self.graph.add_edge(3, 4, 1)
        self.graph.add_edge(3, 5, 1)
        self.graph.add_edge(4, 1, 1)
        self.graph.add_edge(4, 2, 1)
        self.graph.add_edge(4, 3, 1)
        self.graph.add_edge(5, 0, 1)
        self.graph.add_edge(5, 2, 1)
        self.graph.add_edge(5, 4, 1)

    def test_v_size(self):
        self.assertEqual(7, self.graph.v_size())
        # add new node
        self.assertTrue(self.graph.add_node(7))
        self.assertEqual(8, self.graph.v_size())
        # add existing node
        self.assertFalse(self.graph.add_node(0))
        self.assertEqual(8, self.graph.v_size())

    def test_e_size(self):
        self.assertEqual(18, self.graph.e_size())
        # add new edge
        self.assertTrue(self.graph.add_edge(6, 5, 1))
        self.assertEqual(19, self.graph.e_size())
        # add edge that already exists in the graph
        self.assertFalse(self.graph.add_edge(0, 1, 1))
        self.assertEqual(19, self.graph.e_size())

    def test_get_all_v(self):
        nodes = {
            0: Node(0),
            1: Node(1),
            2: Node(2),
            3: Node(3),
            4: Node(4),
            5: Node(5),
            6: Node(6)
        }
        self.assertEqual(nodes.__repr__(), self.graph.get_all_v().__repr__())

    def test_all_in_edges_of_node(self):
        self.assertEqual({1: 1, 5: 1}, self.graph.all_in_edges_of_node(0))
        self.graph.add_node(7)
        self.assertEqual({}, self.graph.all_in_edges_of_node(7))

        self.assertRaises(Exception, self.graph.all_in_edges_of_node, 10)

    def test_all_out_edges_of_node(self):
        self.assertEqual({
            1: 1,
            2: 1,
            3: 1,
            4: 1,
            5: 1,
            6: 1
        }, self.graph.all_out_edges_of_node(0))
        self.assertEqual({0: 1, 2: 1}, self.graph.all_out_edges_of_node(1))
        self.assertEqual({}, self.graph.all_out_edges_of_node(6))

        self.assertRaises(Exception, self.graph.all_in_edges_of_node, 10)

    def test_get_mc(self):
        self.assertEqual(25, self.graph.get_mc())
        # remove node with edges
        self.assertTrue(self.graph.remove_node(0))
        # mc+=9 , remove node: 1, remove edges out of node 0: 5, remove edges in to node 0: 2
        self.assertEqual(34, self.graph.get_mc())

    def test_add_edge(self):
        self.assertEqual(18, self.graph.e_size())
        # add new edge
        self.assertTrue(self.graph.add_edge(6, 5, 1))
        self.assertEqual(19, self.graph.e_size())
        self.assertEqual(26, self.graph.get_mc())
        # add edge that already exists in the graph
        self.assertFalse(self.graph.add_edge(0, 1, 1))
        # add edge between nodes that does not exists in the graph
        self.assertFalse(self.graph.add_edge(0, 10, 1))
        self.assertFalse(self.graph.add_edge(10, 0, 1))
        self.assertFalse(self.graph.add_edge(10, 11, 1))
        self.assertEqual(19, self.graph.e_size())
        self.assertEqual(26, self.graph.get_mc())

    def test_add_node(self):
        self.assertEqual(7, self.graph.v_size())
        # add new node
        self.assertTrue(self.graph.add_node(7))
        self.assertEqual(8, self.graph.v_size())
        self.assertEqual(26, self.graph.get_mc())
        # add existing node
        self.assertFalse(self.graph.add_node(0))
        self.assertEqual(8, self.graph.v_size())
        self.assertEqual(26, self.graph.get_mc())

    def test_remove_node(self):
        self.assertEqual(7, self.graph.v_size())
        # remove node
        self.assertTrue(self.graph.remove_node(6))
        self.assertEqual(6, self.graph.v_size())
        self.assertEqual(27, self.graph.get_mc())
        # remove node that does not exists in the graph
        self.assertFalse(self.graph.remove_node(10))
        self.assertEqual(6, self.graph.v_size())
        self.assertEqual(27, self.graph.get_mc())

    def test_remove_edge(self):
        self.assertEqual(18, self.graph.e_size())
        # remove edge
        self.assertTrue(self.graph.remove_edge(1, 2))
        self.assertEqual(17, self.graph.e_size())
        self.assertEqual(26, self.graph.get_mc())
        # remove edge that does not exists in the graph
        self.assertFalse(self.graph.remove_edge(1, 6))
        self.assertEqual(17, self.graph.e_size())
        self.assertEqual(26, self.graph.get_mc())

    def test_get_node(self):
        node_0 = self.graph.nodes.get(0)
        self.assertEqual(node_0, self.graph.get_node(0))
        self.assertRaises(Exception, self.graph.get_node, 10)
Beispiel #22
0
class TestDiGraph(TestCase):
    def setUp(self) -> None:
        self.graph = DiGraph()
        for i in range(4):
            self.graph.add_node(i)

        self.graph.add_edge(0, 1, 1)
        self.graph.add_edge(1, 0, 1)
        self.graph.add_edge(1, 2, 1)
        self.graph.add_edge(2, 3, 1)
        self.graph.add_edge(3, 1, 1)

    def test_v_size(self):
        size = self.graph.v_size()
        expected = 4
        self.assertEqual(size, expected)

    def test_e_size(self):
        size = self.graph.e_size()
        expected = 5
        self.assertEqual(size, expected)

    def test_get_all_v(self):
        all_v = list(self.graph.get_all_v())
        expected = [0, 1, 2, 3]
        self.assertEqual(all_v, expected)

    def test_get_node(self):
        in_node = self.graph.get_node(1)
        not_in_node = self.graph.get_node(10)
        expected_node_id = 1
        self.assertEqual(in_node.get_node_id(), expected_node_id)
        self.assertEqual(not_in_node, None)

    def test_all_in_edges_of_node_and_all_out_edges(self):
        all_in = list(self.graph.all_in_edges_of_node(1))
        expected = [0, 3]
        self.assertEqual(all_in, expected)
        all_out = list(self.graph.all_out_edges_of_node(1))
        expected = [0, 2]
        self.assertEqual(all_out, expected)

    def test_has_edge(self):
        check_edge = self.graph.has_edge(0, 1)
        self.assertEqual(check_edge, True)
        check_edge = self.graph.has_edge(2, 1)
        self.assertEqual(check_edge, False)

    def test_add_edge_and_remove_edge(self):
        self.graph.add_edge(1, 3, 1)
        size = self.graph.e_size()
        expected = 6
        self.assertEqual(size, expected)
        self.graph.remove_edge(1, 3)
        size = self.graph.e_size()
        expected = 5
        self.assertEqual(size, expected)

    def test_add_node_and_remove_node(self):
        self.graph.add_node(4)
        size = self.graph.v_size()
        expected = 5
        self.assertEqual(size, expected)
        self.graph.remove_node(4)
        size = self.graph.v_size()
        expected = 4
        self.assertEqual(size, expected)
Beispiel #23
0
class GraphAlgo(GraphAlgoInterface):
    """
 *  1) This class represents a Graph-Theory Algorithms on a directed weighted graph that is based on the given
 *     GraphAlgoInterface api.
 *
 *  2) This class and the algorithm is based on a Tree data structure
 *
 * This class contains all the requested methods:
 *              - get_graph
 *              - load
 *              - load_from_json
 *              - save_to_json
 *              - shortestPath
 *              - connected_component
 *              - connected_component by given a vertex
 *              - plot_graph
 *
 * Dijkstra's Shortest-Path algorithm:
 *
 *
 * function Dijkstra(Graph,source):
 *
 *   	create vertex set Q
 *
 *   	for each vertex v in Graph:		//Initialization
 *   		dist[v] <- INFINITY		//Unknown distance from source to V
 *   		prev[v] <- UNDEFINED		//Previous node in optimal path from source
 *   		add v to Q			//All nodes initially in Q (unvisited nodes)
 *
 *      dist[source] <- 0			//Distance from source to source
 *
 *   	while Q is not empty:
 *   		u <- vertex in Q with min dist[u] //Source node will be selected first
 *   		remove u from Q
 *
 *
 *   		for each neighbor v of u:        // where v is still in Q
 *   			alt <- dist[u] + length(u,v)
 *   			if alt < dist[v]:	 // A shorter path to v has been found
 *   			dist[v] <- alt
 *   			prev[v] <- u
 *
 *   	return dist[], prev[]
    """
    def __init__(self, graph: DiGraph = None):
        """
            init method
        :param graph:
        """
        if graph is None:
            self.graph = DiGraph()
        else:
            self.graph = graph

    def get_graph(self) -> GraphInterface:
        """
        :return: the directed graph on which the algorithm works on.
        """
        return self.graph

    def load_from_json(self, file_name: str) -> bool:
        """
        A method that loads the current graph from a json file.
        in order to implement the function we used the previous assignment's code
        plus:
        https://www.geeksforgeeks.org/how-to-convert-python-dictionary-to-json/
        https://www.w3schools.com/python/python_try_except.asp
        https://www.geeksforgeeks.org/read-json-file-using-python/

        :param file_name:
        :return:
        """
        try:
            with open(file_name, 'r') as file_n:
                g_s = file_n.read()
                json_graph = json.loads(g_s)
            for m in json_graph['Nodes']:
                key = m.get("id")
                pos = m.get("pos")
                if "pos" not in m:
                    node = GNode(key)
                    key = node.get_key()
                    self.graph.add_node(key)
                else:
                    node = GNode(key)
                    key = node.get_key()
                    self.graph.add_node(key)
                    position = tuple((float, m['pos'].split(',')))
                    self.graph.add_node(key, position)
            for k in json_graph['Edges']:
                src = int(k.get('src'))
                w = float(k.get('w'))
                dst = int(k.get('dest'))
                self.graph.add_edge(src, dst, w)
            file_n.close()
            return True
        except OSError:
            print("File does not exist!\n")
            return False

    def save_to_json(self, file_name: str) -> bool:
        """
        A method that saves the current graph into json file.
        in order to implement the function we used the previous assignment's code
        plus:

        https://www.w3schools.com/python/python_try_except.asp
        https://www.geeksforgeeks.org/saving-text-json-and-csv-to-a-file-in-python/
        :param file_name:
        :return: boolean
        """
        try:
            with open(file_name, 'w') as file:
                graph = {"Edges": [], "Nodes": []}
                for k in self.graph.edges:
                    graph["Edges"].append({
                        "src": k[0],
                        "w": k[2],
                        "dest": k[1]
                    })

                for j in self.graph.vertices:
                    node = self.graph.get_node(j)
                    if node.get_position() is None:
                        graph["Nodes"].append({"id": node.get_key()})
                    else:
                        position = str(node.get_position()[0]) + "," + str(
                            node.get_position()[1]) + "," + str(
                                node.get_position()[2])
                        graph["Nodes"].append({
                            'pos': position,
                            "id": node.get_key()
                        })

                file.write(json.dumps(graph))
                file.close()
                return True

        except OSError:
            print("File", file_name, " not found! ")
            return False

    def shortest_path(self, id1: int, id2: int) -> (float, list):
        """
        Returns the shortest path from node id1 to node id2 using Dijkstra's Algorithm
        @param id1: The start node id
        @param id2: The end node id
        @return: The distance of the path, a list of the nodes ids that the path goes through

        Notes:
        If there is no path between id1 and id2, or one of them dose not exist the function returns (float('inf'),[])
        More info:
        https://en.wikipedia.org/wiki/Dijkstra's_algorithm
        """
        if id1 not in self.graph.vertices or id2 not in self.graph.vertices:
            return float('inf'), []
        if id1 == id2:
            return 0, [id1]
        ans = self.dijksytra_algo(id1, id2)
        return ans

    def connected_component(self, id1: int) -> list:
        """
        Finds the Strongly Connected Component(SCC) that node id1 is a part of.
        based on two helping functions below and compare them
        @param id1: The node id
        @return: The list of nodes in the SCC

        Notes:
        If the graph is None or id1 is not in the graph, the function should return an empty list []
        """
        component_original = self.connected_component_aid_original_geph(id1)
        component_revers = self.connected_component_aid_reverse_geph(id1)
        container = []
        for k in component_original:
            for m in component_revers:
                if k == m:
                    if k not in container:
                        container.append(k)
                        self.graph.get_node(k).set_info("in")
        container.sort()
        return container

    def connected_component_aid_original_geph(self, id1):
        """
        A method that helps us in connected components by a given node.
        gets all keys tags of every nodes that are connected to the id1 node
        :param id1:
        :return: container
        """
        self.reset_nodes_tags()
        container = []
        pointer = 0
        container.append(id1)
        while pointer < len(container):
            key = container[pointer]
            node_neighbors = self.graph.all_out_edges_of_node(key)
            for m in range(0, len(node_neighbors)):
                neighbor_key = list(node_neighbors.keys())[m]
                node_pointer = self.graph.get_node(neighbor_key)
                if node_pointer.get_tag() == -1:
                    container.append(neighbor_key)
                    node_pointer.set_tag(1)
            pointer += 1
        return container

    def connected_component_aid_reverse_geph(self, id1):
        """
        A method that helps us in connected components by a given node.
        gets all keys tags of every nodes that are connected to the id1 node but the only
        change is that the function reverse the graph
        :param id1:
        :return: container
        """
        self.reset_nodes_tags()
        container = []
        pointer = 0
        container.append(id1)
        while pointer < len(container):
            key = container[pointer]
            node_neighbors = self.graph.all_in_edges_of_node(key)
            for m in range(0, len(node_neighbors)):
                neighbor_key = list(node_neighbors.keys())[m]
                node_pointer = self.graph.get_node(neighbor_key)
                if node_pointer.get_tag() == -1:
                    container.append(neighbor_key)
                    node_pointer.set_tag(1)
            pointer += 1
        return container

    def connected_components(self) -> List[list]:
        """
        Finds all the Strongly Connected Component(SCC) in the graph.
        check each vertex on the connected_components by given a node
        @return: The list all SCC

        Notes:
        If the graph is None the function should return an empty list []
        """
        self.reset_nodes_info()
        ans = []
        graph_nodes = self.graph.get_all_v()
        for n in graph_nodes:
            if self.graph.get_node(n).get_info() != "in":
                mid_ans = self.connected_component(n)
                ans.append(mid_ans)
        return ans

    def reset_nodes_info(self) -> None:
        """
        Aid function that walks all over the graph and reset each node's info
        :return: None
        """
        for k in self.graph.get_all_v():
            self.graph.get_node(k).set_info("")

    def plot_graph(self) -> None:
        """
        Plots the graph.
        If the nodes have a position, the nodes will be placed there.
        Otherwise, they will be placed in a random but elegant manner.
        @return: None
        """
        self.reset_nodes_tags()
        x = []
        y = []
        key = []
        graph_vertex = self.graph.get_all_v()
        for i in graph_vertex:
            node_pointer = self.graph.get_node(i)
            pos = node_pointer.get_position()
            if pos is None:
                node_pointer.set_position(random() * 434, random() * 35, 0)
            pos = node_pointer.get_position()
            x.append(pos[0])
            y.append(pos[1])
            key.append(i)
        fig, ax = plt.subplots()
        ax.scatter(x, y)

        for i in self.graph.edges:
            src = self.graph.get_node(i[0])
            dest = self.graph.get_node(i[1])
            src_x = src.get_position()[0]
            src_y = src.get_position()[1]
            dest_x = dest.get_position()[0]
            dest_y = dest.get_position()[1]
            x_list = [src_x, dest_x]
            y_list = [src_y, dest_y]
            ax.annotate("",
                        xy=(dest_x, dest_y),
                        xytext=(src_x, src_y),
                        arrowprops=dict(arrowstyle="->"),
                        color="RED")
            plt.plot(x_list, y_list, color="CYAN")
        for i, txt in enumerate(key):
            ax.annotate(key[i], (x[i], y[i]), color="BLUE")
        plt.title("Directed Weighted Graph - graph visualization")
        plt.show()

    def reset_nodes_tags(self) -> None:
        """
        Aid function that walks all over the graph and reset each node's tag
        :return: None
        """
        for k in self.graph.get_all_v():
            self.graph.get_node(k).set_tag(-1)

    def dijksytra_algo(self, src, dest) -> (float, list):
        """
        Dijkstra's shortest path algorithm (mentioned above) that is being implemented
        :param src:
        :param dest:
        :return: (float, list)
        """
        self.reset_nodes_tags()
        paths = {}
        container = []
        pointer = 0
        container.append(self.graph.get_node(src))
        paths[src] = 0
        container[0].set_tag(0)
        # create a dictionary, a list a variable, put inside the list the src node and resets everything created
        while pointer < len(container):
            node_o_pointer = container[pointer]
            src_key = node_o_pointer.get_key()
            node_neighbors = self.graph.all_out_edges_of_node(src_key)
            path_weight = paths[src_key]
            for k in range(0, len(node_neighbors)):
                # walks over the node neighbors
                dest_key = list(node_neighbors.keys())[k]
                edge_weight = self.graph.get_edge_weight(src_key, dest_key)
                node_pointer = self.graph.get_node(dest_key)
                tag = node_pointer.get_tag()
                if tag != -1:
                    # checks if the node is visited
                    new_path = path_weight + edge_weight
                    if new_path < paths[dest_key]:
                        paths[dest_key] = new_path
                if node_pointer.get_tag() == -1:
                    # checks if the node is unvisited
                    container.append(node_pointer)
                    paths[dest_key] = path_weight + edge_weight
                    node_pointer.set_tag(0)
            node_o_pointer.set_tag(1)
            pointer += 1
        if dest not in paths:
            # if didn't find destination node in paths list
            return float('inf'), []
        ans = []
        pointer = 0
        key = dest
        ans.append(key)
        while src not in ans and pointer < len(ans):
            key_pointer = ans[pointer]
            path_key = paths[key_pointer]
            key_neighbors = self.graph.all_in_edges_of_node(key_pointer)
            for l in key_neighbors:
                if l in paths:
                    path_n = paths[l]
                    e_b = self.graph.get_edge_weight(l, key_pointer)
                    if round(e_b + path_n, 7) == round(path_key, 7):
                        ans.append(l)
                        break
            pointer += 1
        return paths[dest], ans
Beispiel #24
0
class GraphAlgo(GraphAlgoInterface):
    def __init__(self, g: tuple = None):
        if g is None:
            self.g = DiGraph()
        else:
            self.g = g

    def get_graph(self) -> GraphInterface:
        return self.g

    def load_from_json(self, file_name: str):
        self.g = DiGraph()
        with open(file_name) as f:
            data = json.load(f)
            for n in data['Nodes']:
                self.g.add_node(n['id'])
            for e in data['Edges']:
                self.g.add_edge(e['src'], e['dest'], e['w'])

    def save_to_json(self, file_name: str):
        data = {"Edges": [], "Nodes": []}
        for n in self.g.get_all_v().keys():
            data["Nodes"].append({"id": n})
        for n in self.g.get_all_v().keys():
            for n2, w in self.g.all_out_edges_of_node(n).items():
                data["Edges"].append({"src": n, "w": w, "dest": n2})
        with open(file_name, 'w+') as f:
            json.dump(data, f)

    def shortest_path(self, id1: int, id2: int) -> (float, list):
        distancedict = {}
        q = []
        list = []
        q.append(id1)
        distancedict.update({id1: 0})
        while len(q) != 0:
            tmp = q.pop(0)
            for i in self.g.all_out_edges_of_node(tmp):
                if i not in distancedict:
                    q.append(i)
                    distancedict.update({
                        i:
                        self.g.all_out_edges_of_node(tmp)[i] +
                        distancedict[tmp]
                    })
                elif (self.g.all_out_edges_of_node(tmp)[i] +
                      distancedict[tmp]) < distancedict[i]:
                    q.append(i)
                    distancedict.update({
                        i:
                        self.g.all_out_edges_of_node(tmp)[i] +
                        distancedict[tmp]
                    })
        if not id2 in distancedict:
            return math.inf, []
        tmp2 = id2
        list.append(id2)
        while tmp2 != id1:
            for i in self.g.all_in_edges_of_node(tmp2):
                distancedict[i]
                if self.g.all_out_edges_of_node(
                        i)[tmp2] + distancedict[i] == distancedict[tmp2]:
                    list.append(i)
                    tmp2 = i
                    break
        list.reverse()
        return distancedict[id2], list

    def SCCUtil(self, u):
        next = 0
        nextgroup = 0
        index = [None] * self.g.v_size()
        lowlink = [None] * self.g.v_size()
        onstack = [False] * self.g.v_size()
        stack = []
        groups = []
        groupid = {}
        work = [(u, 0)]
        while work:
            v, i = work[-1]
            del work[-1]
            if i == 0:
                index[v] = next
                lowlink[v] = next
                next += 1
                stack.append(v)
                onstack[v] = True
            recurse = False
            for j in self.g.all_out_edges_of_node(v).keys():
                w = j
                if index[w] == None:
                    work.append((v, j + 1))
                    work.append((w, 0))
                    recurse = True
                    break
                elif onstack[w]:
                    lowlink[v] = min(lowlink[v], index[w])
            if recurse: continue
            if index[v] == lowlink[v]:
                com = []
                while True:
                    w = stack[-1]
                    del stack[-1]
                    onstack[w] = False
                    com.append(w)
                    groupid[w] = nextgroup
                    if w == v: break
                groups.append(com)
                nextgroup += 1
            if work:
                w = v
                v, _ = work[-1]
                lowlink[v] = min(lowlink[v], lowlink[w])
        return groups

    def connected_component(self, id1: int):
        for i in self.SCCUtil(id1):
            for j in i:
                if (j == id1):
                    return i
        return list()

    def Diff(self, li1, li2):
        return list(list(set(li1) - set(li2)) + list(set(li2) - set(li1)))

    def connected_components(self):
        check = list(self.g.get_all_v().keys())
        ans = list()
        for i in self.g.get_all_v().keys():
            obj = self.SCCUtil(i)
            for j in obj:
                if check.__contains__(j[0]):
                    j.reverse()
                    ans.append(j)
                    check = self.Diff(check, j)

        if not self.g.get_all_v().keys():
            ans.append(list())
        return ans

    def plot_graph(self):
        for key, val in self.g.get_all_v().items():
            x = val[0]
            y = val[1]
            plt.text(x, y, key)
            for node, _ in self.g.all_out_edges_of_node(key).items():
                x2, y2 = self.g.get_all_v()[node]
                x1, y1 = val
                plt.plot([x1, x2], [y1, y2], marker='o')
        plt.show()
Beispiel #25
0
class TestDiGraph(TestCase):
    def setUp(self) -> None:
        self.my_graph = DiGraph()
        for i in range(5):
            self.my_graph.add_node(i)

        self.my_graph.add_edge(0, 1, 3)
        self.my_graph.add_edge(0, 2, 1)
        self.my_graph.add_edge(2, 0, 9)
        self.my_graph.add_edge(1, 2, 20)
        self.my_graph.add_edge(1, 3, 5)
        self.my_graph.add_edge(1, 4, 7)
        self.my_graph.add_edge(3, 4, 55)
        self.my_graph.add_edge(4, 3, 34)

    def test_has_edge(self):
        self.assertTrue(self.my_graph.has_edge(0, 1))
        self.assertFalse(self.my_graph.has_edge(1, 0))
        self.assertFalse(self.my_graph.has_edge(3, 3))
        self.assertTrue(self.my_graph.has_edge(4, 3))

    def test_v_size(self):
        vertices = self.my_graph.get_all_v()
        self.assertEqual(len(vertices.keys()), self.my_graph.vertices_total)

    def test_e_size(self):
        self.my_graph.remove_edge(0, 2)
        self.assertEqual(7, self.my_graph.e_size())

    def test_get_all_v(self):
        self.assertEqual(self.my_graph.get_all_v().keys(), {0, 1, 2, 3, 4})

    def test_all_in_edges_of_node(self):
        self.assertEqual(self.my_graph.all_in_edges_of_node(0).keys(), {2})
        self.assertEqual(self.my_graph.all_in_edges_of_node(1).keys(), {0})
        self.assertEqual(self.my_graph.all_in_edges_of_node(2).keys(), {0, 1})
        self.assertEqual(self.my_graph.all_in_edges_of_node(3).keys(), {1, 4})
        self.assertEqual(self.my_graph.all_in_edges_of_node(4).keys(), {1, 3})

    def test_all_out_edges_of_node(self):
        self.assertEqual(self.my_graph.all_out_edges_of_node(0).keys(), {1, 2})
        self.assertEqual(
            self.my_graph.all_out_edges_of_node(1).keys(), {2, 3, 4})
        self.assertEqual(self.my_graph.all_out_edges_of_node(2).keys(), {0})
        self.assertEqual(self.my_graph.all_out_edges_of_node(3).keys(), {4})
        self.assertEqual(self.my_graph.all_out_edges_of_node(4).keys(), {3})

    def test_get_mc(self):
        self.g = DiGraph()
        for i in range(10):
            self.g.add_node(i)
        self.assertEqual(self.g.get_mc(), 10)

        for i in range(9):
            self.g.add_edge(i, i + 1, i + 1)
        self.assertEqual(self.g.get_mc(), 19)

        for i in range(6, 10):
            self.g.remove_node(i)
        self.assertEqual(self.g.get_mc(), 23)

    def test_add_edge(self):
        num_of_edges = self.my_graph.e_size()
        self.my_graph.add_edge(2, 4, 100)
        self.my_graph.remove_edge(2, 4)
        self.assertEqual(self.my_graph.e_size(), num_of_edges)
        self.assertFalse(self.my_graph.add_edge(11, 14, 55))

    def test_add_node(self):
        first_mc = self.my_graph.get_mc()
        num_of_nodes = self.my_graph.v_size()
        self.my_graph.add_node(2)
        self.assertEqual(first_mc, self.my_graph.get_mc())
        self.assertEqual(num_of_nodes, self.my_graph.v_size())
        self.my_graph.add_node(6)
        self.assertEqual(first_mc + 1, self.my_graph.get_mc())
        self.assertEqual(num_of_nodes + 1, self.my_graph.v_size())

    def test_remove_node(self):
        self.my_graph.remove_node(1)
        self.assertEqual(4, self.my_graph.v_size())
        self.assertEqual(4, self.my_graph.e_size())

    def test_remove_edge(self):
        self.my_graph.remove_edge(0, 2)
        self.assertEqual(self.my_graph.e_size(), 7)
Beispiel #26
0
def check():
    """
    This function tests the naming (main methods of the DiGraph class, as defined in GraphInterface.
    :return:


    """
    g = DiGraph()  # creates an empty directed graph

    for n in range(5):
        g.add_node(n)

    b = g.add_node(1)
    print("add test (false):" + str(b))  # should return false

    g.add_edge(0, 1, 1)
    g.add_edge(1, 0, 1.1)

    g.add_edge(1, 2, 1.3)
    g.add_edge(2, 3, 1.1)

    g.add_edge(1, 3, 1.9)
    b = g.add_edge(1, 3, 10)
    print("add update weight (false): ", b)

    b = g.remove_edge(1, 3)
    print("remove (true): " + str(b))  # should return true

    b = g.add_edge(1, 3, 10)
    print("add after remove (true): ", b)

    b = g.remove_node(2)
    print("remove node (true): ", b)

    b = g.remove_node(12)
    print("remove node that doesnt exist(false): ", b)

    b = g.add_edge(2, 3, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 2, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 3, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    b = g.add_edge(3, 13, 1.5)
    print("add edge of node that doesnt exist (false): ", b)

    print(g)  # prints the __repr__ (func output)

    print(g.get_all_v())  # prints a dict with all the graph's vertices.
    print(g.all_in_edges_of_node(1))
    print(g.all_out_edges_of_node(1))
    """
        output:

        g -> Graph: |V|=3 , |E|=3
        {0: 0: score inf, 1: 1: score inf, 2: 2: score inf, 3: 3: score inf}
        {0: 1}
        {0: 1.1, 3: 10}
    """
    g_algo = GraphAlgo(g)
    b = g_algo.save_to_json('../data/test_json')
    print("save: ", b)
    # print(g_algo.shortest_path(0, 3))

    # test shortest path

    dist, path = g_algo.shortest_path(0, 3)
    print(f"test shortest path < 0 to 3> -> (2.3, [0,1,2,3]) = {dist}, {path}")

    dist, path = g_algo.shortest_path(0, 50)
    print(f"test shortest path < 0 to 50> -> (inf, []) = {dist}, {path}")

    # dist, path = g_algo.shortest_path(20, 2)
    # print(dist, path)
    # dist, path = g_algo.shortest_path(2, 20)
    # print(dist, path)

    print(f"test SCC from node 0 -> [0, 1] = {g_algo.connected_component(0)}")
    g_ = GraphAlgo()
    g_.load_from_json('../data/A5')

    load_g = g_.get_graph()

    print(load_g)
    print(load_g.get_all_v())  # prints a dict with all the graph's vertices.
    print(load_g.all_in_edges_of_node(1))
    print(load_g.all_out_edges_of_node(1))

    g_.plot_graph()
class TestDiGraph(TestCase):

    def setUp(self) -> None:
        self.graph = DiGraph()
        for vertex in range(7):
            self.graph.add_node(vertex)
        self.graph.add_edge(0, 3, 3)
        self.graph.add_edge(1, 3, 1)
        self.graph.add_edge(2, 4, 1.99)
        self.graph.add_edge(3, 2, 7)
        self.graph.add_edge(3, 4, 1.2)
        self.graph.add_edge(4, 6, 1.99)
        self.graph.add_edge(4, 5, 1.8)
        self.graph.add_edge(6, 2, 1)
        self.graph.add_edge(6, 5, 9)

    def test_add_node(self):
        self.assertFalse(self.graph.add_node(0))

    def test_get_node(self):
        self.assertFalse(self.graph.get_node(100))
        self.assertTrue(self.graph.get_node(3))

    def test_add_edge(self):
        self.assertFalse(self.graph.add_edge(1, 4, -9))
        self.assertFalse(self.graph.add_edge(93, 4, -9))
        self.assertTrue(self.graph.add_edge(1, 3, 0.34))
        print(self.graph.edges)

    def test_all_in_edges_of_node(self):
        actual = list(self.graph.all_in_edges_of_node(2).keys())
        expected = [3, 6]
        self.assertEqual(actual, expected)
        self.assertIsNone(self.graph.all_in_edges_of_node(90))

    def test_all_out_edges_of_node(self):
        actual = list(self.graph.all_out_edges_of_node(4))
        expected = [6, 5]
        self.assertEqual(actual, expected)
        self.assertIsNone(self.graph.all_out_edges_of_node(90))
        actual_weight = self.graph.getEdge(4, 6)
        expected = 1.99
        self.assertEqual(actual_weight, expected)

    def test_remove_edge(self):
        tup = (3, 2, self.graph.getEdge(3, 2))
        self.assertFalse(self.graph.remove_edge(0, 31))
        self.assertTrue(self.graph.remove_edge(3, 2))
        actual = self.graph.e_size()
        expected = 8
        self.assertEqual(actual, expected)
        self.assertNotIn(tup, list(self.graph.edges))

    def test_remove_node(self):
        self.assertFalse(self.graph.remove_node(31))
        self.graph.remove_node(3)
        actual = self.graph.v_size()
        expected = 6
        self.assertEqual(actual, expected)
        self.assertNotIn(3, list(self.graph.adjacency))
        self.assertNotIn(3, list(self.graph.vertices))

    def test_graph_transpose(self):
        graph_transpose = self.graph.graph_transpose()
        actual = list(self.graph.edges)
        expected = []
        for source, destination, weight in graph_transpose.edges:
            expected.append((destination, source, weight))

        self.assertListEqual(actual, expected)

    def test_v_size(self):
        actual = self.graph.v_size()
        expected = 7
        self.assertEqual(actual, expected)
        self.graph.remove_node(900)
        self.assertEqual(actual, expected)

    def test_e_size(self):
        actual = self.graph.e_size()
        expected = 9
        self.assertEqual(actual, expected)
        self.graph.remove_edge(0, 900)
        self.assertEqual(actual, expected)

    def test_get_mc(self):
        actual = self.graph.mc
        expected = 16
        self.assertEqual(actual, expected)
        self.graph.remove_node(5)
        actual = self.graph.mc
        expected = 19
        self.assertEqual(actual, expected)

    def test_get_all_v(self):
        actual = list(self.graph.get_all_v())
        expected = [0, 1, 2, 3, 4, 5, 6]
        self.assertListEqual(actual,expected)

    def test_reset(self):
        for vertex in self.graph.vertices.values():
            vertex.setInfo("visited")

        self.graph.Reset()
        actual = 0
        for vertex in self.graph.vertices.values():
            if vertex.getInfo() == "unvisited":
                actual = actual + 1

        expected = 7
        self.assertEqual(actual, expected)
Beispiel #28
0
 def test_empty_list(self):
     g = DiGraph()
     g.add_node(1)
     self.assertEqual(g.all_in_edges_of_node(1), {})
Beispiel #29
0
class MyTestCase(unittest.TestCase):
    def setUp(self) -> None:
        self.graph = DiGraph()
        for i in range(5):
            self.graph.add_node(i)
        self.graph.add_edge(0, 1, 1.0)
        self.graph.add_edge(0, 2, 1.1)
        self.graph.add_edge(1, 3, 1.2)
        self.graph.add_edge(1, 4, 1.3)
        self.graph.add_edge(2, 0, 1.4)
        self.graph.add_edge(2, 3, 1.5)
        self.graph.add_edge(3, 1, 1.5)
        self.graph.add_edge(3, 4, 1.6)
        self.graph.add_edge(4, 0, 1.7)
        self.graph.add_edge(4, 1, 1.8)
        self.graph.add_edge(4, 3, 1.9)

    def test_v_size(self):
        self.assertEqual(5, self.graph.v_size())
        self.assertTrue(self.graph.add_node(5))
        self.assertEqual(6, self.graph.v_size())
        self.assertFalse(self.graph.add_node(1))
        self.assertEqual(6, self.graph.v_size())
        self.assertTrue(self.graph.add_node(6))
        self.assertEqual(7, self.graph.v_size())

    def test_e_size(self):
        self.assertEqual(11, self.graph.e_size())
        self.assertFalse(self.graph.add_edge(4, 3, 51.12))
        self.assertEqual(11, self.graph.e_size())
        self.assertTrue(self.graph.remove_node(1))
        self.assertEqual(6, self.graph.e_size())

    def test_add_node(self):
        self.assertEqual(5, self.graph.v_size())
        self.assertTrue(self.graph.add_node(13))
        self.assertEqual(6, self.graph.v_size())
        self.assertEqual(17, self.graph.get_mc())
        self.assertFalse(self.graph.add_node(4))
        self.assertEqual(17, self.graph.get_mc())

    def test_remove_node(self):
        self.assertEqual(16, self.graph.get_mc())
        self.assertEqual(5, self.graph.v_size())
        self.assertTrue(self.graph.remove_node(1))
        self.assertEqual(4, self.graph.v_size())
        self.assertEqual(17, self.graph.get_mc())
        self.assertFalse(self.graph.remove_node(9))
        self.assertEqual(4, self.graph.v_size())
        self.assertEqual(17, self.graph.get_mc())

    def test_add_edge(self):
        self.assertEqual(11, self.graph.e_size())
        self.assertTrue(self.graph.add_edge(0, 3, 4.99))
        self.assertEqual(12, self.graph.e_size())
        self.assertEqual(17, self.graph.get_mc())
        self.assertFalse(self.graph.add_edge(1, 4, 3.99))
        self.assertFalse(self.graph.add_edge(4, 51, 1))
        self.assertFalse(self.graph.add_edge(51, 4, 1))
        self.assertFalse(self.graph.add_edge(51, 12, 13))
        self.assertEqual(12, self.graph.e_size())
        self.assertEqual(17, self.graph.get_mc())

    def test_remove_edge(self):
        self.assertEqual(11, self.graph.e_size())
        self.assertTrue(self.graph.remove_edge(4, 3))
        self.assertEqual(10, self.graph.e_size())
        self.assertEqual(17, self.graph.get_mc())
        self.assertFalse(self.graph.remove_edge(3, 2))
        self.assertEqual(10, self.graph.e_size())
        self.assertEqual(17, self.graph.get_mc())

    def test_all_in_edges_of_node(self):
        self.assertIsNot({}, self.graph.all_in_edges_of_node(1))
        self.assertIsNot({}, self.graph.all_in_edges_of_node(2))
        self.assertIsNot({}, self.graph.all_in_edges_of_node(3))
        self.assertIsNot({}, self.graph.all_in_edges_of_node(4))
        self.assertTrue(self.graph.remove_edge(0, 2))
        self.assertEqual({}, self.graph.all_in_edges_of_node(2))

    def test_all_out_edges_of_node(self):
        self.assertIsNotNone(self.graph.all_out_edges_of_node(1))
        self.assertIsNotNone(self.graph.all_out_edges_of_node(2))
        self.assertIsNotNone(self.graph.all_out_edges_of_node(3))
        self.assertIsNotNone(self.graph.all_out_edges_of_node(4))
        self.assertIsNone(self.graph.all_out_edges_of_node(10))
        self.assertIsNone(self.graph.all_out_edges_of_node(22))

    def test_get_mc(self):
        self.assertEqual(16, self.graph.get_mc())
Beispiel #30
0
class GraphAlgo(GraphAlgoInterface):
    def __init__(self, graph: DiGraph = None):
        if graph is None:
            graph = DiGraph()
        self.G = graph

    def get_graph(self) -> GraphInterface:
        return self.G

    def load_from_json(self, file_name: str) -> bool:
        """create a graph using a saved text file by using the key words "Nodes" and "Edges"
        then split the string by , to get the X Y Z and creating a new node and adding it to the graph
         connects the nodes by Edges and w for weight src and dest"""
        self.G = DiGraph()
        try:
            with open(file_name, "r") as file:
                x = json.load(file)
                for node in x["Nodes"]:
                    if node.__contains__("pos"):
                        new_pos = [
                            float(i)
                            for i in node["pos"].split(",", maxsplit=2)
                        ]
                        self.G.add_node(node["id"],
                                        (new_pos[0], new_pos[1], new_pos[2]))
                    else:
                        self.G.add_node(node["id"])
                if x.__contains__("Edges"):
                    for edge in x["Edges"]:
                        self.G.add_edge(edge["src"], edge["dest"], edge["w"])

                return True
        except IOError as e:
            print(e)
            return False

    def save_to_json(self, file_name: str) -> bool:
        """save a graph to a text file and saving his Nodes and Edges
        for the nodes well save the pos and their key
        for the edges well save the src dest and edge weight"""
        graph_dict = {}
        edge_list = []

        for i in self.G.oute.keys():
            for j in self.G.oute[i].keys():
                edge_map = {'src': i, 'w': self.G.oute[i][j], 'dest': j}
                edge_list.append(edge_map)

        try:
            with open(file_name, "w") as file:
                graph_dict["Edges"] = edge_list
                graph_dict["Nodes"] = [i for i in self.G.graph.values()]
                json.dump(graph_dict, default=lambda m: m.as_dict(), fp=file)
                return True
        except IOError as e:
            print(e)
            return False

    def shortest_path(self, id1: int, id2: int) -> (float, list):
        """returns a list of nodes that represents the shortest path between tow nodes and the distance as well
        using Dijkstra algorithm is an algorithm to fined the shortest path between nodes(by weight).
        this method find the shortest distance by weight from src node to all the node in the graph.
        this method based on 4 data structure path(list) , unused(PriorityQueue), used(list)
        and nodePar(dict).
        first add the src node to unused PriorityQueue and set is weight to 0,
        continue while unused is not empty,
        iterate throw all it's neighbors and every node that isnt with inf weight
        if the node weight is bigger then his father weight + the edge weight or node weight is inf
        replace the node weight with his father + the edge between the node and his father.
        (skip this step for the father node).
        add to unused PriorityQueue  , same for all neighbors.
        after that pull the next node from unused, because of the PriorityQueue every next node on the list
        will be with the lightest weight.
        after iterate throw all the graph all the nodes will be in the nodeDis Hashmap and contain in the value
        their min weight from src node.
        also the nodePar will contain every node and his father when called from shortestPath method.
        now that nodePar is full we can go from the dest node by pointer back until well get to the
        src node while we adding the nodes the pointer points on to a list which will be the shortest path list
        then we return this list(nodes we need to go for the shortest path) and the weight of the dest(the distance of that path)"""
        if id1 not in self.G.get_all_v() or id2 not in self.G.get_all_v():
            tmp = (math.inf, [])
            return tmp
        used = []
        unused = queue.PriorityQueue()
        nodePar = {}
        path = []
        self.G.graph.get(id1).Weight = 0.0
        unused.put(self.G.graph.get(id1))

        while not unused.empty():

            t = unused.get()
            if t.id == id2:
                break
            if t.id in used:
                continue
            used.append(t.id)
            for Nei in self.G.all_out_edges_of_node(t.id):

                tempNeiDis = self.G.graph.get(Nei).Weight  # nodeDis.get(Nei)
                tDis = self.G.graph.get(t.id).Weight
                EdgeDis = self.G.oute.get(t.id).get(Nei)

                if tempNeiDis > (tDis + EdgeDis):
                    self.G.graph.get(Nei).Weight = tDis + EdgeDis
                    unused.put(self.G.graph.get(Nei))
                    nodePar[Nei] = t

        if self.G.graph.get(id2).Weight == math.inf:
            self.reset_w()
            return math.inf, path

        pointernode = self.G.graph.get(id2)
        path.append(pointernode.id)
        while pointernode.id is not id1:
            pointernode = nodePar.get(pointernode.id)
            path.append(pointernode.id)
        path.reverse()
        res = self.G.graph.get(id2).Weight
        self.reset_w()
        return res, path

    def connected_component(self, id1: int) -> list:
        """returns the Strongly Connected Component(SCC) that node id1 is a part of by
        creating to sets the first one will be filled with the nodes ids that he can get to
        the second one will be filled with the nodes that can get to him then well return the
        intersection of those two lists"""
        if id1 not in self.G.get_all_v():
            return []
        connected1 = set()
        connected_to = []
        connected_from = []

        connected1.add(id1)

        while len(connected1) > 0:
            for node in self.G.all_out_edges_of_node(connected1.pop()):

                if self.G.graph.get(node).Weight == math.inf:
                    self.G.graph.get(node).Weight = 0
                    connected1.add(node)
                    connected_to.append(node)

        connected1.add(id1)

        while len(connected1) > 0:
            for node in self.G.all_in_edges_of_node(connected1.pop()):
                if self.G.graph.get(node).Tag == -1:
                    self.G.graph.get(node).Tag = 0
                    connected1.add(node)
                    connected_from.append(node)

        res = list(set(connected_from).intersection(connected_to))
        for node in self.G.get_all_v().values():
            node.Weight = math.inf
            node.Tag = -1
        if len(res) == 0:
            res.append(id1)
        return res

    def connected_components(self) -> List[list]:
        """returns all the Strongly Connected Component(SCC) in the graph.
        returns by creating a set of all the nodes keys and every time send the first
        node on this list to connected_component(node id) and save that list in a list of lists
        then removing all the nodes that are in that list from the sets of all nodes and sends the next one
        untill the set of all nodes is empty and we have list of lists of the strongly connected component in the graph."""
        all_nodes = set(self.G.get_all_v().keys())
        res = []
        if len(all_nodes) == 0:
            return res
        while len(all_nodes) > 0:
            list1 = self.connected_component(all_nodes.pop())
            res.append(list1)

            all_nodes = all_nodes - (set(list1))
        return res

    def plot_graph(self) -> None:
        """this function draws the graph by using mat_plot_lib
        we add every node by his pos and every edge by it src and dest(we draw a line between them)"""
        x = [i.pos[0] for i in self.G.get_all_v().values()]
        y = [i.pos[1] for i in self.G.get_all_v().values()]
        plt.plot(x, y, "o")
        for i in self.G.get_all_v().values():
            for j in self.G.all_out_edges_of_node(i.id):
                x1 = i.pos[0]
                y1 = i.pos[1]
                x2 = self.G.graph[j].pos[0]
                y2 = self.G.graph[j].pos[1]
                plt.annotate("",
                             xy=(x1, y1),
                             xytext=(x2, y2),
                             arrowprops=dict(arrowstyle="->"))

        plt.show()

    def reset_w(self):
        """resets all the nodes weight to inf"""
        for node in self.G.get_all_v().values():
            node.Weight = math.inf