def prim(graph): """Algoritmo di Prim per la ricerca del minimo albero ricoprente. Variante che utilizza un albero binario per la gestione della frontiera tramite coda con priorita'. """ n = len(graph.nodes) currentWeight = n * [INFINITE] #imposta il peso degli archi a infinito pq = PriorityQueue() #rappresenta la frontiera dell'albero generato root = 0 #scelgo arbitrariamente il nodo 0 come radice currentWeight[root] = 0 mstNodes = set() #insieme dei nodi correnti inclusi nella soluzione #inizializzazione dell'albero treeNode = TreeArrayListNode(root) tree = TreeMod(treeNode) mstNodes.add(root) #inizializzazione pq pq.insert((root, Edge(root, root, 0)), 0) #triviale mstWeight = 0 while not pq.isEmpty(): vertex = pq.findMin() pq.deleteMin() if (vertex[0]) not in mstNodes: #nodo non ancora aggiunto al mst #aggiornare albero e peso mst connectingEdge = vertex[1] treeNode = TreeArrayListNode(vertex[0]) father = tree.foundNodeByElem(connectingEdge.tail) father.sons.append(treeNode) treeNode.father = father mstNodes.add(vertex[0]) mstWeight += connectingEdge.weight #print(currentWeight) currNode = graph.inc[vertex[0]].getFirstRecord() while currNode != None: #scorre tutti gli archi incidenti #semplici variabili per semplificare il codice edge = currNode.elem head = edge.head tail = edge.tail weight = edge.weight currWeight = currentWeight[head] if head not in mstNodes: #inserisco solo i nodi che portano #verso vertici non ancora scelti pq.insert((head, edge), weight) if currWeight == INFINITE: currentWeight[head] = weight elif weight < currWeight: currentWeight[head] = weight currNode = currNode.next return mstWeight, tree
def Dijkstra(graph, root): n = len(graph.nodes) currentWeight = n * [INFINITE] #imposta il peso degli archi a infinito pq = PriorityQueue() #rappresenta la frontiera dell'albero generato currentWeight[root] = 0 mstNodes = set() #insieme dei nodi correnti inclusi nella soluzione #inizializzazione dell'albero treeNode = TreeArrayListNode(root) tree = TreeMod(treeNode) mstNodes.add(root) #inizializzazione pq pq.insert((root, Edge(root, root, 0)), 0) #triviale mstWeight = 0 while not pq.isEmpty(): vertex = pq.findMin() pq.deleteMin() if (vertex[0]) not in mstNodes: #nodo non ancora aggiunto #aggiornare albero e peso mst connectingEdge = vertex[1] treeNode = TreeArrayListNode(vertex[0]) father = tree.foundNodeByElem(connectingEdge.tail) father.sons.append(treeNode) treeNode.father = father mstNodes.add(vertex[0]) mstWeight += connectingEdge.weight #print(currentWeight) currNode = graph.inc[vertex[0]].getFirstRecord() while currNode != None: #scorre tutti gli archi incidenti #semplici variabili per semplificare il codice edge = currNode.elem head = edge.head tail = edge.tail weight = edge.weight currWeight = currentWeight[head] distTail = currentWeight[tail] if head not in mstNodes: #inserisco solo i nodi che portano #verso vertici non ancora scelti pq.insert((head, edge), distTail + weight) if currWeight == INFINITE: currentWeight[head] = distTail + weight elif distTail + weight < currWeight: currentWeight[head] = distTail + weight currNode = currNode.next return currentWeight
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(|E|) :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 mst_nodes = {root} # nodes added to MST # initialize weights current_weight = len(graph.nodes) * [INFINITE] current_weight[root] = 0 mst_weight = 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 u not yet in MST, update the tree if node not in mst_nodes: edge = pq_elem[1] tree_node = TreeNode(node) tree_father = tree.foundNodeByElem(edge.tail) tree_father.sons.append(tree_node) tree_node.father = tree_father mst_nodes.add(node) mst_weight += edge.weight # for every edge (u,v) ... curr = graph.inc[node].getFirstRecord() while curr is not None: edge = curr.elem # the edge 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 mst_nodes: weight = edge.weight pq.insert((head, edge), weight) # relaxation step if current_weight[head] > weight: current_weight[head] = weight curr = curr.next return mst_weight, 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 # the edge 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