Ejemplo n.º 1
0
def dorogovtsev_mendes(n, directed=False):
    """
    Create a Dorogovtsev-Mendes graph
    :param n: number of nodes
    :param directed: enable graph directed
    :return: graph created
    """
    # Parameter's validation
    if n < 3:
        raise ValueError("n parameter must to be >= 3 ")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    # Create 3 vertex and 3 edges to form triangle
    for i in range(3):
        g.add_vertex(vertex.Vertex(i))
    for i in range(3):
        j = i + 1 if i < 2 else 0
        g.add_edge(edge.Edge(i, j), directed)

    # To add next vertices one by one, choosing randomly one edge of the grap
    # and create edges between new vertice and origin and source of edge selected
    for i in range(3, n):
        g.add_vertex(vertex.Vertex(i))
        # Select random edge of the graph
        id_edge = randint(0, len(g.get_edges()) - 1)
        edge_selected = g.get_edges()[id_edge]
        (source, target) = edge_selected
        # Create edges between new vertice and origin and source of edge selected
        g.add_edge(edge.Edge(i, source), directed)
        g.add_edge(edge.Edge(i, target), directed)

    return g
Ejemplo n.º 2
0
    def dijkstra_tree(self, s):
        """
        dijkstra_tree is an algorithm for finding tree of cost for each node according Dijkstra's algorithm.
        :param s: node source
        :param t: node target
        :return g graph generated with the shortest path from source to target 
        """
        l = []
        dist = {}
        prev = {}
        discovered = {}
        g = Graph(attr={DIRECTED: True})
        g.add_vertex(vertex.Vertex(s, {"WEIGHT": 0}))
        for v in self.get_vertices():
            dist[v] = float('inf')
            prev[v] = None
            discovered[v] = False
        dist[s] = 0
        l.append((s, dist[s]))
        while len(l) != 0:
            u = min(l, key=lambda x: x[1])
            l.remove(u)
            u = u[0]
            discovered[u] = True
            for v in self.get_adjacent_vertices_by_vertex(u):
                if not discovered[v]:
                    alt = dist[u] + self.get_edge((u, v)).attr["WEIGHT"]
                    if alt < dist[v]:
                        dist[v] = alt
                        prev[v] = u
                        l.append((v, dist[v]))
                        g.add_vertex(vertex.Vertex(v, {"WEIGHT": dist[v]}))
                        g.add_edge(edge.Edge(u, v, {"WEIGHT": dist[v]}))

        return g
Ejemplo n.º 3
0
    def KruskalD(self):
        """
        KruskalD is a function based on Krustal's algorithm to find a minimum spanning forest of an undirected edge-weighted graph. 
        :return g graph representing minimum spannng forest 
        """
        g = Graph(attr={DIRECTED: False})
        # Create set for each v of V[G]
        parent = []
        rank = []
        for v in self.get_vertices():
            parent.append(v)
            rank.append(0)

        # Sort edges by weight
        q = sorted(self.edges.items(), key=lambda e: e[1].attr["WEIGHT"])
        for e in q:
            (u, v) = e[0]
            v1 = self.find(parent, u)
            v2 = self.find(parent, v)
            if v1 != v2:
                g.add_vertex(vertex.Vertex(u))
                g.add_vertex(vertex.Vertex(v))
                g.add_edge(edge.Edge(u, v, {"WEIGHT": e[1].attr["WEIGHT"]}))
                if rank[v1] < rank[v2]:
                    parent[v1] = v2
                    rank[v2] += 1
                else:
                    parent[v2] = v1
                    rank[v1] += 1
        return g
Ejemplo n.º 4
0
 def test_calculate_distance(self):
     v1 = vertex.Vertex(1, {models.COORDINATE_X: 3, models.COORDINATE_Y: 2})
     v2 = vertex.Vertex(2, {models.COORDINATE_X: 9, models.COORDINATE_Y: 7})
     p1 = (v1.attributes[models.COORDINATE_X],
           v1.attributes[models.COORDINATE_Y])
     p2 = (v2.attributes[models.COORDINATE_X],
           v2.attributes[models.COORDINATE_Y])
     models.calculate_distance(p1, p2)
