def four_chain(three_chain_list, DAG_TC): #Uses the transitive completion of the DAG to find all of the three chains in the DAG four_chain_list = [] for three_chain in three_chain_list: #Iterates over every 3 chain [node1, node2, node3] = three_chain for node in DAG_TC.nodes(): #Iterates over every node in the DAG if dl.age_check(DAG_TC, node1, node): #If a node has birthdays between two of the nodes in the 3 chain, it could be possible to find a 4 chain that has this node added in to the 3 chain if dl.age_check(DAG_TC, node, node2): if nx.has_path(DAG_TC, node1, node): if nx.has_path(DAG_TC, node, node2): four_chain_list.append([node1, node, node2, node3]) #If a three chain can be formed, add it to the list return four_chain_list
def three_chain(DAG_TC): #Uses the transitive completion of the DAG to find all of the three chains in the DAG three_chain_list = [] for edge in DAG_TC.edges(): #Iterates over every edge in the TC, which is also every 2 chain [node1, node2] = edge for node in DAG_TC.nodes(): if dl.age_check(DAG_TC, node1, node): #If a node has birthdays between each end of the 2 chain, it could be possible to find a 3 chain that has this node inbetween the the ends of the 2 chain if dl.age_check(DAG_TC, node, node2): if nx.has_path(DAG_TC, node1, node): #check if there is a path to the middle node from the 1st if nx.has_path(DAG_TC, node, node2): #check if there is a path from the middle node to the 2nd three_chain_list.append([node1, node, node2]) #If a three chain can be formed, add it to the list return three_chain_list
def trans_comp(DAG): for node1 in DAG.nodes(): for node2 in DAG.nodes(): if dl.age_check(DAG, node1, node2): if not node1 == node2: if nx.has_path(DAG, node1, node2): DAG.add_edge(node1, node2) return DAG
def test_TR(DAG, TR): missing_edges = [] for node1 in DAG.nodes(): for node2 in DAG.nodes(): #iterates over all pairs of nodes in the DAG if dl.age_check(DAG, node1, node2): #ensure that there could possibly be a path from node1 to node2 if nx.has_path(DAG, node1, node2): #tests whether there is a path between these two nodes in the original DAG if not nx.has_path(TR, node1, node2): missing_edges.append([node1, node2]) #if there is no longer a path between these two pairs of nodes in the transitive reduction... return missing_edges #...then these two edges are stored and printed
def path_check(DAG, start, end): if end in DAG.successors(start): return True for child in DAG.successors(start): if dl.age_check(DAG, child, end): # We can possibly go from this child to the end if path_check(DAG, child, end): return True else: return False
def trans_comp_nx(DAG): N = DAG.number_of_nodes() i = 0 print_limit = 0.01 for node1 in DAG.nodes(): for node2 in DAG.nodes(): #iterates over all pairs of edges if dl.age_check(DAG, node1, node2): #ensures that the time ordering of the pair is such that an edge could exist from node1 to node2 if not node1 == node2: #prevents loops if nx.has_path(DAG, node1, node2): DAG.add_edge(node1, node2) #if there is a path from node1 to node2, add an edge from node1 to node2 i += 1. pc = (i/float(N))*100. #convert to percentage if pc > print_limit: #print 'Finished %f percent' %pc print_limit += 0.01 return DAG