Esempio n. 1
0
 def __init__(self):
     self.graph = Graph()
     self.pages = []
Esempio n. 2
0

# TODO
# https://www.geeksforgeeks.org/detect-cycle-in-an-undirected-graph-using-bfs/
def detect_cycle_using_BFS(graph: Graph[T]) -> Tuple[bool, List[Vertex[T]]]:
    pass


# TODO
# https://www.geeksforgeeks.org/detect-cycle-in-the-graph-using-degrees-of-nodes-of-graph/?ref=rp
def detct_cycle_using_degree(graph: Graph[T]) -> bool:
    pass


if __name__ == '__main__':
    graph1: Graph[str] = Graph()
    graph1.add_edge('A', 'B', reverse=False)
    graph1.add_edge('B', 'C', reverse=False)
    graph1.add_edge('C', 'D', reverse=False)

    print('Graph:')
    print(graph1, '\n')

    # (B-->A, A-->C, B-->C, C-->A, A-->B, C-->B)
    print("All edges:", graph1.edges)

    # (B---A, A---C, B---C)
    print("Undirected/unique edges:", graph1.undirected_edges)

    has_cycle = detect_cycle_using_disjoint_set(graph1)
    print("\nUsing Disjoint set - " +
Esempio n. 3
0
    # We could randomly start from any vertex and all __DFS__(random_vertex, visited) only once. But then, if graph
    # would be disconnected then, we might miss a few vertex while traversing the graph.
    for data, ver in all_data_vertex_mapping.items():
        if not visited.get(data, False):
            __DFS__(ver)
    return dfs


if __name__ == '__main__':
    # a -- b             x
    # |    |  \        /   \
    # |    |   e      y     z
    # |    |  /
    # c -- d

    graph1 = Graph()
    graph1.add_edge('a', 'b', is_directed=False)
    graph1.add_edge('b', 'e', is_directed=False)
    graph1.add_edge('b', 'd', is_directed=False)
    graph1.add_edge('e', 'd', is_directed=False)
    graph1.add_edge('d', 'c', is_directed=False)
    graph1.add_edge('c', 'a', is_directed=False)
    graph1.add_edge('x', 'y', is_directed=False)
    graph1.add_edge('x', 'z', is_directed=False)

    print(graph1)
    bfs_arr = BFS(graph1)
    # [b, a, e, d, c, x, z, y]
    print("\nBFS:", bfs_arr)

    dfs_arr = DFS_recursive(graph1)
    is_acyclic, top_order = topological_sort_using_BFS(graph)
    return not is_acyclic


if __name__ == '__main__':
    #
    #    ⟶ B ⟶ D ⟵ F
    #   |    |     |    |
    #   A    ⭣    ⭣    ⭣
    #   ⭡___ C ⟶ E     G
    #

    # A - C - B - A
    # C - B - A - C

    graph1 = Graph()
    graph1.add_edge('A', 'B', is_directed=True)
    graph1.add_edge(
        'B', 'C',
        is_directed=True)  # Replace edge B -> C to B -> G it to remove cycle.
    # graph1.add_edge('B', 'G', is_directed=True)
    graph1.add_edge('B', 'D', is_directed=True)
    graph1.add_edge('C', 'A', is_directed=True)
    graph1.add_edge('C', 'E', is_directed=True)
    graph1.add_edge('D', 'E', is_directed=True)
    graph1.add_edge('F', 'D', is_directed=True)
    graph1.add_edge('F', 'G', is_directed=True)

    # A: A-->B
    # B: B-->D, B-->C
    # C: C-->E, C-->A
Esempio n. 5
0
 def __init__(self):
     self.trie = Trie()      # Only change Trie <-> Trie2 here to test the other class
     self.graph = Graph()
     self.pages = []
     self.dict = {}      # Dictionary is used to keep record of pages, in the format <PageNumber>:<PageName>
     self.files = []
    def test_find_love(self):
        '''
        Función encargada de probar la función find love.
        :return:
        '''
        # Primer test
        start, goal = 0, 4
        arcs = [(0, 1), (0, 2), (0, 3), (3, 4)]

        g = Graph(goal + 1)
        for arc in arcs:
            g.add_edge(arc[0], arc[1])
        self.assertEqual(g.find_love(start, goal), (2, ['3', '4']))

        # Segundo test
        start, goal = 0, 9
        arcs = [(0, 1), (0, 2), (0, 3), (1, 5), (2, 4), (3, 7), (4, 9), (5, 6),
                (7, 8), (6, 9), (8, 9)]

        g = Graph(goal + 1)
        for arc in arcs:
            g.add_edge(arc[0], arc[1])
        self.assertEqual(g.find_love(start, goal), (3, ['2', '4', '9']))

        # Tercer test
        start, goal = 0, 4
        arcs = [(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 4)]

        g = Graph(goal + 1)
        for arc in arcs:
            g.add_edge(arc[0], arc[1])
        self.assertEqual(g.find_love(start, goal), (2, ['2', '4']))
        for neighbor in current_vert.get_neighbors():
            # print(current_vert, neighbor)
            if queue.contains(neighbor.key):
                new_dist = current_vert.dist + current_vert.get_weight(neighbor)
                # print(new_dist, 'new dist')
                if new_dist < neighbor.dist:
                    neighbor.dist = new_dist
                    neighbor.predecessor = current_vert
                    # print(neighbor.predecessor)
                    #  The problem is herede
                    # queue.percolate_up(neighbor.key, queue.node_position[neighbor.key])
                    queue.percolate_up(queue.node_position[neighbor.key], neighbor.key)



g = Graph()
a = ['A', 'B', 'C', 'D', 'E']
for key in a:
    g.add_vertex(key)

g.add_edge('A', 'B', 3)
g.add_edge('B', 'A', 3)
g.add_edge('A', 'C', 2)
g.add_edge('C', 'A', 2)
g.add_edge('A', 'E', 4)
g.add_edge('E', 'A', 4)
g.add_edge('B', 'C', 8)
g.add_edge('C', 'B', 8)
g.add_edge('E', 'D', 3)
g.add_edge('D', 'E', 3)
g.add_edge('D', 'C', 1)
Esempio n. 8
0
# Encoding: UTF-8
"""
Run Graph program from CLI
Usage : python run.py {start_node} {end_node} {path/to/csv}
"""

from Graph.graph import Graph
from Converter.csv_converter import CsvConverter
import pprint
import argparse

# Get arg from CLI
argparser = argparse.ArgumentParser(description="Run Graph program from CLI")
argparser.add_argument('start_node', help="The start node for pathfinding")
argparser.add_argument('end_node', help="The end node for pathfinding")
argparser.add_argument('csv_file', help="csv file representing graph as : ['source', 'target', 'cost']")
args = argparser.parse_args()

graph = Graph()
graph.set_converter(CsvConverter())
graph.convert(args.csv_file)
print "Graph loaded :"
graph.print_graph()
path = graph.find_path(args.start_node, args.end_node)
pprint.pprint("A path exists from %s to %s" % (args.start_node, args.end_node))
pprint.pprint(path)
shortest_path = graph.djikstra(args.start_node, args.end_node)
print "And the minimum cost path is :"
pprint.pprint(shortest_path)
Esempio n. 9
0
class GraphApi(Resource):
    def __init__(self):
        # Arcos
        self._arcs = []

        # Nodo inicial
        self._start = None

        # Nodo final
        self._goal = None

        # Instancia de la clase 'Graph'
        self._g_instance = None

        # Mensaje de respuesta al usuario
        self._data = None

    # Getters y setters
    @property
    def arcs(self):
        '''
        Getter de la variable 'arcs'.
        :return: La variable 'arcs'
        '''
        return self._arcs

    @arcs.setter
    def arcs(self, arcs):
        '''
            Setter de la variable 'arcs'.
            :return: None
        '''
        self._arcs = arcs

    @property
    def start(self):
        '''
            Getter de la variable 'start'.
            :return: La variable 'start'
        '''
        return self._start

    @start.setter
    def start(self, start):
        '''
            Setter de la variable 'start'.
            :return: None
        '''
        self._start = start

    @property
    def goal(self):
        '''
            Getter de la variable 'goal'.
            :return: La variable 'goal'
        '''
        return self._goal

    @goal.setter
    def goal(self, goal):
        '''
            Setter de la variable 'goal'.
            :return: None
        '''
        self._goal = goal

    @property
    def g_instance(self):
        '''
            Getter de la variable 'g_instance'.
            :return: La variable 'g_instance'
        '''
        return self._g_instance

    @g_instance.setter
    def g_instance(self, g_instance):
        '''
            Setter de la variable 'g_instance'.
            :return: None
        '''
        self._g_instance = g_instance

    @property
    def data(self):
        '''
            Getter de la variable 'data'.
            :return: La variable 'data'
        '''
        return self._data

    @data.setter
    def data(self, data):
        '''
            Setter de la variable 'data'.
            :return: None
        '''
        self._data = data

    def get(self):
        '''
        Función que devuelve la lista de arcos del árbol (si la hay) al hacer
        una petición GET al endpoint '/graph'.
        :return: Un JSON con los arcos del grafo.
        '''

        return {"data": "Graph API working..."}

    def put(self):
        '''
        Función encargada de recibir los datos necesarios para crear un grafo.
        Los recibe en formato JSON cuando se hace una petición PUT al endpoint.
        :return: Una tupla de la forma (num_personas_necesarias, [lista_de_personas_necesarias])
        '''
        # Verificamos que cumpla con los datos que necesitamos
        args = graph_put_args.parse_args()

        # Función encargada de tratar la entrada
        self.clean_data(args)

        # Iniciamos el grafo
        self.start_graph()

        # Le damos formato al JSON de respuesta
        self.data = {"distance": self.data[0], "nodes": self.data[1]}

        return self.data, 201

    def clean_data(self, args):
        # Guardamos el inicio y el objetivo
        self.start = args['start']
        self.goal = args['goal']

        # Separamos los arcos por parejas
        edges = args['edges'].split(',')

        # Separamos cada pareja
        edges = [tuple(map(int, edge.split('-'))) for edge in edges]

        # Guardamos los arcos en su variable respectiva
        self.arcs = edges

        # Modificamos la variable global
        for el in self.arcs:
            temp_graph.append(el)

    def delete(self):
        temp_graph.clear()
        return {"message": "Arcos borrados satisfactoriamente"}

    def are_arcs_empty(self):
        if len(temp_graph) == 0:
            abort(404, message="No se puede consultar un grafo sin nodos")

    def start_graph(self):
        self.g_instance = Graph(self.goal + 1)

        # Agregamos los arcos al grafo
        for pair in self.arcs:
            self.g_instance.add_edge(pair[0], pair[1])

        # Buscamos la cantidad de personas necesarias para llegar de 'start' a 'goal'
        self.data = self.g_instance.find_love(self.start, self.goal)
Esempio n. 10
0
        head_node = head_node.next_element

    # remove the node from the recursive call
    rec_node_stack[node] = False
    return False


# g1 = Graph(4)
# g1.add_edge(0, 1)
# g1.add_edge(1, 2)
# g1.add_edge(1, 3)
# g1.add_edge(3, 0)
#
# g2 = Graph(3)
# g2.add_edge(0, 1)
# g2.add_edge(1, 2)

g3 = Graph(10)
g3.add_edge(0, 1)
g3.add_edge(0, 2)
g3.add_edge(1, 4)
g3.add_edge(1, 5)
g3.add_edge(2, 6)
g3.add_edge(2, 7)
g3.add_edge(3, 8)
g3.add_edge(3, 9)
g3.add_edge(9, 0)

# print(detect_cycle(g1))
# print(detect_cycle(g2))
print(detect_cycle(g3))
Esempio n. 11
0
    while not queue.is_empty():
        # Dequeue a vertex/node from queue and add it to result
        current_node = queue.dequeue()
        result += str(current_node)
        # Get adjacent vertices to the current_node from the list,
        # and if they are not already visited then enqueue them in the Q
        temp = g.array[current_node].head_node
        while temp is not None:
            if not visited[temp.data]:
                queue.enqueue(temp.data)
                visited[temp.data] = True  # Visit the current Node
            temp = temp.next_element
    return result


g = Graph(7)
g.add_edge(1, 2)
g.add_edge(1, 3)
g.add_edge(2, 4)
g.add_edge(2, 5)
g.add_edge(3, 6)
print(bfs_traversal(g, 1))
# g = Graph(6)
#
# num_of_vertices = g.vertices
#
# if num_of_vertices == 0:
#     print("Graph is empty")
# else:
#     g.add_edge(0, 1)
#     g.add_edge(0, 2)
Esempio n. 12
0
            return True

        # Continue BFS by obtaining first element in linked list
        adjacent = g.array[node].head_node
        while adjacent:
            # enqueue adjacent node if it has not been visited
            if visited[adjacent.data] is False:
                queue.enqueue(adjacent.data)
                visited[adjacent.data] = True
            adjacent = adjacent.next_element

    # Destination was not found in the search
    return False


g1 = Graph(9)
g1.add_edge(0, 2)
g1.add_edge(0, 5)
g1.add_edge(2, 3)
g1.add_edge(2, 4)
g1.add_edge(5, 3)
g1.add_edge(5, 6)
g1.add_edge(3, 6)
g1.add_edge(6, 7)
g1.add_edge(6, 8)
g1.add_edge(6, 4)
g1.add_edge(7, 8)

g2 = Graph(4)
g2.add_edge(0, 1)
g2.add_edge(1, 2)
Esempio n. 13
0
def check_cycle(g, node, visited, parent):
    # Mark node as visited
    visited[node] = True

    # Pick adjacent node and run recursive DFS
    adjacent = g.array[node].head_node
    while adjacent:
        if visited[adjacent.data] is False:
            if check_cycle(g, adjacent.data, visited, node) is True:
                return True

        # If adjacent is visited and not the parent node of the current node
        elif adjacent.data is not parent:
            # Cycle found
            return True
        adjacent = adjacent.next_element

    return False


g = Graph(5)
g.add_edge(0, 1)
g.add_edge(0, 2)
g.add_edge(0, 3)
g.add_edge(3, 4)
g.add_edge(1, 0)
g.add_edge(2, 0)
g.add_edge(3, 0)
g.add_edge(4, 3)

print(is_tree(g))
Esempio n. 14
0
# References:
# https://www.geeksforgeeks.org/kruskals-algorithm-simple-implementation-for-adjacency-matrix/?ref=rp

if __name__ == '__main__':
    #
    #       1     6
    #   A ---- D ---- E
    #   |     /|     /|
    # 3 |  3/  |1  /5 | 2
    #   | /    | /    |
    #   B ---- C ---- F
    #      1      4
    #

    graph: Graph[T] = Graph()
    graph.add_edge('A', 'B', weight=3, reverse=False)
    graph.add_edge('A', 'D', weight=1, reverse=False)
    graph.add_edge('B', 'C', weight=1, reverse=False)
    graph.add_edge('B', 'D', weight=3, reverse=False)
    graph.add_edge('C', 'D', weight=1, reverse=False)
    graph.add_edge('C', 'E', weight=5, reverse=False)
    graph.add_edge('C', 'F', weight=4, reverse=False)
    graph.add_edge('D', 'E', weight=6, reverse=False)
    graph.add_edge('E', 'F', weight=2, reverse=False)

    print("Adjacency list:")
    # A: A--(3)-->B, A--(1)-->D
    # B: B--(3)-->D, B--(1)-->C
    # C: C--(1)-->D, C--(4)-->F, C--(5)-->E
    # D: D--(6)-->E
Esempio n. 15
0
class HtmlLoader(object):
    """
        Class which is in charge of everything data-wise. Within its fields, it holds the Trie structure,
        Graph and a dictionary with every page name linked to a certain page number (later used as ID).
    """

    def __init__(self):
        self.trie = Trie()      # Only change Trie <-> Trie2 here to test the other class
        self.graph = Graph()
        self.pages = []
        self.dict = {}      # Dictionary is used to keep record of pages, in the format <PageNumber>:<PageName>
        self.files = []

    def loadTrieViaHTML(self, path):
        """
            Collects all the '.html' files from the given path and its subfolders into a list. Then proceeds to
            call Parser.parse() for each file in the list. Words from every file are then inserted into the Trie
            structure. After filling the Trie, it creates the Graph structure.
        """
        parser = Parser()

        start = time.time()
        """
            By using 'self.getAllFiles(path), we collect the absolute paths for every '.html' file in the given
            directory. Paths are kept within the list 'self.files'. 
            Using a for loop and a parser, we iterate through the list, and parse every file, add its words
            to the Trie structure, and subsequently build a Graph.
        """

        page_counter = -1
        self.getHtmlFiles(path)

        for file in self.files:
            page_counter += 1
            self.dict[page_counter] = file

            parser.parse(file)                      # Parse the page at the given path

            page = Page(file, parser.links, len(parser.words))         # Create a new Page object to be used for Graphing
            self.pages.append(page)

            for word in parser.words:                   # Insert every word from the page into Trie
                self.trie.insertWord(word, page_counter)

        " Graph creation below: "
        " Creating a Vertex for every page "
        for page in self.pages:
            self.graph.insert_vertex(Graph.Vertex(page.path))

        " Adding edges for every link between pages "
        for page in self.pages:
            for link in page.links:
                self.graph.insert_edge(Graph.Vertex(page.path), Graph.Vertex(link))

        end = time.time()
        print("Parsed files, loaded Trie and formed a Graph in  " + str((end - start).__round__(2)) + " seconds.")


    " Returns a page name corresponding to the page number which is passed as a parameter. "
    def getPageName(self, pageNum):
        return self.dict.get(pageNum)

    " Return a corresponding page number for a given page name. "
    def getPageNum(self, pageName):
        for key in self.dict.keys():
            if self.dict[key] == pageName:
                return key
        return -1

    " Iterates through all the files and subfolders in the given path folder, and adds .html file names to self.files "
    def getHtmlFiles(self, path):
        for file in os.scandir(path):
            filepath = file.path
            if file.name.endswith('html'):
                self.files.append(filepath)
            elif file.is_dir():
                self.getHtmlFiles(filepath)
Esempio n. 16
0
def num_edges(g):
    # For undirected graph, just sum up the size of
    # all the adjacency lists for each vertex
    sum_ = 0
    for i in range(g.vertices):
        temp = g.array[i].head_node
        while temp is not None:
            sum_ += 1
            temp = temp.next_element

    # Half the total sum as it is an undirected graph
    return sum_ // 2


g = Graph(9)
g.add_edge(0, 2)
g.add_edge(0, 5)
g.add_edge(2, 3)
g.add_edge(2, 4)
g.add_edge(5, 3)
g.add_edge(5, 6)
g.add_edge(3, 6)
g.add_edge(6, 7)
g.add_edge(6, 8)
g.add_edge(6, 4)
g.add_edge(7, 8)

g.add_edge(2, 0)
g.add_edge(5, 0)
g.add_edge(3, 2)
Esempio n. 17
0
def main():
    g = Graph(int(input("Enter Number Of Nodes of Your Graph: ")))
    g.create_graph_with_edges(int(
        input("Enter The Number Of Edges : ")))  # Take The Graph Input
    g.sort_edges_by_value()  # Sort The Edges By Weight
    krushkal_algo(g)