Ejemplo n.º 5
0
 def test_edges(self):
     g = graph.Graph()
     v = vertex.Vertex(1)
     g.add_vertex(v)
     v = vertex.Vertex(2)
     g.add_vertex(v)
     e = edge.Edge(1, 2)
     g.add_edge(e)
     self.assertEqual([(1, 2)], g.get_edges())
Ejemplo n.º 6
0
 def test_add_edge(self):
     g = graph.Graph()
     v1 = vertex.Vertex(1)
     v2 = vertex.Vertex(2)
     g.add_vertex(v1)
     g.add_vertex(v2)
     e = edge.Edge(1, 2)
     g.add_edge(e)
     self.assertEqual(1, len(g.get_edges()))
Ejemplo n.º 7
0
def erdos_rengy(n, m, directed=False, auto=False):
    """
    Creates a graph of n nodes with model Erdos-Renyi
    :param n: number of nodes ( > 0)
    :param m: number of edges ( >= n-1)
    :param directed: enable graph directed
    :param auto: allow auto-cycle (loops)
    :return: Graph created
    """
    # Parameter's validation
    if n <= 0:
        raise ValueError("n parameter must to be > 0 ")
    if m < n - 1:
        raise ValueError("m parameter must to be >= n-1 ")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    for i in range(n):
        g.add_vertex(vertex.Vertex(i))
    edges = {}
    while len(g.edges) != m:
        # Create random m different edges
        source = randint(0, m - 1)
        target = randint(0, m - 1)
        e = (source, target)
        if e not in edges:
            edges[e] = e
            g.add_edge(edge.Edge(source, target), directed, auto)
    return g
Ejemplo n.º 8
0
    def test_prim(self):
        g = graph.Graph()
        for i in range(0, 6):
            v = vertex.Vertex(i)
            g.add_vertex(v)
        e1 = edge.Edge(0, 1, {"WEIGHT": 4})
        g.add_edge(e1)
        e2 = edge.Edge(0, 2, {"WEIGHT": 1})
        g.add_edge(e2)
        e3 = edge.Edge(0, 3, {"WEIGHT": 5})
        g.add_edge(e3)
        e4 = edge.Edge(1, 3, {"WEIGHT": 2})
        g.add_edge(e4)
        e5 = edge.Edge(1, 4, {"WEIGHT": 3})
        g.add_edge(e5)
        e6 = edge.Edge(1, 5, {"WEIGHT": 3})
        g.add_edge(e6)
        e7 = edge.Edge(2, 3, {"WEIGHT": 2})
        g.add_edge(e7)
        e8 = edge.Edge(2, 4, {"WEIGHT": 8})
        g.add_edge(e8)
        e9 = edge.Edge(3, 4, {"WEIGHT": 1})
        g.add_edge(e9)
        e10 = edge.Edge(4, 5, {"WEIGHT": 3})
        g.add_edge(e10)
        primg = g.Prim()
        amount = 0
        for k in primg.edges:
            amount = amount + primg.edges[k].attr["WEIGHT"]

        self.assertEqual(amount, 9)
Ejemplo n.º 9
0
def mesh(m, n, directed=False):
    """
    Creates a graph of m*n nodes
    :param m: number of columns (>1)
    :param n: number of rows (>1)
    :param directed: enable graph directed
    :return: Graph created
    """
    # Parameter's validation
    if m <= 1 or n <= 1:
        raise ValueError("m,n parameters must to be > 1")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    for i in range(m * n):
        v = vertex.Vertex(i)
        g.add_vertex(v)
    index = 0
    for i in range(m):
        for j in range(n):
            if i != (m - 1):
                g.add_edge(edge.Edge(index, (index + n)), directed)
            if j != (n - 1):
                g.add_edge(edge.Edge(index, (index + 1)), directed)
            index = index + 1
    return g
Ejemplo n.º 10
0
def gilbert(n, p, directed=False, auto=False):
    """
    Creates a graph of n nodes with model Gilbert 
    :param n: number of nodes ( > 0)
    :param p: probability to create an edge (0,1)
    :param directed: enable graph directed
    :param auto: allow auto-cycle (loops)
    :return: Graph created
    """
    # Parameter's validation
    if n <= 0:
        raise ValueError("n parameter must to be > 0 ")
    if p <= 0 or p >= 1:
        raise ValueError("p parameter must to be in range (0,1)")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    for i in range(n):
        g.add_vertex(vertex.Vertex(i))
    for i in range(n):
        for j in range(n):
            # Create edge with probability => random number (0,1)
            if random() <= p:
                g.add_edge(edge.Edge(i, j), directed, auto)

    return g
