Exemplo n.º 1
0
    def genericSearch(self, rootId):
        """
        Execute a generic search in the graph starting from the specified node.
        :param rootId: the root node ID (integer).
        :return: the generic exploration tree.
        """
        if rootId not in self.nodes:
            return None

        treeNode = TreeNode(rootId)
        tree = Tree(treeNode)
        vertexSet = {treeNode}  # nodes to explore
        markedNodes = {rootId}  # nodes already explored

        while len(vertexSet) > 0:  # while there are nodes to explore ...
            treeNode = vertexSet.pop()  # get an unexplored node
            adjacentNodes = self.getAdj(treeNode.info)
            for nodeIndex in adjacentNodes:
                if nodeIndex not in markedNodes:  # if not explored ...
                    newTreeNode = TreeNode(nodeIndex)
                    newTreeNode.father = treeNode
                    treeNode.sons.append(newTreeNode)
                    vertexSet.add(newTreeNode)
                    markedNodes.add(nodeIndex)  # mark as explored
        return tree
Exemplo n.º 2
0
    def visitaInPriorita3(self, rootId):
        """
        Execute a priority search in the graph starting from the specified node.
        :param rootId: the root node ID (integer).
        :return: the generic exploration tree.
        """

        if rootId not in self.nodes:
            return None
        treeNode = TreeNode(rootId)
        tree = Tree(treeNode)
        markedNodes = {rootId}  # nodes already explored
        cod = p3()
        nodeIndex = rootId
        cod.insert(nodeIndex, 0)

        while cod.heap:  # while there are nodes to explore ...
            treeNode = TreeNode(cod.findMax())  # get an unexplored node
            adjacentNodes = self.getAdj(treeNode.info)
            for nodeIndex in adjacentNodes:
                if nodeIndex not in markedNodes:  # if not explored ...
                    newTreeNode = TreeNode(nodeIndex)
                    newTreeNode.father = treeNode
                    treeNode.sons.append(newTreeNode)
                    cod.insert(
                        nodeIndex,
                        self.nodeWeight(treeNode, self.nodes[nodeIndex]))
                markedNodes.add(nodeIndex)

        return tree
Exemplo n.º 3
0
def prim(graph):
    """
    Prim's algorithm is a greedy algorithm for the computation of the
    Minimum Spanning Tree (MST).
    The algorithm assumes a graph implemented as incidence list.
    This implementation leverages the BinaryTree and PriorityQueue data
    structures.
    ---
    Time Complexity: O(|E|*log(|V|)
    Memory Complexity: O()

    :param graph: the graph.
    :return the MST, represented as a tree.
    """
    # initialize the root
    root = 0

    # initialize the tree
    tree = Tree(TreeNode(root))  # MST as a tree
    mstNodes = {root}

    # initialize weights
    currentWeight = len(graph.nodes) * [INFINITE]
    currentWeight[root] = 0
    mstWeight = 0

    # initialize the frontier (priority-queue)
    pq = PriorityQueue()
    pq.insert((root, Edge(root, root, 0)), 0)

    # while the frontier is not empty ...
    while not pq.isEmpty():
        # pop from the priority queue the node u with the minimum weight
        pq_elem = pq.popMin()
        node = pq_elem[0]
        # if node not yet in MST, update the tree
        if node not in mstNodes:
            edge = pq_elem[1]
            treeNode = TreeNode(node)
            treeFather = tree.foundNodeByElem(edge.tail)
            treeFather.sons.append(treeNode)
            treeNode.father = treeFather
            mstNodes.add(node)
            mstWeight += edge.weight

        # for every edge (u,v) ...
        curr = graph.inc[node].getFirstRecord()
        while curr is not None:
            edge = curr.elem
            head = edge.head  # the head node of the edge
            # if node v not yet added into the tree, push it into the priority
            # queue and apply the relaxation step
            if head not in mstNodes:
                weight = edge.weight
                pq.insert((head, edge), weight)
                currWeight = currentWeight[head]
                # relaxation step
                if currWeight == INFINITE:
                    currentWeight[head] = weight
                elif weight < currWeight:
                    currentWeight[head] = weight
            curr = curr.next

    return mstWeight, tree
def Dijkstra(graph, root):
    """
    Dijkstra's algorithm for the computation of the shortest path.
    The algorithm assumes a graph implemented as incidence list.
    This implementation leverages the BinaryTree and PriorityQueue data
    structures.
    ---
    Time Complexity: O(|E|*log(|V|))
    Memory Complexity: O()

    :param graph: the graph.
    :param root: the root node to start from.
    :return: the shortest path.
    """
    n = len(graph.nodes)

    # initialize weights:
    # d[i] = inf for every i in E
    # d[i] = 0, if i == root
    currentWeight = n * [INFINITE]
    currentWeight[root] = 0

    # initialize the tree
    tree = Tree(TreeNode(root))
    mstNodes = {root}
    mstWeight = 0

    # initialize the frontier (priority queue)
    pq = PriorityQueue()
    pq.insert((root, Edge(root, root, 0)), 0)

    # while the frontier is not empty ...
    while not pq.isEmpty():
        # pop from the priority queue the node u with the minimum weight
        pq_elem = pq.popMin()
        node = pq_elem[0]
        # if node not yet in the tree, update the tree
        if node not in mstNodes:
            edge = pq_elem[1]
            treeNode = TreeNode(node)
            father = tree.foundNodeByElem(edge.tail)
            father.sons.append(treeNode)
            treeNode.father = father
            mstNodes.add(node)
            mstWeight += edge.weight

        # for every edge (u,v) ...
        curr = graph.inc[node].getFirstRecord()
        while curr is not None:
            edge = curr.elem
            head = edge.head  # the head node of the edge
            # if node v not yet added into the tree, push it into the priority
            # queue and apply the relaxation step
            if head not in mstNodes:
                tail = edge.tail
                weight = edge.weight
                currWeight = currentWeight[head]
                distTail = currentWeight[tail]
                pq.insert((head, edge), distTail + weight)
                # relaxation step
                if currWeight == INFINITE:
                    currentWeight[head] = distTail + weight
                elif distTail + weight < currWeight:
                    currentWeight[head] = distTail + weight
            curr = curr.next

    return currentWeight