def _add_edge_connected_subgraphs(self, first_graph: nx.DiGraph, second_graph: nx.DiGraph) -> None: """ Adds an edge between last node of 'first_graph' and first node of 'second_graph', which are found by nx.lexicographical_topological_sort(). :param first_graph: the graph which will be traversed the first in the united graph. :param second_graph: the graph which will be traversed the second in the united graph. """ self_graph = self._graph last_node_first_graph = list( nx.lexicographical_topological_sort(first_graph, key=int))[-1] assert first_graph.out_degree(last_node_first_graph) == 0 first_node_second_graph = list( nx.lexicographical_topological_sort(second_graph, key=int))[0] assert second_graph.in_degree(first_node_second_graph) == 0 # Special case when first node is ANY_PATTERN_NODE_TYPE or NON_PATTERN_NODE_TYPE if GraphPattern.ANY_PATTERN_NODE_TYPE in second_graph.nodes[first_node_second_graph]['type'] or \ GraphPattern.NON_PATTERN_NODE_TYPE in second_graph.nodes[first_node_second_graph]['type']: successors = self_graph.successors(first_node_second_graph) new_edges = list(it.product([last_node_first_graph], successors)) self_graph.add_edges_from(new_edges) self_graph.remove_node(first_node_second_graph) else: self_graph.add_edge(last_node_first_graph, first_node_second_graph)
def test_lexicographical_topological_sort(self): G = nx.DiGraph([(1, 2), (2, 3), (1, 4), (1, 5), (2, 6)]) assert (list( nx.lexicographical_topological_sort(G)) == [1, 2, 3, 4, 5, 6]) assert (list(nx.lexicographical_topological_sort( G, key=lambda x: x)) == [1, 2, 3, 4, 5, 6]) assert (list(nx.lexicographical_topological_sort( G, key=lambda x: -x)) == [1, 5, 4, 2, 6, 3])
def test_lexicographical_topological_sort(self): G = nx.DiGraph([(1, 2), (2, 3), (1, 4), (1, 5), (2, 6)]) assert_equal(list(nx.lexicographical_topological_sort(G)), [1, 2, 3, 4, 5, 6]) assert_equal(list(nx.lexicographical_topological_sort( G, key=lambda x: x)), [1, 2, 3, 4, 5, 6]) assert_equal(list(nx.lexicographical_topological_sort( G, key=lambda x: -x)), [1, 5, 4, 2, 6, 3])
def solve(lines): G = nx.DiGraph() for line in lines: parts = line.split(" ") G.add_edge(parts[1], parts[7]) print(''.join(nx.lexicographical_topological_sort(G))) task_times = [] tasks = [] time = 0 while task_times or G: available_tasks = [ t for t in G if t not in tasks and G.in_degree(t) == 0 ] if available_tasks and len(task_times) < 5: task = min( available_tasks) # min gets smallest task alphabetically task_times.append(ord(task) - 4) tasks.append(task) else: min_time = min(task_times) completed = [ tasks[i] for i, v in enumerate(task_times) if v == min_time ] task_times = [v - min_time for v in task_times if v > min_time] tasks = [t for t in tasks if t not in completed] time += min_time G.remove_nodes_from(completed) print(time)
def print_trace_graph(self, trace_graph): if trace_graph is not None: i = 0 for trace_id in trace_graph: dg = trace_graph[trace_id] if 'failed' in dg.graph and dg.graph['failed'] is True: i = i + 1 sorted_nodes = list( nx.lexicographical_topological_sort(dg)) all_node_data = dg.nodes.data() for node in sorted_nodes: if 'node' not in all_node_data[node]: print('\n') if 'is_child' in all_node_data[node]: print(" - " + all_node_data[node]['time'] + " " + all_node_data[node]['app'] + " " + all_node_data[node]['component'] + "" + all_node_data[node]['msg']) else: print("- " + all_node_data[node]['time'] + " " + all_node_data[node]['app'] + " " + all_node_data[node]['component'] + "" + all_node_data[node]['msg']) print('\nTotal failed traces: ', i) else: raise ValueError
def process(self, json_schema): if "definitions" in json_schema: for _obj_name, _obj in json_schema["definitions"].items(): model = self.definition_parser(_obj_name, _obj) self.definitions.append(model) # topological ordered dependencies g = networkx.DiGraph() models_map = {} for model in self.definitions: models_map[model["name"]] = model deps = self.get_model_dependencies(model) if not deps: g.add_edge(model["name"], "") for dep in deps: g.add_edge(model["name"], dep) self.definitions = [] if self.generate_definitions: # use lexicographical topo sort so that the generation order is stable for model_name in networkx.lexicographical_topological_sort(g): if model_name in models_map: # insert to front so that the sorting is reversed self.definitions.insert(0, models_map[model_name]) # create root object if there are some properties in the root if "title" in json_schema: root_object_name = "".join( x for x in json_schema["title"].title() if x.isalpha() ) else: root_object_name = "RootObject" if self.generate_root: root_model = self.definition_parser(root_object_name, json_schema) self.definitions.append(root_model)
def test_lexicographical_topological_sort2(self): """ Check the case of two or more nodes with same key value. Want to avoid exception raised due to comparing nodes directly. See Issue #3493 """ class Test_Node: def __init__(self, n): self.label = n self.priority = 1 def __repr__(self): return f"Node({self.label})" def sorting_key(node): return node.priority test_nodes = [Test_Node(n) for n in range(4)] G = nx.DiGraph() edges = [(0, 1), (0, 2), (0, 3), (2, 3)] G.add_edges_from((test_nodes[a], test_nodes[b]) for a, b in edges) sorting = list(nx.lexicographical_topological_sort(G, key=sorting_key)) assert sorting == test_nodes
def test_lexicographical_topological_sort2(self): ''' Check the case of two or more nodes with same key value. Want to avoid exception raised due to comparing nodes directly. See Issue #3493 ''' class Test_Node: def __init__(self, n): self.label = n self.priority = 1 def __repr__(self): return 'Node({})'.format(self.label) def sorting_key(node): return node.priority test_nodes = [Test_Node(n) for n in range(4)] G = nx.DiGraph() edges = [(0, 1), (0, 2), (0, 3), (2, 3)] G.add_edges_from((test_nodes[a], test_nodes[b]) for a, b in edges) sorting = list(nx.lexicographical_topological_sort(G, key=sorting_key)) # order reported does depend on order of list(G) in python 3.5 # and that is not deterministic due to dicts not being ordered until v3.6 # after dropping NX support for 3.5 this can become: # assert_equal(sorting, test_nodes) assert set(sorting) == set(test_nodes)
def _dependencies(self) -> tuple[Sequence[str], nx.DiGraph]: """ Returns: dependency_graph: The graph of dependencies. topo_sorted: A topological sort of the dependency graph """ g = self.digraph g2 = nx.DiGraph() # A graph with all dependencies. g2.add_nodes_from(g) for name in g: node_dict = g.nodes[name] position = node_dict.get('position', None) if position is not None: if not isinstance(position, NodePosition): raise TypeError for node in position.anchor.base_nodes(): g2.add_edge(node, name) if 'container' in node_dict: container = node_dict['container'] if not isinstance(container, NodeContainer): raise TypeError for node in container.nodes: g2.add_edge(node, name) try: return g2, list(nx.lexicographical_topological_sort(g2)) except nx.NetworkXUnfeasible: raise ValueError("Cyclic dependencies: " + str(list(nx.simple_cycles(g2)))) from None
def solve(lines): G = nx.DiGraph() for line in lines: parts = line.split(" ") G.add_edge(parts[1], parts[7]) print(''.join(nx.lexicographical_topological_sort(G))) return G
def solve_watershed_loading(g: nx.DiGraph, context: Dict[str, Any]) -> None: wet_weather_parameters = init_wq_parameters( "land_surface_emc_table", context=context ) dry_weather_parameters = init_wq_parameters( "dry_weather_land_surface_emc_table", context=context ) wet_weather_facility_performance_map = effluent_function_map( "tmnt_performance_table", context=context ) dry_weather_facility_performance_map = effluent_function_map( "dry_weather_tmnt_performance_table", context=context ) nomograph_map = load_nomograph_mapping(context=context) for node in nx.lexicographical_topological_sort(g): solve_node( g, node, wet_weather_parameters, dry_weather_parameters, wet_weather_facility_performance_map, dry_weather_facility_performance_map, nomograph_map, ) return
def solve1(text: str): tree = nx.DiGraph() for s1, s2 in parse_dependencies(text): tree.add_edge(s1, s2) nodes = list(nx.lexicographical_topological_sort(tree)) return ''.join(nodes)
def _get_tasks(product): order_graph = scheduler.subgraph(product.physical_graph, scheduler.DEPENDS_READY) tasks = networkx.lexicographical_topological_sort( order_graph.reverse(), key=lambda node: node.name) tasks = [task for task in tasks if isinstance(task, SDPPhysicalTask)] return tasks
def _topo_sort_nodes(dag) -> iset: """ Topo-sort dag by execution order & operation-insertion order to break ties. This means (probably!?) that the first inserted win the `needs`, but the last one win the `provides` (and the final solution). Inform user in case of cycles. """ node_keys = dict(zip(dag.nodes, count())) try: return iset(nx.lexicographical_topological_sort(dag, key=node_keys.get)) except nx.NetworkXUnfeasible as ex: import sys from textwrap import dedent tb = sys.exc_info()[2] msg = dedent(f""" {ex} TIP: Launch a post-mortem debugger, move 3 frames UP, and plot the `graphtik.planning.Network' class in `self` to discover the cycle. If GRAPHTIK_DEBUG enabled, this plot will be stored tmp-folder automatically :-) """) raise nx.NetworkXUnfeasible(msg).with_traceback(tb)
def test_topological_sort1(self): DG = nx.DiGraph([(1, 2), (1, 3), (2, 3)]) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: assert_equal(tuple(algorithm(DG)), (1, 2, 3)) DG.add_edge(3, 2) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: assert_raises(nx.NetworkXUnfeasible, consume, algorithm(DG)) DG.remove_edge(2, 3) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: assert_equal(tuple(algorithm(DG)), (1, 3, 2)) DG.remove_edge(3, 2) assert_in(tuple(nx.topological_sort(DG)), {(1, 2, 3), (1, 3, 2)}) assert_equal(tuple(nx.lexicographical_topological_sort(DG)), (1, 2, 3))
def select_fdx(adj_matrix, p_vals, alpha, gamma): ''' FDX extension of MG ''' # get fwer selections selections = select(adj_matrix, p_vals, alpha) # Get the number of selections nfwer = np.sum(selections) # calculate the magic number magic_number = int(np.floor(nfwer * gamma / (1 - gamma))) # Get the nodes in toplogical order from the top of the graph # (resolve ambiguities by going for the low p-values first) g = networkx.DiGraph(adj_matrix) ordered_inds = np.array( list( networkx.lexicographical_topological_sort( g, key=lambda i: p_vals[i]))) # only care about ones which we haven't already rejected ordered_inds = ordered_inds[~selections] # get the top magic-number of them, add 'em to the list! selections[ordered_inds[:magic_number]] = True # done return selections
def test_topological_sort1(self): DG = nx.DiGraph([(1, 2), (1, 3), (2, 3)]) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: assert tuple(algorithm(DG)) == (1, 2, 3) DG.add_edge(3, 2) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: pytest.raises(nx.NetworkXUnfeasible, _consume, algorithm(DG)) DG.remove_edge(2, 3) for algorithm in [ nx.topological_sort, nx.lexicographical_topological_sort ]: assert tuple(algorithm(DG)) == (1, 3, 2) DG.remove_edge(3, 2) assert tuple(nx.topological_sort(DG)) in {(1, 2, 3), (1, 3, 2)} assert tuple(nx.lexicographical_topological_sort(DG)) == (1, 2, 3)
def LTSort(lines): # initialize a networkx.DiGraph object graph = nx.DiGraph() for line in lines: # Step I must be finished before step P can begin. parts = line.split(" ") graph.add_edge(parts[1], parts[7]) # networkx does the sorting for us, so we just ask it to do so and poof, our part1 answer print("Part1 answer:", ''.join(nx.lexicographical_topological_sort(graph))) # Part2: With 5 workers and the 60+ second step durations described above, how long will it take to complete all of the steps? # steps are (60 + (chr(ord(step))) seconds long task_times = [] tasks = [] time = 0 while task_times or graph: available_tasks = [ t for t in graph if t not in tasks and graph.in_degree(t) == 0 ] if available_tasks and len(task_times) < 5: task = min( available_tasks) # min gets smallest task alphabetically task_times.append(ord(task) - 4) tasks.append(task) else: min_time = min(task_times) completed = [ tasks[i] for i, v in enumerate(task_times) if v == min_time ] task_times = [v - min_time for v in task_times if v > min_time] tasks = [t for t in tasks if t not in completed] time += min_time graph.remove_nodes_from(completed) print("Part2 answer:", time)
def to_dag(G, plot=False): ''' docstring: converts an acyclic graph to a DAG with branches yet directed towards the center. Input: indirect graph to be converted Output: DAG ''' if plot: nx.draw(G, with_labels=True, with_attributes=True) plt.show() center_dict = {} graph_ordered_node_trav = {} center = [n for n, d in G.out_degree() if d == 0][0] G = G.reverse() depth_list = nx.shortest_path_length(G, center) G = G.reverse() for n in nx.lexicographical_topological_sort(G): if G.in_degree(n) > 0: son_list_ordered = [] for p in sorted(list(G.predecessors(n)), key=lambda x: G.nodes[x]['atom']): G.nodes[n]['atom'] = G.nodes[n]['atom'] + G.nodes[p]['atom'] son_list_ordered.append(p) graph_ordered_node_trav[n] = son_list_ordered else: graph_ordered_node_trav[n] = [] center_dict[G.nodes[center] ['atom']] = G, graph_ordered_node_trav, depth_list, center return center_dict[min(center_dict.keys())]
def sequential_subgraph_nodes(g: nx.DiGraph, size: int) -> List[List[Union[str, int]]]: if not nx.is_weakly_connected(g): raise nx.NetworkXUnfeasible( "sequential solutions are not possible for disconnected graphs.") if size <= 1: raise nx.NetworkXUnfeasible( "the minimum directed subgraph length is 2 nodes.") g = nx.DiGraph(g.edges()) # make a copy because we'll modify the structure graphs = [] while len(g.nodes()) > 1: sg = find_leafy_branch_larger_than_size(g, size) sg_nodes = list(nx.lexicographical_topological_sort(sg)) graphs.append(sg_nodes) # trim the upstream nodes out of the graph, except the upstream root us_nodes = [n for n, deg in sg.out_degree if deg > 0] g = g.subgraph([n for n in g.nodes() if n not in us_nodes]) # rinse and repeat until there's one or fewer nodes left in the graph return graphs
def to_topological_dict(self): if self.validate(): result = [] for node in nx.lexicographical_topological_sort(self._graph, key=lambda x: str(x)): next_nodes = list(self._graph.successors(node)) result.append({node: next_nodes[0] if len(next_nodes) > 0 else None}) return result
def part1(data: str): prerequisites, edges = process_data(data.split("\n")) G = nx.DiGraph() for edge in edges: G.add_edge(edge[0], edge[1]) # hashmap of letter and its prerequisite letters for part 2 and own implementation of the sort return "".join(nx.lexicographical_topological_sort(G)), prerequisites
def task_descendants(self): return { task_name: [ self.tasks[name] for name in nx.descendants(self.graph, task_name) ] for task_name in nx.lexicographical_topological_sort(self.graph) }
def get_task_groups(self): # self._update_task_state_inplace() # graph = self.task_dependency_graph for task_name in networkx.lexicographical_topological_sort(graph): yield graph.nodes[task_name]['tasks']
def task_ancestors(self): """ graph ancestors, with the keys in lexicographical topological sort order. """ return { task_name: [self.tasks[name] for name in nx.ancestors(self.graph, task_name)] for task_name in nx.lexicographical_topological_sort(self.graph) }
def compute_condensation_in_topological_order(dependency_graph: nx.DiGraph, sort_by = lambda x: x): if not dependency_graph.number_of_nodes(): return condensed_graph = nx.condensation(dependency_graph) assert isinstance(condensed_graph, nx.DiGraph) for connected_component_index in nx.lexicographical_topological_sort(condensed_graph, key=sort_by): yield list(sorted(condensed_graph.node[connected_component_index]['members'], key=sort_by))
def topological_nodes(self): """ Yield nodes in topological order. Returns: generator(DAGNode): node in topological order """ return nx.lexicographical_topological_sort(self._multi_graph, key=lambda x: str(x.qargs))
def next_tasks(dag, changed_step): sub_dag = create_subgraph(dag, changed_step) sorted_sub_dag = nx.lexicographical_topological_sort(sub_dag) data_sub_dag = sub_dag.nodes(data=True) pendent_tasks = [node for node in sorted_sub_dag if data_sub_dag[node]['type'] == 'operator'] return pendent_tasks
def topological_sort(self) -> List[NNCFNode]: """ Returns nodes in topologically sorted order, additionally sorted in ascending node ID order. """ return [ self._nx_node_to_nncf_node(self._nx_graph.nodes[node_name]) for node_name in nx.lexicographical_topological_sort( self._nx_graph, key=lambda x: self._nx_graph.nodes[x][NNCFGraph.ID_NODE_ATTR]) ]
def test_parallel_sequential_subgraph_nodes(graph, size): if size == 1: with pytest.raises(nx.NetworkXUnfeasible): p_seqs = parallel_sequential_subgraph_nodes(graph, size) else: p_seqs = parallel_sequential_subgraph_nodes(graph, size) ls = list(nx.lexicographical_topological_sort(graph)) for seqs in p_seqs: assert check_sequential(seqs, ls)
def function(ii, DBG=True): # build world = build DAG # topological sort world = build_world(ii, DBG) ts = list(nx.lexicographical_topological_sort(world)) if (DBG): print(ts) return ''.join(ts)
def test_topological_sort1(self): DG = nx.DiGraph([(1, 2), (1, 3), (2, 3)]) for algorithm in [nx.topological_sort, nx.lexicographical_topological_sort]: assert_equal(tuple(algorithm(DG)), (1, 2, 3)) DG.add_edge(3, 2) for algorithm in [nx.topological_sort, nx.lexicographical_topological_sort]: assert_raises(nx.NetworkXUnfeasible, consume, algorithm(DG)) DG.remove_edge(2, 3) for algorithm in [nx.topological_sort, nx.lexicographical_topological_sort]: assert_equal(tuple(algorithm(DG)), (1, 3, 2)) DG.remove_edge(3, 2) assert_in(tuple(nx.topological_sort(DG)), {(1, 2, 3), (1, 3, 2)}) assert_equal(tuple(nx.lexicographical_topological_sort(DG)), (1, 2, 3))