Ejemplo n.º 11
0
 def dijkstra(self, s, t):
     """
     dijkstra is an algorithm for finding the shortest paths between nodes in a graph.
     :param s: node source
     :param t: node target
     :return g graph generated with the shortest path from source to target 
     """
     l = []
     dist = {}
     prev = {}
     discovered = {}
     for v in self.get_vertices():
         dist[v] = float('inf')
         prev[v] = None
         discovered[v] = False
     dist[s] = 0
     l.append((s, dist[s]))
     while len(l) != 0:
         u = min(l, key=lambda x: x[1])
         l.remove(u)
         u = u[0]
         discovered[u] = True
         if u == t:
             break
         for v in self.get_adjacent_vertices_by_vertex(u):
             if not discovered[v]:
                 alt = dist[u] + self.get_edge((u, v)).attr["WEIGHT"]
                 if alt < dist[v]:
                     dist[v] = alt
                     prev[v] = u
                     l.append((v, dist[v]))
     # Create a graph according to visited nodes store in prev array
     u = t
     g = Graph(attr={DIRECTED: True})
     while u is not None:
         g.add_vertex(vertex.Vertex(u, {"WEIGHT": dist[u]}))
         if prev[u] is not None:
             g.add_vertex(vertex.Vertex(prev[u], {"WEIGHT": dist[prev[u]]}))
             g.add_edge(edge.Edge(prev[u], u))
             u = prev[u]
         else:
             break
     return g
Ejemplo n.º 12
0
 def test_get_by_vertex(self):
     g = graph.Graph()
     v = vertex.Vertex(1)
     g.add_vertex(v)
     v = vertex.Vertex(2)
     g.add_vertex(v)
     v = vertex.Vertex(3)
     g.add_vertex(v)
     e = edge.Edge(1, 2)
     g.add_edge(e)
     self.assertEqual([(1, 2)], g.get_edges_by_vertex(1))
     e = edge.Edge(1, 3)
     g.add_edge(e)
     self.assertEqual(2, len(g.get_edges_by_vertex(1)))
     e = edge.Edge(2, 1)
     g.add_edge(e, True)
     self.assertEqual(3, len(g.get_edges_by_vertex(1, 0)))
     self.assertEqual(2, len(g.get_edges_by_vertex(1, 1)))
     self.assertEqual(1, len(g.get_edges_by_vertex(1, 2)))
Ejemplo n.º 13
0
    def test_bfs_simple_10(self):
        g = graph.Graph()
        for i in range(1, 11):
            v = vertex.Vertex(i)
            g.add_vertex(v)
        e = edge.Edge(1, 2)
        g.add_edge(e)
        e = edge.Edge(1, 3)
        g.add_edge(e)
        e = edge.Edge(1, 4)
        g.add_edge(e)
        e = edge.Edge(1, 5)
        g.add_edge(e)
        e = edge.Edge(2, 6)
        g.add_edge(e)
        e = edge.Edge(2, 7)
        g.add_edge(e)
        e = edge.Edge(6, 9)
        g.add_edge(e)
        e = edge.Edge(9, 10)
        g.add_edge(e)
        e = edge.Edge(3, 7)
        g.add_edge(e)
        e = edge.Edge(3, 8)
        g.add_edge(e)
        e = edge.Edge(4, 8)
        g.add_edge(e)
        e = edge.Edge(5, 10)
        g.add_edge(e)
        g2 = g.bfs(1)
        dot = g2.create_graphviz('bfs')
        gbase = '''digraph {
    1 [label=1]
    2 [label=2]
    3 [label=3]
    4 [label=4]
    5 [label=5]
    6 [label=6]
    7 [label=7]
    8 [label=8]
    10 [label=10]
    9 [label=9]
    1 -> 2
    1 -> 3
    1 -> 4
    1 -> 5
    2 -> 6
    2 -> 7
    3 -> 8
    5 -> 10
    6 -> 9
}'''
        # dot.render('bfs',view=True)
        self.assertEqual(gbase, str(dot))
