Пример #1
0
 def test_get_node(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     self.assertIsNone(g.get_node(8))
     g.remove_node(5)
     self.assertIsNone(g.get_node(5))
     list = [0, 1, 2, 3, 4, 6]
     sec_list = []
     for key in g.get_all_v().values():
         sec_list.append(g.get_node(key.id).id)
     self.assertListEqual(list, sec_list)
Пример #2
0
 def test_remove_node(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     self.assertFalse(g.remove_node(14))
     self.assertTrue(g.remove_node(5))
     self.assertFalse(g.remove_node(5))
     self.assertTrue(g.remove_node(3))
     self.assertEqual(len(g.get_all_v()), 5)
Пример #3
0
 def test_get_all_v(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     dict = g.get_all_v()
     self.assertEqual(len(dict), 7)
     g.remove_node(6)
     dict = g.get_all_v()
     for i in range(6):
         self.assertEqual(dict[i].id, i)
Пример #4
0
 def load_from_json(self, file_name: str):
     if self is None:
         return False
     new_graph = DiGraph()
     try:
         with open(file_name, 'r') as fp:
             jsn = json.load(fp)
         for item in jsn['Nodes']:
             new_graph.add_node(item.get('id'))
             if item.get('pos') is not None:
                 pos = item.get('pos')
                 x, y, z = pos.split(',')
                 x = float(x)
                 y = float(y)
                 z = float(z)
                 new_graph.get_node(item.get('id')).pos = (x, y, z)
         for edge in jsn['Edges']:
             src = edge['src']
             dest = edge['dest']
             w = edge['w']
             new_graph.add_edge(src, dest, w)
         self.g = new_graph
     except:
         print('cant open file')
         return False
     return True
Пример #5
0
 def reverse_graph(self, graph):
     graph2 = DiGraph()
     for node in graph.get_all_v().keys():
         graph2.add_node(node)
     for ver in graph.get_all_v().values():
         for edge in graph.all_out_edges_of_node(ver.id).keys():
             graph2.add_edge(edge, ver.id, 0)
     return graph2
Пример #6
0
 def __init__(self, d_graph=None):
     if d_graph is None:
         self.g = DiGraph()
     else:
         self.g = d_graph
Пример #7
0
class GraphAlgo:

    def __init__(self, d_graph=None):
        if d_graph is None:
            self.g = DiGraph()
        else:
            self.g = d_graph

    # method to return the DiGraph
    def get_graph(self):
        return self.g

    # method which crate a graph from a json format file and then init the graph in the AlgoGraph
    def load_from_json(self, file_name: str):
        if self is None:
            return False
        new_graph = DiGraph()
        try:
            with open(file_name, 'r') as fp:
                jsn = json.load(fp)
            for item in jsn['Nodes']:
                new_graph.add_node(item.get('id'))
                if item.get('pos') is not None:
                    pos = item.get('pos')
                    x, y, z = pos.split(',')
                    x = float(x)
                    y = float(y)
                    z = float(z)
                    new_graph.get_node(item.get('id')).pos = (x, y, z)
            for edge in jsn['Edges']:
                src = edge['src']
                dest = edge['dest']
                w = edge['w']
                new_graph.add_edge(src, dest, w)
            self.g = new_graph
        except:
            print('cant open file')
            return False
        return True

    # method which saves the DiGraph in a json format
    def save_to_json(self, filename):
        if self is None or self.g is None:
            return False
        x = []
        y = []
        try:
            for value in self.g.get_all_v().values():
                if value.pos is None:
                    x.append({"id": value.id})
                else:
                    s, t, u = value.pos
                    str_pos = str(s) + ", " + str(t) + ", " + "0.0"
                    x.append({"id": value.id, "pos": str_pos})
            for value in self.g.get_all_v().values():
                for sec_key, sec_val in self.g.all_out_edges_of_node(value.id).items():
                    y.append({"src": value.id, "dest": sec_key, "w": sec_val})
            w = {}
            w["Nodes"] = x
            w["Edges"] = y
            with open(filename, 'w') as json_file:
                json.dump(w, json_file)
        except:
            print('Eror saving file')
            return False
        return True

    # method to calculate the shortest path between to nodes using Dijikstra algorithm with a priorityqueue
    # that use a comparator of the value W of every node
    # the function retrun a tuple with the lentgh of the path and a list with all the nodes of the shortest path
    # the method also uses the value Tag of node class to check if a node was visited or not
    def shortest_path(self, id1: int, id2: int) -> (float, list):
        if self is None or self.g is None:
            return (float('inf'), [])
        if self.g.get_node(id1) is None or self.g.get_node(id2) is None:
            return (float('inf'), [])
        if id1 == id2:
            return (0, [id1])

        for node in self.g.get_all_v().values():
            node.w = -1
            node.tag = 0
        q = queue.PriorityQueue()
        dict_node = {}
        node = self.g.get_node(id1)
        node.w = 0
        q.put(node)
        while not q.empty():
            node = q.get()
            node.tag = 1
            ni_list = self.g.all_out_edges_of_node(node.id)
            for ni_node in ni_list.keys():
                if self.g.get_node(ni_node).tag == 0:
                    sum = node.w + self.g.get_edge(node.id, ni_node)
                    if sum < self.g.get_node(ni_node).w or self.g.get_node(ni_node).w == -1:
                        self.g.get_node(ni_node).w = sum
                        dict_node[ni_node] = node.id
                        q.put(self.g.get_node(ni_node))
        arr_list = []
        if self.g.get_node(id2).w == -1:
            return (float('inf'), [])
        else:
            prev_node = id2
            arr_list.append(prev_node)
            prev_node = dict_node.get(prev_node)
            while prev_node != id1:
                arr_list.append(prev_node)
                prev_node = dict_node.get(prev_node)
            arr_list.append(id1)
            arr_list.reverse()
        tuple_list = (self.g.get_node(id2).w, arr_list)
        return tuple_list

    # a method that recive a node id and return the biggest strongly component of the node
    # the method use the "naive algorithm" and run a DFS from the given node after that we call
    # the method reverse graph wich revers all the edges then we run again the DFS from tha same node
    # and the nodes which were visited in both of the DFS are the nodes of the scc

    def connected_component(self, id1: int):
        if self.g is None or self.g.get_node(id1) is None:
            return []
        graph = GraphAlgo()
        self.DFS(self.g.get_node(id1))  # first DFS
        graph.g = self.reverse_graph(self.g)
        graph.DFS(graph.g.get_node(id1))  # second dfs over the reverse graph
        list = []
        for node in graph.g.get_all_v().values():
            if node.tag == 1 and self.g.get_node(node.id).tag == 1:  # taking nodes wich were visited in both DFS
                list.append(node.id)
        return list

    # simple method that  reverse the graph the method copy the same nodes but copy the opposite edges
    def reverse_graph(self, graph):
        graph2 = DiGraph()
        for node in graph.get_all_v().keys():
            graph2.add_node(node)
        for ver in graph.get_all_v().values():
            for edge in graph.all_out_edges_of_node(ver.id).keys():
                graph2.add_edge(edge, ver.id, 0)
        return graph2

    # The function to do DFS traversal. iterative DFS using a queue
    def DFS(self, v):
        for node in self.g.get_all_v().values():
            node.tag = 0
        q = queue.LifoQueue(maxsize=0)
        v.tag = 1
        q.put_nowait(v)
        while not q.empty():
            v = q.get()
            for neighbour in self.g.all_out_edges_of_node(v.id).keys():
                if self.g.get_node(neighbour).tag == 0:
                    self.g.get_node(neighbour).tag = 1
                    q.put(self.g.get_node(neighbour))

    def connected_components(self):
        list = []
        for ver in self.g.get_all_v().values():
            ver.w = -1
        for vertex in self.g.get_all_v().values():
            if vertex.w == 1:
                continue
            list2 = self.connected_component(vertex.id)
            for i in list2:
                self.g.get_node(i).w = 1
            list.append(list2)
        return list

    def plot_graph(self):
        x = []
        y = []
        n = []
        max_x = -1000
        min_x = 1000
        max_y = -1000
        min_y = 1000

        for node in self.g.get_all_v().values():
            n.append(node.id)
            if node.pos is None:
                node.pos = (int(random.randrange(0, 100, 3)), int(random.randrange(0, 100, 8)), 0)
            x.append(node.pos[0])
            y.append(node.pos[1])
            if node.pos[0] > max_x:
                max_x = node.pos[0]
            if node.pos[1] > max_y:
                max_y = node.pos[1]
            if node.pos[0] < min_x:
                min_x = node.pos[0]
            if node.pos[1] < min_y:
                min_y = node.pos[1]
        fig, ax = plt.subplots(facecolor=(0.5, 0.8, 0.8))
        ax.scatter(x, y, 100, 'red')
        for ver in self.g.get_all_v().values():  # type Node
            for neighbour in self.g.all_out_edges_of_node(ver.id).keys():
                from_xy = (ver.pos[0], ver.pos[1])
                to_xy = (self.g.get_node(neighbour).pos[0], self.g.get_node(neighbour).pos[1])
                con = ConnectionPatch(from_xy, to_xy, "data", "data",
                                      arrowstyle="-|>", shrinkA=5, shrinkB=5,
                                      mutation_scale=18, fc="orange")
                ax.add_artist(con)
        for i, txt in enumerate(n):
            ax.annotate(txt, (x[i], y[i] + 0.0002))
        ax.text(0.5, 0.5, 'created by aviem and amiel', transform=ax.transAxes,
                fontsize=30, color='gray', alpha=0.5,
                ha='center', va='center', rotation='30')
        plt.axis([min_x - 0.001, max_x + 0.001, min_y - 0.001, max_y + 0.001])
        plt.xlabel('X axis')
        plt.ylabel('Y axis')
        ax.set_facecolor('#eafff5')
        ax.set_title('Directed Weighted Graph')
        plt.show()

    def __str__(self):
        print(self.g)
        return ""
Пример #8
0
 def test_reverse_graph(self):
     g = DiGraph()
     graph = DiGraph()
     for i in range(5):
         g.add_node(i)
         graph.add_node(i)
     g.add_edge(1, 2, 3)
     graph.add_edge(2, 1, 3)
     g.add_edge(0, 4, 3)
     graph.add_edge(4, 0, 3)
     g.add_edge(1, 3, 3)
     graph.add_edge(3, 1, 3)
     g.add_edge(3, 2, 3)
     graph.add_edge(2, 3, 3)
     algo = GraphAlgo(g)
     self.assertNotEqual(algo.g, graph)
     algo.g = algo.reverse_graph(algo.get_graph())
     self.assertEqual(graph, algo.get_graph())
Пример #9
0
 def test_connected_component(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(0, 1, 5)
     g.add_edge(0, 2, 3)
     g.add_edge(0, 1, 5)
     g.add_edge(1, 6, 12.1)
     g.add_edge(2, 3, 2)
     g.add_edge(2, 5, 8)
     g.add_edge(3, 4, 1)
     g.add_edge(4, 5, 4)
     g.add_edge(5, 6, 7)
     g.add_edge(3, 0, 1)
     g.add_edge(1, 3, 5)
     graph = GraphAlgo(g)
     self.assertListEqual(graph.connected_component(0), [0, 1, 2, 3])
     g.remove_edge(1, 3)
     self.assertListEqual(graph.connected_component(0), [0, 2, 3])
     g.add_edge(5, 0, 8)
     self.assertListEqual(graph.connected_component(0), [0, 2, 3, 4, 5])
Пример #10
0
 def test_shortest_path(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(0, 1, 5)
     g.add_edge(0, 2, 3)
     g.add_edge(0, 1, 5)
     g.add_edge(1, 6, 12.1)
     g.add_edge(2, 3, 2)
     g.add_edge(2, 5, 8)
     g.add_edge(3, 4, 1)
     g.add_edge(4, 5, 4)
     g.add_edge(5, 6, 7)
     graph = GraphAlgo(g)
     self.assertTupleEqual(graph.shortest_path(0, 6),
                           (17, [0, 2, 3, 4, 5, 6]))
     graph.g.add_edge(1, 6, 11.9)
     self.assertTupleEqual(graph.shortest_path(0, 6),
                           (17, [0, 2, 3, 4, 5, 6]))
     self.assertTupleEqual(graph.shortest_path(6, 0), (float('inf'), []))
     self.assertTupleEqual(graph.shortest_path(0, 9), (float('inf'), []))
     self.assertTupleEqual(graph.shortest_path(0, 0), (0, [0]))
Пример #11
0
 def test_get_graph(self):
     graph = DiGraph()
     graph.add_node(1)
     g = GraphAlgo(graph)
     self.assertEqual(len(g.get_graph().get_all_v()), 1)
Пример #12
0
 def test_connected_components(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(0, 1, 5)
     g.add_edge(0, 2, 3)
     g.add_edge(0, 1, 5)
     g.add_edge(1, 6, 12.1)
     g.add_edge(2, 3, 2)
     g.add_edge(2, 5, 8)
     g.add_edge(3, 4, 1)
     g.add_edge(4, 5, 4)
     g.add_edge(5, 6, 7)
     g.add_edge(6, 5, 4)
     g.add_edge(3, 0, 1)
     g.add_edge(1, 3, 5)
     graph = GraphAlgo(g)
     self.assertEqual(graph.connected_components(),
                      [[0, 1, 2, 3], [4], [5, 6]])
     graph.g.remove_edge(1, 3)
     self.assertEqual(graph.connected_components(),
                      [[0, 2, 3], [1], [4], [5, 6]])
     graph.get_graph().remove_node(0)
     self.assertEqual(graph.connected_components(),
                      [[1], [2], [3], [4], [5, 6]])
Пример #13
0
 def test_all_out_edges_of_node(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 1, 3)
     g.add_edge(1, 2, 4)
     g.add_edge(1, 6, -8)
     g.add_edge(1, 2, 7)
     g.add_edge(1, 3, 7)
     g.add_edge(1, 4, 4)
     g.add_edge(1, 18, 4)
     g.remove_node(3)
     g.add_edge(1, 6, 3)
     g.remove_edge(1, 6)
     g.add_edge(1, 5, 3)
     self.assertIsNone(g.all_out_edges_of_node(22), None)
     dict = g.all_out_edges_of_node(1)
     list = []
     for key in dict.keys():
         list.append(key)
     sec_list = [2, 4, 5]
     self.assertListEqual(list, sec_list)
Пример #14
0
 def test_add_edge(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 2, 3)
     g.add_edge(1, 2, 3)
     g.add_edge(1, 2, 4)
     self.assertFalse(g.add_edge(1, 87, 3))
     g.add_edge(92, 2, 3)
     self.assertFalse(g.add_edge(1, 5, -3))
     self.assertFalse(g.add_edge(1, 1, 3))
     g.add_edge(4, 5, 3)
     self.assertEqual(g.e_size(), 2)
Пример #15
0
 def test_e_size(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 1, 3)
     g.add_edge(1, 2, 4)
     g.add_edge(1, 6, -8)
     g.add_edge(2, 1, 7)
     g.add_edge(2, 1, 7)
     g.add_edge(5, 2, 4)
     g.add_edge(32, 45, 4)
     g.add_edge(1, 9, 4)
     g.add_edge(1, 2, 3)
     self.assertEqual(g.e_size(), 3)
Пример #16
0
 def test_remove_edge(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     for i in range(4):
         g.add_edge(i, i + 1, 5)
     self.assertFalse(g.remove_edge(1, 6))
     self.assertFalse(g.remove_edge(7, 6))
     g.add_edge(0, 2, 2)
     g.add_edge(0, 3, 2)
     g.add_edge(0, 4, 2)
     g.add_edge(0, 5, 2)
     g.remove_edge(0, 1)
     g.remove_edge(0, 4)
     list = [2, 3, 5]
     sec_list = []
     for key in g.all_out_edges_of_node(0).keys():
         sec_list.append(key)
     self.assertListEqual(sec_list, list)
Пример #17
0
 def test_get_edge(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 1, 3)
     g.add_edge(1, 2, 4)
     g.add_edge(1, 6, -8)
     g.add_edge(2, 1, 7)
     g.add_edge(2, 1, 9)
     g.add_edge(4, 1, 4)
     g.add_edge(32, 1, 4)
     g.add_edge(5, 1, 4)
     g.add_edge(5, 1, 3)
     g.add_edge(3, 1, 3)
     g.remove_node(3)
     g.add_edge(6, 1, 3)
     g.remove_edge(6, 1)
     self.assertIsNone(g.get_edge(6, 1))
     self.assertIsNone(g.get_edge(6, 6))
     self.assertIsNone(g.get_edge(4, 5))
     self.assertIsNone(g.get_edge(3, 9))
     self.assertEqual(g.get_edge(1, 2), 4)
     self.assertEqual(g.get_edge(2, 1), 7)
Пример #18
0
 def test_v_size(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_node(0)
     g.add_node(2)
     g.remove_node(3)
     g.remove_node(3)
     g.remove_node(4)
     self.assertEqual(g.v_size(), 5)
Пример #19
0
 def test_add_node(self):
     g = DiGraph()
     g.add_node(1)
     g.add_node(1)
     g.add_node(2)
     self.assertEqual(2, len(g.get_all_v()))
Пример #20
0
 def test_all_in_edges_of_node(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 1, 3)
     g.add_edge(1, 2, 4)
     g.add_edge(1, 6, -8)
     g.add_edge(2, 1, 7)
     g.add_edge(2, 1, 7)
     g.add_edge(4, 1, 4)
     g.add_edge(32, 1, 4)
     g.add_edge(5, 1, 4)
     g.add_edge(5, 1, 3)
     g.add_edge(3, 1, 3)
     g.remove_node(3)
     g.add_edge(6, 1, 3)
     g.remove_edge(6, 1)
     self.assertIsNone(g.all_in_edges_of_node(22), None)
     dict = g.all_in_edges_of_node(1)
     self.assertEqual(len(dict), 3)
Пример #21
0
 def test_get_mc(self):
     g = DiGraph()
     for i in range(7):
         g.add_node(i)
     g.add_edge(1, 1, 3)
     g.add_edge(1, 2, 4)
     g.add_edge(1, 6, -8)
     g.add_edge(2, 1, 7)
     g.add_edge(2, 1, 7)
     g.add_edge(4, 1, 4)
     g.add_edge(32, 1, 4)
     g.add_edge(5, 1, 4)
     g.add_edge(5, 1, 3)
     g.add_edge(3, 1, 3)
     g.remove_node(3)
     g.add_edge(6, 1, 3)
     g.remove_edge(6, 1)
     self.assertEqual(g.get_mc(), 15)