def test_find_cycle_on_very_deep_graph(self): gr = pygraph.classes.graph.graph() gr.add_nodes(range(0, 12001)) for i in range(0, 12000): gr.add_edge((i, i + 1)) recursionlimit = getrecursionlimit() find_cycle(gr) assert getrecursionlimit() == recursionlimit
def _init_graph(self): """Initialize our graph.""" for classname in self._classmap: for dep in self._deps[classname]: self.graph.add_edge((classname, dep)) if cycles.find_cycle(self.graph): raise RuntimeError( 'Programmer error: graph contains cycles "{}"'.format( cycles.find_cycle(self.graph)))
def _validate(self): # TODO: test A -> B, A -> C, B -> C if len(self.starters) == 0: return False if find_cycle(self._digraph): return False return True
def _check_cycles(self): """ Raise a CyclesDetectedError if a cycle is detected. """ cycles = find_cycle(self.dag) if cycles: raise CyclesDetectedError(cycles, self.dag)
def condorcet_completion_method(self): # Initialize the candidate graph self.rounds = [] graph = digraph() graph.add_nodes(self.candidates) # Loop until we've considered all possible pairs remaining_strong_pairs = deepcopy(self.strong_pairs) while len(remaining_strong_pairs) > 0: r = {} # Find the strongest pair largest_strength = max(remaining_strong_pairs.values()) strongest_pairs = matching_keys(remaining_strong_pairs, largest_strength) if len(strongest_pairs) > 1: r["tied_pairs"] = strongest_pairs strongest_pair = self.break_ties(strongest_pairs) else: strongest_pair = list(strongest_pairs)[0] r["pair"] = strongest_pair # If the pair would add a cycle, skip it graph.add_edge(strongest_pair) if len(find_cycle(graph)) > 0: r["action"] = "skipped" graph.del_edge(strongest_pair) else: r["action"] = "added" del remaining_strong_pairs[strongest_pair] self.rounds.append(r) self.old_graph = self.graph self.graph = graph self.graph_winner()
def main(): global dg2 while find_cycle(dg2): dg2 = generate(8,10,directed=True) sweep() print dg2 print toporder
def testNoCycleDigraph2(self): G = pygraph.digraph() G.add_nodes([1,2,3]) G.add_edge(1,2) G.add_edge(1,3) G.add_edge(2,3) assert find_cycle(G) == []
def main(): global dg2 while find_cycle(dg2): dg2 = generate(8, 10, directed=True) sweep() print dg2 print toporder
def sort_out_covering_exons (cursor, exons): # havana is manually curated and gets priority is_ensembl = {} is_havana = {} for exon in exons: logic_name = get_logic_name(cursor, exon.analysis_id) is_ensembl[exon] = ('ensembl' in logic_name) is_havana [exon] = ('havana' in logic_name) dg = digraph() dg.add_nodes(exons) for exon1, exon2 in combinations(dg.nodes(),2): master, covered = find_master(cursor, exon1,exon2,is_ensembl,is_havana) if master is not None and covered is not None: dg.add_edge(master,covered) assert not find_cycle(dg) clusters = dict(((k,v) for k,v in accessibility(dg).iteritems() if not dg.incidents(k))) for k in clusters: clusters[k].remove(k) for master_exon, covered_list in clusters.iteritems(): master_exon.covering_exon = -1 # nobody's covering this guy master_exon.covering_exon_known = -1 # formal for covered_exon in covered_list: covered_exon.covering_exon = master_exon.exon_id covered_exon.covering_exon_known = master_exon.is_known
def main(args): g = generate(args.nodes, args.edges, True) while not find_cycle(g): g = generate(args.nodes, args.edges, True) with open(args.output, 'w') as f: f.write(write(g))
def testNoCycleDigraph(self): G = pygraph.digraph() G.add_nodes([1, 2, 3, 4, 5]) G.add_edge(1, 2) G.add_edge(2, 3) G.add_edge(2, 4) G.add_edge(4, 5) G.add_edge(3, 5) assert find_cycle(G) == []
def testSmallCycleDigraph(self): G = pygraph.digraph() G.add_nodes([1, 2, 3, 4, 5]) G.add_edge(1, 2) G.add_edge(2, 3) G.add_edge(2, 4) G.add_edge(4, 5) G.add_edge(2, 1) # Cycle: 1-2 assert find_cycle(G) == [1,2]
def testMisleadingDigraph(self): G = pygraph.digraph() G.add_nodes([1, 2, 3, 4, 5]) G.add_edge(1, 2) G.add_edge(2, 3) G.add_edge(2, 4) G.add_edge(4, 5) G.add_edge(3, 5) G.add_edge(3, 1) assert find_cycle(G) == [1, 2, 3]
def test_find_small_cycle_on_digraph(self): gr = digraph() gr.add_nodes([1, 2, 3, 4, 5]) gr.add_edge((1, 2)) gr.add_edge((2, 3)) gr.add_edge((2, 4)) gr.add_edge((4, 5)) gr.add_edge((2, 1)) # Cycle: 1-2 assert find_cycle(gr) == [1, 2]
def test_regression1(self): G = digraph() G.add_nodes([1, 2, 3, 4, 5]) G.add_edge((1, 2)) G.add_edge((2, 3)) G.add_edge((2, 4)) G.add_edge((4, 5)) G.add_edge((3, 5)) G.add_edge((3, 1)) assert find_cycle(G) == [1, 2, 3]
def test_find_small_cycle_on_digraph(self): gr = digraph() gr.add_nodes([1, 2, 3, 4, 5]) gr.add_edge((1, 2)) gr.add_edge((2, 3)) gr.add_edge((2, 4)) gr.add_edge((4, 5)) gr.add_edge((2, 1)) # Cycle: 1-2 assert find_cycle(gr) == [1,2]
def testGraph(self): G = pygraph.graph() G.add_nodes([1, 2, 3, 4, 5]) G.add_edge(1, 2) G.add_edge(2, 3) G.add_edge(2, 4) G.add_edge(4, 5) G.add_edge(1, 5) G.add_edge(3, 5) # Cycles: 1-2-4-5, 3-2-4-5 and 1-2-3-5 assert find_cycle(G) == [2,3,5,4]
def addDependency(self,server,dependency): ''' Add a dependency to a server :param server: the name of the server :param dependency: the name of the server the former is dependent on :raise DependencyException: Will raise an exception if there was a cycle in the server network ''' self.graph.add_edge(((dependency,server))) #Note this is a turple casting cycleCheck = find_cycle(self.graph) if len(cycleCheck) != 0: raise Exceptions.DependencyException(cycleCheck,"There was a cycle in the server network") return
def _check_valid(graph): """ Check that the given graph is valid. This function does not return anything. It raise an exception however if the graph is considered invalid. """ if graph is None: raise ValueError("The given graph is None!") if not graph.DIRECTED: raise ValueError("The given graph is not a directed graph!") cycle = find_cycle(graph) if len(cycle) != 0: _LOGGER.error("A cycle has been detected") raise CyclesDetectedError(cycle, graph)
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
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 LoopGraph 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 LoopGraph 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
def build_graph(services, root=None): graph = digraph() for name, service in services.iteritems(): dockerfile = "%s/Dockerfile" % service.dockerfile() if not os.path.isfile(dockerfile): sys.exit("%s does not exist" % dockerfile) baseimage = None with open(dockerfile, 'r') as file: for line in file: stripped = line.strip() if stripped.startswith('#'): continue if re.match("^\s*FROM\s+", stripped): if baseimage: sys.exit("'%s' has more than 1 FROM instruction" % dockerfile) tokens = stripped.split() if len(tokens) < 2: sys.exit("'%s' has invalid FROM instruction" % dockerfile) baseimage = tokens[1] _add_node_if_not_exists(graph, name) if baseimage.startswith(DOMAIN): parent = baseimage[len(DOMAIN):] _add_node_if_not_exists(graph, parent) graph.add_edge((parent, name)) if root and not graph.has_node(root): sys.exit("Found no root in graph") cycles = find_cycle(graph) if cycles: sys.exit("Following services %s build a cycle. Please fix it!" % cycles) return _topological_sorting(graph, root)
def _find_cut(candidate_cuts, cycle, tasks, files, releases): for (counter, cut) in enumerate(candidate_cuts): log.info("Cut: %s" % str(cut)) tasks, task, task_name = _apply_cut(cut, tasks) # If no more cycles are found in the updated reduced graph # then return the good cut commits2 = create_commits_graph(files, tasks, releases) cycle2 = find_cycle(commits2) log.info("Cycle: %s" % set(cycle)) log.info("Cycle2: %s" % set(cycle2)) _undo_cut(cut, task_name, task, tasks) if set(cycle) & set(cycle2) == set(cycle): log.info("The cycle was not removed") else: log.info("Cut found.") return cut else: # Error! This should not happen log.info("No cut found.") return None
def detect_cycle (self): return find_cycle (self.graph)
def convert_history(files, tasks, releases, fileobjects): """Converts the Synergy history between two releases to a Git compatible one.""" #print "Look for cycles in the File History graph" while find_cycle(files): cycle = find_cycle(files) #print "A cycle was found!" #print "Cycle:", cycle # Find the newest file newest = max(cycle, key=lambda x: [fileobject.get_integrate_time() for fileobject in fileobjects if fileobject.get_objectname == x][0]) #print "Object %s is the newest in the cycle: it should not have successors!" % newest # Remove the outgoing link from the newest file for successor in files.neighbors(newest): if successor in cycle: files.del_edge((newest, successor)) #print "Removed the %s -> %s edge" % (newest, successor) [files.del_edge(edge) for i, edge in transitive_edges(files)] #print "Removed transitive edges from the File History graph." sanitized_tasks = _sanitize_tasks(tasks) #print "Tasks hypergraph sanitized." commits = create_commits_graph(files, sanitized_tasks, releases) #print "First commits graph created." # Cycles detection while find_cycle(commits): cycle = find_cycle(commits) #print "Cycles found!" #print "Cycle:", cycle # Generate the reduced file history graph reduced_graph = _create_reduced_graph(files, tasks, cycle) #print "Reduced graph:", reduced_graph # Find the longest cycle in the reduced graph longest_cycle = max(mutual_accessibility(reduced_graph).values(), key=len) candidate_cuts = [] for edge in zip(longest_cycle, longest_cycle[1:] + longest_cycle[0:1]): node1, node2 = edge # Find to which task the edge belongs to if tasks.links(node1) == tasks.links(node2): task = tasks.links(node1)[0] # Find which cuts are compatible and add them to the candidates list candidate_cuts.extend( [cut for cut in _find_cuts(tasks.links(task)) if (node1 in cut and node2 not in cut) or (node2 in cut and node2 not in cut)]) #print "Candidate_cuts:", candidate_cuts for (counter, cut) in enumerate(candidate_cuts): #print "Cut:", cut # Apply the cut task = tasks.links(cut[0])[0] # All the nodes in the cut belong to the same task and there are no overlapping tasks task_name = "" for i in count(1): task_name = task + "_" + str(i) if task_name not in tasks.edges(): #print "Adding task", task_name tasks.add_edge(task_name) break for node in cut: #print "Unlinking file %s from task %s" % (node, task) tasks.unlink(node, task) tasks.graph.del_edge(((node,'n'), (task,'h'))) # An ugly hack to work around a bug in pygraph #print "Linking file %s to task %s" % (node, task_name) tasks.link(node, task_name) # If no more cycles are found in the updated reduced graph then break commits2 = create_commits_graph(files, tasks, releases) cycle2 = find_cycle(commits2) if set(cycle) & set(cycle2) == set(cycle): # Undo the changes! #print "The cycle was not removed. Undoing changes..." #print "\tDeleting task", task_name tasks.del_edge(task_name) for node in cut: #print "\tLinking file %s to task %s" % (node, task) tasks.link(node, task) #print "Done." else: #print "Cut found." commits = create_commits_graph(files, tasks, releases) break #else: # Error! This should not happen #print "Cut not found." #else: #print "No cycles found" return commits
def test_find_cycle_on_digraph_without_cycles(self): gr = testlib.new_digraph() st, pre, post = depth_first_search(gr) gr = digraph() gr.add_spanning_tree(st) assert find_cycle(gr) == []
def check_cycle(): cycles = find_cycle(Expression.dependency_graph) if cycles: print("[!] Exist dependency cycle: %s" % (cycles,), file=sys.stderr) sys.exit(-1)
def check_cycle(): cycles = find_cycle(Expression.dependency_graph) if cycles: print("[!] Exist dependency cycle: %s" % (cycles, ), file=sys.stderr) sys.exit(-1)
def has_cycle(cls, nodes, edges): gr = digraph() gr.add_nodes(nodes) for edge in edges: gr.add_edge(edge) return find_cycle(gr)
def get_cycles(self): '''computes one cycle or an empty list''' # FIXME: check complexity return find_cycle(self._graph)
def sampleLink(self, index, list_index, ll): s = SamplerStateTracker.samplerStates[SamplerStateTracker.current_iter] table_id = s.get_t(index, list_index) customersAtTable = s.getCustomersAtTable(table_id, list_index) orig_table_members = [] g = digraph() ug = graph() for i in customersAtTable: orig_table_members.append(i) if not g.has_node(i): ug.add_node(i) g.add_node(i) j = s.getC(i, list_index) if not g.has_node(j): ug.add_node(j) g.add_node(j) g.add_edge((i,j)) ug.add_edge((i,j)) cycles = find_cycle(g) isCyclePresent = False if index in cycles: isCyclePresent = True if not isCyclePresent: # obs to sample moval will split the table into 2 ug.del_edge((index, s.getC(index, list_index))) temp, new_table_members = breadth_first_search(ug, index) orig_table_members = new_table_members temp, old_table_members = breadth_first_search(ug, s.getC(index, list_index)) s.setT(s.getT() + 1) s.setC(None, index, list_index) new_table_id = self.emptyTables[list_index].remove(0) for l in new_table_members: s.set_t(new_table_id, l , list_index) old_table_id = table_id s.setCustomersAtTable(set(old_table_members), old_table_id, list_index) table_id = new_table_id s.setCustomersAtTable(set(new_table_members), new_table_id, list_index) distanceMatrices = Data.getDistanceMatrices() distance_matrix = distanceMatrices[list_index] priors = distance_matrix[index] priors[index] = ll.getHyperParameters().getSelfLinkProb() sum_p = sum(priors) priors = priors/sum_p posterior = [] indexes = [] for i in range(len(priors)): if priors[i] != 0: indexes.append(i) table_proposed = s.get_t(i, list_index) if table_proposed == table_id: posterior.append(priors[i]) else: proposedTableMembersSet = s.getCustomersAtTable(table_proposed, list_index) proposed_table_members = list(proposedTableMembersSet) change_in_log_likelihood = self.compute_change_in_likelihood(ll, orig_table_members,proposed_table_members, list_index) posterior.append(exp(log(priors[i]+change_in_log_likelihood))) sample = Util.sample(posterior) customer_assignment_index = indexes[sample] assigned_table = s.get_t(customer_assignment_index, list_index) s.setC(customer_assignment_index, index, list_index) if assigned_table != table_id: s.setT(s.getT()-1) for members in orig_table_members: s.set_t(assigned_table, members, list_index) hs_orig_members_in_new_table = set(s.getCustomersAtTable(assigned_table, list_index)) for i in range(len(orig_table_members)): hs_orig_members_in_new_table.add(orig_table_members[i]) s.setCustomersAtTable(hs_orig_members_in_new_table, assigned_table, list_index) s.setCustomersAtTable(None, table_id, list_index) self.emptyTables[index].append(table_id)
def cycle(self): cicle = find_cycle(self.graph) if cicle: return cicle else: return None
def test_find_cycle_on_digraph(self): gr = testlib.new_digraph() cycle = find_cycle(gr) verify_cycle(gr, cycle)
def critical_path(graph): """ Compute and return the critical path in an acyclic directed weighted graph. @attention: This function is only meaningful for directed weighted acyclic graphs @type graph: digraph @param graph: Digraph @rtype: List @return: List containing all the nodes in the path (or an empty array if the graph contains a cycle) """ #if the graph contains a cycle we return an empty array if not len(find_cycle(graph)) == 0: return [] #this empty dictionary will contain a tuple for every single node #the tuple contains the information about the most costly predecessor #of the given node and the cost of the path to this node #(predecessor, cost) node_tuples = {} topological_nodes = topological_sorting(graph) #all the tuples must be set to a default value for every node in the graph for node in topological_nodes: node_tuples.update({node: (None, 0)}) #run trough all the nodes in a topological order for node in topological_nodes: predecessors = [] #we must check all the predecessors for pre in graph.incidents(node): max_pre = node_tuples[pre][1] predecessors.append((pre, graph.edge_weight( (pre, node)) + max_pre)) max = 0 max_tuple = (None, 0) for i in predecessors: #look for the most costly predecessor if i[1] >= max: max = i[1] max_tuple = i #assign the maximum value to the given node in the node_tuples dictionary node_tuples[node] = max_tuple #find the critical node max = 0 critical_node = None for k, v in list(node_tuples.items()): if v[1] >= max: max = v[1] critical_node = k path = [] #find the critical path with backtracking trought the dictionary def mid_critical_path(end): if node_tuples[end][0] != None: path.append(end) mid_critical_path(node_tuples[end][0]) else: path.append(end) #call the recursive function mid_critical_path(critical_node) path.reverse() return path #return the array containing the critical path
def convert_history(files, tasks, releases, objects): """Converts the Synergy history between two releases to a Git compatible one.""" log.basicConfig(filename="convert_history.log", level=log.DEBUG) file_objects = [ccm_cache.get_object(o) for o in objects] log.info("Looking for cycles in the File History graph") while find_cycle(files): cycle = find_cycle(files) log.info("\tA cycle was found!") log.info("\tCycle: %s" % ", ".join(cycle)) # Find the newest file newest = max( cycle, key=lambda x: [ fileobject.get_integrate_time() for fileobject in file_objects if fileobject.get_objectname() == x ][0], ) log.info("\tObject %s is the newest in the cycle: it should not have successors!" % newest) # Remove the outgoing link from the newest file for successor in files.neighbors(newest): if successor in cycle: files.del_edge((newest, successor)) log.info("\tRemoved the %s -> %s edge" % (newest, successor)) log.info("Remove transitive edges in the File History graph") for edge in transitive_edges(files): if edge in files.edges(): files.del_edge(edge) else: log.warning("Weird, transitive edge not found!") log.info("Sanitize tasks") sanitized_tasks = _sanitize_tasks(tasks) log.info("Create commits graph") commits = create_commits_graph(files, sanitized_tasks, releases) # Uncomment for debug... (remember import) # hack = {'previous': releases.edges()[0]} # htg.commit_graph_to_image(commits, hack, tasks, name='Pre-'+releases.edges()[1]) log.info("Looking for cycles in the Commits graph") while find_cycle(commits): log.info("Finding strictly connected components") cycle = max(mutual_accessibility(commits).values(), key=len) # cycle = find_cycle(commits) log.info("\tA cycle was found!") log.info("\tCycle: %s" % ", ".join(cycle)) log.info("Find the nodes in the cycle going from one task to another") culpript_edges = [] for task in cycle: for obj in tasks.links(task): for neighbor in files.neighbors(obj): if neighbor not in tasks.links(task) and tasks.links(neighbor)[0] in cycle: culpript_edges.append((obj, neighbor)) log.info("\tAdding culpript edge (%s, %s)" % (obj, neighbor)) log.info("Connect the nodes found") culpript_nodes = set() for head, tail in culpript_edges: culpript_nodes.add(head) culpript_nodes.add(tail) for head, tail in permutations(culpript_nodes, 2): if tasks.links(head)[0] == tasks.links(tail)[0] and (head, tail) not in culpript_edges: log.info("\tAdding edge (%s, %s)" % (head, tail)) culpript_edges.append((head, tail)) reduced_digraph = digraph() reduced_digraph.add_nodes(culpript_nodes) [reduced_digraph.add_edge(edge) for edge in culpript_edges] shortest_cycle = max(mutual_accessibility(reduced_digraph).values(), key=len) log.info("Cycle in objects: %s" % shortest_cycle) candidate_cuts = [] # Find the tasks t = set() for node in shortest_cycle: t.add(tasks.links(node)[0]) log.info("T: %s" % str(t)) for i in t: log.info("Cuts for task %s" % i) # Find the objects in the cycle belonging to task i obj_in_task = set(tasks.links(i)) & set(shortest_cycle) log.info("Objects in cycle and task: %s" % obj_in_task) if len(obj_in_task) < 15: if len(obj_in_task) > 1: for j in range(1, len(obj_in_task) / 2 + 1): candidate_cuts.extend([k for k in combinations(obj_in_task, j)]) else: log.info("Cycle too long...") pass log.info("Candidate_cuts: %s" % str(candidate_cuts)) # Find the cut to break the cycle cut = _find_cut(candidate_cuts, cycle, tasks, files, releases) if not cut: # Make a qualified guess of a cut with the shortest walk of files in the tasks walk, node = _find_shortest_incident_or_neighbor_walk(shortest_cycle, cycle, files, tasks) new_cut = walk new_cut.append(node) candidate_cuts.insert(0, tuple(new_cut)) log.info("Candidate cuts: %s", candidate_cuts) cut = _find_cut(candidate_cuts, cycle, tasks, files, releases) if not cut: # Error! This should not happen log.info("Cut not found.") log.shutdown() raise Exception("Cut not found") tasks, task, task_name = _apply_cut(cut, tasks) commits = create_commits_graph(files, tasks, releases) else: log.info("No cycles found") log.shutdown() return commits
def convert_history(files, tasks, releases, objects): """Converts the Synergy history between two releases to a Git compatible one.""" log.basicConfig(filename='convert_history.log', level=log.DEBUG) file_objects = [ccm_cache.get_object(o) for o in objects] log.info("Looking for cycles in the File History graph") while find_cycle(files): cycle = find_cycle(files) log.info("\tA cycle was found!") log.info("\tCycle: %s" % ", ".join(cycle)) # Find the newest file newest = max(cycle, key=lambda x: [ fileobject.get_integrate_time() for fileobject in file_objects if fileobject.get_objectname() == x ][0]) log.info( "\tObject %s is the newest in the cycle: it should not have successors!" % newest) # Remove the outgoing link from the newest file for successor in files.neighbors(newest): if successor in cycle: files.del_edge((newest, successor)) log.info("\tRemoved the %s -> %s edge" % (newest, successor)) log.info("Remove transitive edges in the File History graph") for edge in transitive_edges(files): if edge in files.edges(): files.del_edge(edge) else: log.warning("Weird, transitive edge not found!") log.info("Sanitize tasks") sanitized_tasks = _sanitize_tasks(tasks) log.info("Create commits graph") commits = create_commits_graph(files, sanitized_tasks, releases) # Uncomment for debug... (remember import) #hack = {'previous': releases.edges()[0]} #htg.commit_graph_to_image(commits, hack, tasks, name='Pre-'+releases.edges()[1]) log.info("Looking for cycles in the Commits graph") while find_cycle(commits): log.info("Finding strictly connected components") cycle = max(mutual_accessibility(commits).values(), key=len) #cycle = find_cycle(commits) log.info("\tA cycle was found!") log.info("\tCycle: %s" % ", ".join(cycle)) log.info("Find the nodes in the cycle going from one task to another") culpript_edges = [] for task in cycle: for obj in tasks.links(task): for neighbor in files.neighbors(obj): if neighbor not in tasks.links(task) and tasks.links( neighbor)[0] in cycle: culpript_edges.append((obj, neighbor)) log.info("\tAdding culpript edge (%s, %s)" % (obj, neighbor)) log.info("Connect the nodes found") culpript_nodes = set() for head, tail in culpript_edges: culpript_nodes.add(head) culpript_nodes.add(tail) for head, tail in permutations(culpript_nodes, 2): if tasks.links(head)[0] == tasks.links(tail)[0] and ( head, tail) not in culpript_edges: log.info("\tAdding edge (%s, %s)" % (head, tail)) culpript_edges.append((head, tail)) reduced_digraph = digraph() reduced_digraph.add_nodes(culpript_nodes) [reduced_digraph.add_edge(edge) for edge in culpript_edges] shortest_cycle = max(mutual_accessibility(reduced_digraph).values(), key=len) log.info("Cycle in objects: %s" % shortest_cycle) candidate_cuts = [] # Find the tasks t = set() for node in shortest_cycle: t.add(tasks.links(node)[0]) log.info("T: %s" % str(t)) for i in t: log.info("Cuts for task %s" % i) # Find the objects in the cycle belonging to task i obj_in_task = set(tasks.links(i)) & set(shortest_cycle) log.info("Objects in cycle and task: %s" % obj_in_task) if len(obj_in_task) < 15: if len(obj_in_task) > 1: for j in range(1, len(obj_in_task) / 2 + 1): candidate_cuts.extend( [k for k in combinations(obj_in_task, j)]) else: log.info("Cycle too long...") pass if len(candidate_cuts) < 50: log.info("Candidate_cuts: %s" % str(candidate_cuts)) # Find the cut to break the cycle cut = _find_cut(candidate_cuts, cycle, tasks, files, releases) if not cut: log.info("Shortest cycle cut didn't work, next option...") # Make a qualified guess of a cut with the shortest walk of files in the tasks walk, node = _find_shortest_incident_or_neighbor_walk( shortest_cycle, cycle, files, tasks) log.info("Shortest incident or neighbor walk from {0}: {1}".format( node, walk)) new_cut = walk new_cut.append(node) candidate_cuts.insert(0, tuple(new_cut)) log.info("Candidate cuts: %s", candidate_cuts) cut = _find_cut(candidate_cuts, cycle, tasks, files, releases) if not cut: # Error! This should not happen log.info("Cut not found.") log.shutdown() raise Exception("Cut not found") tasks, task, task_name = _apply_cut(cut, tasks) commits = create_commits_graph(files, tasks, releases) else: log.info("No cycles found") log.shutdown() return commits
def _find_one_pointless_cycle(node2arc_targets): # I guess find_cycle is cheaper than mutual_accessibility() if you # only care if there are cycles or not, but don't need the exact # strongly connected components """ print(find_cycle(_graph2py_digraph(graph)))
"spots", "temperature", "tonecurve", "tonemap", "velvia", "vignette", "watermark", "zonesystem", "rawspeed", ] ) add_edges(gr) # make sure we don't have cycles: cycle_list = find_cycle(gr) if cycle_list: print "cycles:" print cycle_list exit(1) # get us some sort order! sorted_nodes = topological_sorting(gr) length = len(sorted_nodes) priority = 1000 for n in sorted_nodes: # now that should be the priority in the c file: print "%d %s" % (priority, n) filename = "../src/iop/%s.c" % n if not os.path.isfile(filename): filename = "../src/iop/%s.cc" % n
def __init__(self, adjacencies = Adjacency()): super().__init__() self.add_adjacencies(adjacencies) if find_cycle(self): raise ValueError("Cycle detected!")
'temperature', 'tonecurve', 'tonemap', 'velvia', 'vibrance', 'vignette', 'watermark', 'zonesystem', 'rawprepare', 'rawspeed' ]) add_edges(gr) # make sure we don't have cycles: cycle_list = find_cycle(gr) if cycle_list: print("cycles:") print(cycle_list) exit(1) # replace all the priorities with garbage. to make sure all the iops are in this file. for filename in glob.glob( os.path.join(os.path.dirname(__file__), '../src/iop/*.c')) + glob.glob( os.path.join(os.path.dirname(__file__), '../src/iop/*.cc')): if apply_changes: replace_all( filename, "( )*?(?P<identifier>((\w)*))( )*?->( )*?priority( )*?(=).*?(;).*\n", " \g<identifier>->priority = %s; // module order created by iop_dependencies.py, do not edit!\n" % "NAN")
def find_all_cycle(gr, gr_copy=None, use_colors=True, number_cycle=1): gr_copy = gr_copy or deepcopy(gr) cycle = find_cycle(gr_copy) if cycle: mark_cycle(gr, cycle, number_cycle, gr_copy, use_colors=use_colors) find_all_cycle(gr, gr_copy, use_colors, number_cycle=number_cycle + 1)