Ejemplo n.º 14
0
    def test_dfs_simple_10(self):
        g = graph.Graph(attr={graph.DIRECTED: True})
        for i in range(1, 11):
            v = vertex.Vertex(i)
            g.add_vertex(v)
        e = edge.Edge(1, 2)
        g.add_edge(e)
        e = edge.Edge(1, 3)
        g.add_edge(e)
        e = edge.Edge(1, 4)
        g.add_edge(e)
        e = edge.Edge(1, 5)
        g.add_edge(e)
        e = edge.Edge(2, 6)
        g.add_edge(e)
        e = edge.Edge(2, 7)
        g.add_edge(e)
        e = edge.Edge(6, 9)
        g.add_edge(e)
        e = edge.Edge(9, 10)
        g.add_edge(e)
        e = edge.Edge(3, 7)
        g.add_edge(e)
        e = edge.Edge(3, 8)
        g.add_edge(e)
        e = edge.Edge(4, 8)
        g.add_edge(e)
        e = edge.Edge(5, 10)
        g.add_edge(e)
        g2 = g.dfs(1)
        dot = g2.create_graphviz('dfs')
        gbase = '''digraph {
    1 [label=1]
    5 [label=5]
    10 [label=10]
    4 [label=4]
    8 [label=8]
    3 [label=3]
    7 [label=7]
    2 [label=2]
    6 [label=6]
    9 [label=9]
    1 -> 5
    5 -> 10
    1 -> 4
    4 -> 8
    1 -> 3
    3 -> 7
    1 -> 2
    2 -> 6
    6 -> 9
}'''
        # dot.render('dfs',view=True)
        self.assertEqual(gbase, str(dot))
Ejemplo n.º 15
0
def barabasi(n, d, directed=False, auto=False):
    """
    Create Barabasi-Albert (BA) graph
    :param n: number of nodes ( > 0)
    :param d: max number of edges of vertex ( > 1)
    :param directed: enable graph directed
    :param auto: allow auto-cycle (loops)
    return: graph created
    """
    # Parameter's validation
    if n <= 0:
        raise ValueError("n parameter must to be > 0 ")
    if d <= 1:
        raise ValueError("d parameter must to be > 1")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    # The first d vertices are created with edges to relate each one with the others
    for i in range(d):
        g.add_vertex(vertex.Vertex(i))
    for i in range(d):
        for j in range(d):
            if len(g.get_edges_by_vertex(i)) < d and len(
                    g.get_edges_by_vertex(j)) < d:
                g.add_edge(edge.Edge(i, j), directed, auto)

    for i in range(d, n):
        g.add_vertex(vertex.Vertex(i))
        for j in range(i):
            # The probability p that the new node i is connected to node j
            # is the grade of vertex j divided by the number of edges of graph
            p = len(g.get_edges_by_vertex(j)) / len(g.get_edges())
            if len(g.get_edges_by_vertex(i)) < d and len(
                    g.get_edges_by_vertex(j)) < d and p >= random():
                g.add_edge(edge.Edge(i, j), directed, auto)
    return g
Ejemplo n.º 16
0
    def test_dfs_r_simple_8(self):
        g = graph.Graph(attr={graph.DIRECTED: True})
        for i in range(1, 9):
            v = vertex.Vertex(i)
            g.add_vertex(v)
        e = edge.Edge(1, 2)
        g.add_edge(e)
        e = edge.Edge(1, 3)
        g.add_edge(e)
        e = edge.Edge(1, 4)
        g.add_edge(e)
        e = edge.Edge(2, 5)
        g.add_edge(e)
        e = edge.Edge(5, 7)
        g.add_edge(e)
        e = edge.Edge(7, 8)
        g.add_edge(e)
        e = edge.Edge(3, 6)
        g.add_edge(e)
        e = edge.Edge(6, 8)
        g.add_edge(e)
        e = edge.Edge(6, 7)
        g.add_edge(e)
        g2 = g.dfs_r(1)
        dot = g2.create_graphviz('dfs')
        print(dot)
        gbase = '''digraph {
    1 [label=1]
    2 [label=2]
    5 [label=5]
    7 [label=7]
    8 [label=8]
    3 [label=3]
    6 [label=6]
    4 [label=4]
    1 -> 2
    2 -> 5
    5 -> 7
    7 -> 8
    1 -> 3
    3 -> 6
    1 -> 4
}'''

        # dot.render('dfs_r',view=True)
        self.assertEqual(gbase, str(dot))
