def prioritySearch_PQbinaryHeap(self): """ This algorithm executes a prioritySearch based on the genericSearch of a graph. It uses a list to represent the visit of the graph and a Binary Heap as priority queue for the nodes to explore. :return: the list of the exploration. """ pq = PQbinaryHeap() exploredNodes = [] enqueuedVertices = [] s = self.maxWeight() ID = s[0] KEY = -(s[1]) pq.insert(ID, KEY) enqueuedVertices.append(ID) while not pq.isEmpty(): u = pq.findMin() pq.deleteMin() exploredNodes.append(u) for ID in self.getAdj(u): node = self.getNode(ID) KEY = -(node.getWeight()) if ID not in enqueuedVertices: pq.insert(ID, KEY) enqueuedVertices.append(ID) return exploredNodes
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 prioritySearchDraw(graph): """ Implementazione modificata di visitaInPriorita' (implementata con binary heap), converte il grafo nella struttura Graph della libreria networkx e crea un set di immagini del grafo, tramite la libreria matplotlib, evidenziando passo passo i nodi visitati. """ edges = graph.getEdges() nodes = graph.getNodes() name = 'graphPictures/figure' name_n = 0 edgeCouples = [] nodesID = [] for edge in edges: edgeCouples.append((edge.head, edge.tail)) for node in nodes: nodesID.append(node.id) G = networkx.Graph() for nodeID in nodesID: G.add_node(nodeID, w=(graph.getNode(0)).getWeight()) G.add_edges_from(edgeCouples) labels = dict.fromkeys(nodesID, 0) for key in labels.keys(): labels[key] = graph.nodes[key].getWeight() pos = networkx.spring_layout(G) networkx.draw_networkx(G, pos, arrows=True, with_labels=True, node_size=500, labels=labels) plt.axis('off') outputName = name + str(name_n) + '.png' plt.savefig(outputName) name_n += 1 pq = PQbinaryHeap() exploredNodes = [] s = graph.maxWeight() ID = s[0] KEY = -(s[1]) pq.insert(ID, KEY) while not pq.isEmpty(): u = pq.findMin() pq.deleteMin() exploredNodes.append(u) networkx.draw_networkx(G, pos, arrows=True, with_labels=True, node_size=500, labels=labels) networkx.draw_networkx_nodes(G, pos, nodelist=exploredNodes, node_color='b', node_size=500) plt.axis('off') outputName = name + str(name_n) + '.png' plt.savefig(outputName) name_n += 1 for vertex in graph.getAdj(u): ID = vertex KEY = -(graph.getNodes()[vertex].getWeight()) if ID not in exploredNodes: pq.insert(ID, KEY) return exploredNodes