def is_predecessor(self, node_x, node_y): """ Comprueba si node_x es antecesor de node_y segun Dietz’s numbering scheme. @type node_x: RandomVariable @param node_x: Nodo antecesor. @type node_y: RandomVariable @param node_y: Nodo descendiente. @rtype: boolean @return: Valor de verdad acerca de si x es antecesor de y. """ pre_iterator = traversal(self.graph, node_x, 'pre') post_iterator = traversal(self.graph, node_x, 'post') pre_tree = [node for node in pre_iterator] post_tree = [node for node in post_iterator] is_predecessor = False if(node_y in pre_tree): is_predecessor = (pre_tree.index(node_x) < pre_tree.index(node_y)) and (post_tree.index(node_x) > post_tree.index(node_y)) return is_predecessor
def transitive_edges(graph): """ Return a list of transitive edges. Example of transitivity within graphs: A -> B, B -> C, A -> C in this case the transitive edge is: A -> C @attention: This function is only meaningful for directed acyclic graphs. @type graph: digraph @param graph: Digraph @rtype: List @return: List containing tuples with transitive edges (or an empty array if the digraph contains a cycle) """ #if the graph contains a cycle we return an empty array if not len(find_cycle(graph)) == 0: return [] tranz_edges = [] # create an empty array that will contain all the tuples #run trough all the nodes in the graph for start in topological_sorting(graph): #find all the successors on the path for the current node successors = [] for a in traversal(graph,start,'pre'): successors.append(a) del successors[0] #we need all the nodes in it's path except the start node itself for next in successors: #look for an intersection between all the neighbors of the #given node and all the neighbors from the given successor intersect_array = _intersection(graph.neighbors(next), graph.neighbors(start) ) for a in intersect_array: if graph.has_edge((start, a)): ##check for the detected edge and append it to the returned array tranz_edges.append( (start,a) ) return tranz_edges # return the final array