Ejemplo n.º 17
0
    def Prim(self):
        """
        Prim is a function based on  Prim's algorithm to find a minimum spanning forest of an undirected edge-weighted graph. 
        :return g graph representing minimum spannng forest 
        """
        g = Graph(attr={DIRECTED: False})
        distance = [sys.maxsize] * len(self.vertices)
        parent = [None] * len(self.vertices)
        set = [False] * len(self.vertices)

        distance[0] = 0
        parent[0] = -1

        for i in self.vertices:
            # Search vertex with minimum distance
            min_index = 0
            min = sys.maxsize
            for v in self.vertices:
                if distance[v] < min and set[v] is False:
                    min = distance[v]
                    min_index = v
            u = min_index

            # Add u vertex in set to not use it in other iteration 
            set[u] = True
            g.add_vertex(vertex.Vertex(u))

            # Iterate all adjacent vertices of u vertex and update distance 
            for v in self.get_adjacent_vertices_by_vertex(u):
                if set[v] is False and distance[v] > \
                        self.get_edge((u, v)).attr["WEIGHT"]:
                    distance[v] = self.get_edge((u, v)).attr["WEIGHT"]
                    parent[v] = u

        for i in self.vertices:
            if i == 0:
                continue
            if parent[i] is not None:
                g.add_edge(edge.Edge(parent[i], i, {"WEIGHT": self.get_edge((parent[i], i)).attr["WEIGHT"]}))

        return g
Ejemplo n.º 18
0
 def test_dijkstra_simple_3(self):
     g = graph.Graph()
     for i in range(1, 6):
         v = vertex.Vertex(i)
         g.add_vertex(v)
     e = edge.Edge(1, 2, {"WEIGHT": 1})
     g.add_edge(e)
     e = edge.Edge(2, 4, {"WEIGHT": 1})
     g.add_edge(e)
     e = edge.Edge(4, 5, {"WEIGHT": 1})
     g.add_edge(e)
     e = edge.Edge(1, 3, {"WEIGHT": 5})
     g.add_edge(e)
     e = edge.Edge(3, 4, {"WEIGHT": 3})
     g.add_edge(e)
     dot = g.create_graphviz('dijkstra_original_3',
                             attr_label_edge="WEIGHT")
     dot.render('dijkstra_3_original', view=True)
     result = g.dijkstra(1, 5)
     print(result)
     dot = result.create_graphviz('dijkstra_calculado_3', "WEIGHT", 1)
Ejemplo n.º 19
0
def geo_simple(n, r, directed=False, auto=False):
    """
    Create a random graph with simple method geographic
    :param n: number of vertices ( > 0)
    :param r: max distance to generate edge between nodes (0,1)
    :param directed: enable graph directed
    :param auto: allow auto-cycle (loops)
    :return: graph created
    """
    # Parameter's validation
    if n <= 0:
        raise ValueError("n parameter must to be > 0 ")
    if r <= 0 or r >= 1:
        raise ValueError("r parameter must to be in range (0,1)")

    g = graph.Graph()
    # Add attribute DIRECTED in graph
    g.attr[graph.DIRECTED] = directed

    # Create n nodes with uniform coordinates
    for i in range(n):
        g.add_vertex(
            vertex.Vertex(i, {
                COORDINATE_X: random(),
                COORDINATE_Y: random()
            }))

    # Create edge between two vertex if there is a distance <= r
    for i in range(n):
        for j in range(n):
            # Calculate distance between two points
            p1 = (g.get_vertex(i).attributes[COORDINATE_X],
                  g.get_vertex(i).attributes[COORDINATE_Y])
            p2 = (g.get_vertex(j).attributes[COORDINATE_X],
                  g.get_vertex(j).attributes[COORDINATE_Y])
            d = calculate_distance(p1, p2)
            if d <= r:
                g.add_edge(edge.Edge(i, j), directed, auto)
    return g
Ejemplo n.º 20
0
 def test_initialize_vertex(self):
     v = vertex.Vertex(1)
     self.assertEqual(1, v.id)
Ejemplo n.º 21
0
 def test_add_vertice(self):
     g = graph.Graph()
     v = vertex.Vertex(1)
     g.add_vertex(v)
     self.assertEqual(1, len(g.vertices))