def test_execution_order(steps_dependency_graph, request): cached_topsorts = request.config.cache.get(repr(steps_dependency_graph), default=[]) expected = (cached_topsorts if cached_topsorts else ParallelGenerator( (tuple(reversed(topsort)) for topsort in all_topological_sorts(steps_dependency_graph)), max_lookahead=2, )) execution_order = ExecutionOrder(steps_dependency_graph) actual = tuple(itertools.chain.from_iterable(execution_order)) if cached_topsorts: assert any(list(actual) == topsort for topsort in cached_topsorts), f"{actual} not found in {cached_topsorts}" else: with expected as topsorts: done = False for topsort in topsorts: cached_topsorts.append(topsort) if actual == topsort: done = True break request.config.cache.set(repr(steps_dependency_graph), tuple(cached_topsorts)) assert done
def test_all_topological_sorts_2(self): DG = nx.DiGraph([(1, 3), (2, 1), (2, 4), (4, 3), (4, 5)]) assert (sorted(nx.all_topological_sorts(DG)) == [[2, 1, 4, 3, 5], [2, 1, 4, 5, 3], [2, 4, 1, 3, 5], [2, 4, 1, 5, 3], [2, 4, 5, 1, 3]])
def test_all_topological_sorts_4(self): DG = nx.DiGraph() for i in range(7): DG.add_node(i) assert sorted(map(list, permutations(DG.nodes))) == sorted( nx.all_topological_sorts(DG) )
def test_all_topological_sorts_multigraph_2(self): N = 9 edges = [] for i in range(1, N): edges.extend([(i, i + 1)] * i) DG = nx.MultiDiGraph(edges) assert list(nx.all_topological_sorts(DG)) == [list(range(1, N + 1))]
def main(): data = get_data_from_file() G = nx.DiGraph() for i in data: G.add_edges_from([(i[0],i[1]),(i[1],i[2])]) ans = list(nx.all_topological_sorts(G))[0] return int(''.join(ans))
def generate_exec_orders(wf, popsize, rng, skip_limit): top_sort_list = [] gen = nx.all_topological_sorts(G=wf.graph) retval = peek(gen) if retval is None: return None while len(top_sort_list) < popsize: gen = nx.all_topological_sorts(G=wf.graph) for top in gen: # 'skip through' a number of different top sorts to ensure we are # getting a diverse range. skip = rng.integers(low=0, high=RAND_BOUNDS) % skip_limit for x in range(skip): next(gen) yield top
def test_all_topological_sorts_multigraph_2(self): N = 9 edges = [] for i in range(1, N): edges.extend([(i, i+1)] * i) DG = nx.MultiDiGraph(edges) assert_equal(list(nx.all_topological_sorts(DG)), [list(range(1, N+1))])
def generate_exec_orders(wf, popsize, seed, skip_limit): top_sort_list = [] generator = nx.all_topological_sorts(G=wf.graph) retval = peek(generator) if retval is None: return None random.seed(seed) while len(top_sort_list) < popsize: generator = nx.all_topological_sorts(G=wf.graph) for top in generator: # 'skip through' a number of different top sorts to ensure we are # getting a diverse range. skip = random.randint(0, RAND_BOUNDS) % skip_limit for x in range(skip): next(generator) yield top
def test_all_topological_sorts_2(self): DG = nx.DiGraph([(1, 3), (2, 1), (2, 4), (4, 3), (4, 5)]) assert_equal(sorted(nx.all_topological_sorts(DG)), [[2, 1, 4, 3, 5], [2, 1, 4, 5, 3], [2, 4, 1, 3, 5], [2, 4, 1, 5, 3], [2, 4, 5, 1, 3]])
def save_units(G, path_out, glabels): for p in glabels: #process each group, removing nodes that are not part of that group, and other groups GD = G.copy() #temporary copy of full graph #print() #print(p,glabels[p].replace(" ","_").replace("-","_"),"----------------------") nlist = list(G.nodes) #display(nlist) for n in nlist: # Calculate total number of groups and their names groups if ('gid' in GD.nodes[n]): #normal node if (GD.nodes[n]['gid'] != p): #normal node but not part of current group GD.remove_node(n) else: #group node GD.remove_node(n) elist = list(G.edges) #display(elist) egraphics = nx.get_edge_attributes(G, 'graphics') #print(egraphics) labels = {} for node in GD.nodes(): #local store of node labels labels[node] = G.nodes[node]['LabelGraphics']['text'].replace( " ", "_").replace("-", "_") plt.figure(p + 1) #display strat graph for one group plt.title(glabels[p]) nx.draw_networkx(GD, pos=nx.kamada_kawai_layout(GD), arrows=True, with_labels=False) nx.draw_networkx_labels(GD, pos=nx.kamada_kawai_layout(GD), labels=labels, font_size=12, font_family='sans-serif') nlist = list(nx.all_topological_sorts( GD)) #all possible sorted directional graphs f = open( path_out + "/" + glabels[p].replace(" ", "_").replace("-", "_") + '.csv', 'w') #print("choices:",len(nlist)) #f.write(str(len(nlist))+" ") #f.write(str(len(GD))+"\n") for m in range(len(nlist)): #process all sorted graphs f.write('Choice ' + str(m)) for n in range(0, len(GD)): #display nodes for one sorted graph #print(nlist[m][n],G.nodes[nlist[m][n]]['LabelGraphics']['text'].replace(" ","_").replace("-","_")) f.write("," + G.nodes[nlist[m][n]]['LabelGraphics'] ['text'].replace(" ", "_").replace("-", "_")) #if(m<len(nlist)-1): #print("....") f.write('\n') f.close()
def test_graph(self): G = random_tl_graph([2, 4, 3, 1]) save(G, "input-network.txt") subprocess.check_call(["./lab4b.out", "input-network.txt"]) reference = list(nx.all_topological_sorts(G)) result = self.load_result("result.txt") self.assertIn(result, reference)
def test_chain_graph(self): """ Check program output for node chain """ G = random_tl_graph([1, 1, 1, 1, 1]) save(G, "input-network.txt") subprocess.check_call(["./lab4b.out", "input-network.txt"]) reference = list(nx.all_topological_sorts(G)) result = self.load_result("result.txt") self.assertIn(result, reference)
def solve(words): chars = set(char for word in words for char in word) if len(chars) == 1: return words[0][0] lts = less_than_relations(words) dg = DiGraph() dg.add_edges_from(lts) res = None for toposort in all_topological_sorts(dg): if len(toposort) < len(chars) or res != None: return 'AMBIGUOUS' else: res = toposort return ' '.join(res)
def generate_complete_dag(dag, ngraphs=10): """ Given a DAG, return ngraphs complete graphs which are a super DAG of the original one. Note: their could be more than one possibility, so we return ngraphs of them. """ dags = [] for argsort in nx.all_topological_sorts(nx.DiGraph(dag)): a = dag.copy() for i, parent in enumerate(argsort): for child in argsort[i + 1:]: a[parent, child] = 1 dags.append(a) if len(dags) == ngraphs: return dags return dags
def _get_conanfile(self, vertex: str) -> Optional[ConanFile]: """ Resolve precedence between requires, those closer to root take precedence (steps according to 'requires' relation) """ in_edges = self.graph.in_edges(vertex, data='require') # Handle corner-case for the rootnode # TODO: You can do better if not in_edges: log.warning(f"Handle root corner case. It is vertex '{vertex}'") return self.provider.get_conanfile(vertex, []) requires_graph = self.graph.get_requires_graph() # if the vertex is not in the requires graph, do not get the conanfile if not requires_graph.has_node(vertex): log.debug( f"Vertex '{vertex}' doesn't belong to the requires graph") return # Filter requires by ancestors: requires_ancestors = nx.ancestors(requires_graph, vertex) requires: Dict[str, Require] = { ori: require for ori, _, require in in_edges if ori in requires_ancestors } # We need to consider all the topological orderings and check they resolve to the same # conanfile, otherwise we have an ambiguity that should be reported as a conflict. candidate_conanfiles: List[ConanFile] = [] for topo_order in nx.all_topological_sorts(requires_graph): log.debug(f"Topological order: f{topo_order}") requires_given_order: List[Tuple[str, Require]] = [] for it in topo_order: if it == vertex: # Optimization break req = requires.get(it, None) if req: requires_given_order.append((it, req)) conanfile = self.provider.get_conanfile(vertex, requires_given_order) candidate_conanfiles.append(conanfile) # Validate that we get the same conanfile assert len(set( candidate_conanfiles)) == 1, "Multiple conanfiles --> ambiguity!" return candidate_conanfiles[0]
def _get_graph_data(self, DG): assert any(n in ['topological', 'lex_topological', 'all'] for n in self.node_order), "Invalid node ordering selected." adj_list = [] if 'topological' in self.node_order: nodelist = [n for n in nx.topological_sort(DG)] adj = np.transpose( np.array(nx.to_numpy_matrix(DG, nodelist=nodelist))) if self.is_tril: adj = adj + adj.transpose() assert adj.sum() > 0, "{}".format(DG.graph) adj_list.append(adj) if 'lex_topological' in self.node_order: nodelist = [n for n in nx.lexicographical_topological_sort(DG)] adj = np.transpose( np.array(nx.to_numpy_matrix(DG, nodelist=nodelist))) if self.is_tril: adj = adj + adj.transpose() assert adj.sum() > 0, "{}".format(DG.graph) adj_list.append(adj) if 'all' in self.node_order: all_nodelist = list(nx.all_topological_sorts(DG)) for nodelist in all_nodelist: adj = np.transpose( np.array(nx.to_numpy_matrix(DG, nodelist=nodelist))) if self.is_tril: adj = adj + adj.transpose() assert adj.sum() > 0, "{}".format(DG.graph) adj_list.append(adj) return adj_list
def find_adapter_chain(adapter_graph: nx.DiGraph) -> tuple[int, int]: """Find a valid chain of adapters & determine how many 1 & 3 joltage deltas are present.""" # NOTE: This approach is super overkill for this problem, but I wanted to stick with the graph # # Since our edges represent a valid adapter connection, we're looking for a Hamiltonian path # here: a path that visits every node exactly once. For this problem, since adapter joltage has # to be ascending, we can check a topological sort and see if they're all connected. n_one_delta = 0 n_three_delta = 0 for check_path in nx.all_topological_sorts(adapter_graph): # First check that the topological sort has yielded a valid path. if not nx.is_path(adapter_graph, check_path): continue # Let's assume there's only one valid path for source, dest in zip(check_path, check_path[1:]): delta = adapter_graph.get_edge_data(source, dest)["delta"] if delta == 1: n_one_delta += 1 elif delta == 3: n_three_delta += 1 return n_one_delta, n_three_delta
def not_implemented(): G = nx.Graph([(1, 2), (2, 3)]) # convert to list to execute generator list(nx.all_topological_sorts(G))
def test_all_topological_sorts_1(self): DG = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 5)]) assert list(nx.all_topological_sorts(DG)) == [[1, 2, 3, 4, 5]]
def unfeasible(): DG = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 2), (4, 5)]) # convert to list to execute generator list(nx.all_topological_sorts(DG))
def save_group(G, path_out, glabels, geol, c_l): Gp = nx.Graph().to_directed() #New Group graph geology_file = gpd.read_file(path_out + 'geol_clip.shp') abs_age_groups(geol, path_out, c_l) geology_file.drop_duplicates(subset=c_l['c'], inplace=True) geology_file.set_index(c_l['c'], inplace=True) #display(geology_file) gp_ages = pd.read_csv(path_out + 'age_sorted_groups.csv') #display(gp_ages) gp_ages.set_index('group_', inplace=True) display(gp_ages) gp_ids = [] nlist = list(G.nodes) for n in nlist: # Find out total number of groups and their names groups if ('isGroup' in G.nodes[n]): G.add_nodes_from([n]) display(gp_ids) for e in G.edges: if (G.nodes[e[0]]['gid'] != G.nodes[e[1]]['gid']): glabel_0 = G.nodes[e[0]]['LabelGraphics']['text'] glabel_1 = G.nodes[e[1]]['LabelGraphics']['text'] #print(glabel_0,glabel_1) #print(geology_file.loc[glabel_0][c_l['g']]) if (str(geology_file.loc[glabel_0][c_l['g']]) == 'None'): grp0 = glabel_0.replace(" ", "_").replace("-", "_") else: grp0 = geology_file.loc[glabel_0][c_l['g']].replace( " ", "_").replace("-", "_") if (str(geology_file.loc[glabel_1][c_l['g']]) == 'None'): grp1 = glabel_1.replace(" ", "_").replace("-", "_") else: grp1 = geology_file.loc[glabel_1][c_l['g']].replace( " ", "_").replace("-", "_") #print(glabel_0,glabel_1,gp_ages.loc[grp0],gp_ages.loc[grp1]) if (gp_ages.loc[grp0]['ave'] < gp_ages.loc[grp1]['ave']): Gp.add_edge(G.nodes[e[0]]['gid'], G.nodes[e[1]]['gid']) GpD = Gp.copy() #temporary copy of full graph GpD2 = Gp.copy() #temporary copy of full graph for e in GpD2.edges: #remove duplicate edges with opposite directions for f in GpD.edges: if (e[0] == f[1] and e[1] == f[0] and e[0] < f[0] ): #arbitrary choice to ensure edge is not completely removed Gp.remove_edge(e[0], e[1]) plt.figure(1) #display strat graph for one group plt.title("groups") nx.draw_networkx(Gp, pos=nx.kamada_kawai_layout(Gp), arrows=True, with_labels=False) nx.draw_networkx_labels(Gp, pos=nx.kamada_kawai_layout(Gp), labels=glabels, font_size=12, font_family='sans-serif') if ( len(gp_ages) > 10 ): # when lots of groups very large number of possibilities so short cut to first choice. glist = list( nx.topological_sort(Gp)) #all possible sorted directional graphs print("group choices: 1 (more than 10 groups)") f = open(path_out + 'groups.csv', 'w') glen = len(glist) f.write('Choice 0') for n in range(0, glen): f.write(',' + str(glabels[glist[n]])) #check underscore f.write('\n') f.close() else: glist = list(nx.all_topological_sorts( Gp)) #all possible sorted directional graphs print("group choices:", len(glist)) f = open(path_out + 'groups.csv', 'w') glen = len(glist) if (glen > 100): glen = 100 for n in range(0, glen): f.write('Choice ' + str(n)) for m in range(0, len(glist[0])): f.write(',' + str(glabels[glist[n][m]])) #check underscore f.write('\n') f.close() #display(glist) nx.write_gml(Gp, path_out + 'groups.gml') #plt.show() #g=open(path_out+'groups.csv',"r") #contents =g.readlines() #g.close #hdr=contents[0].split(" ") contents = np.genfromtxt(path_out + 'groups.csv', delimiter=',', dtype='U100') #display('lencon',len(contents[0])) k = 0 ag = open(path_out + '/all_sorts.csv', "w") ag.write("index,group number,index in group,number in group,code,group\n") if (len(contents.shape) == 1): for i in range(1, len(contents)): ucontents = np.genfromtxt( path_out + "/" + contents[i].replace("\n", "").replace(" ", "_") + ".csv", delimiter=',', dtype='U100') #f=open(path_out+"/"+contents[i].replace("\n","").replace(" ","_")+".csv","r")#check underscore #ucontents =f.readlines() #f.close #print(len(ucontents.shape),ucontents) if (len(ucontents.shape) == 1): for j in range(1, len(ucontents)): ag.write( str(k) + "," + str(i) + "," + str(j) + "," + str(len(ucontents) - 1) + "," + ucontents[j].replace("\n", "") + "," + contents[i].replace("\n", "").replace( " ", "_").replace("-", "_") + "\n") k = k + 1 else: for j in range(1, len(ucontents[0])): ag.write( str(k) + "," + str(i) + "," + str(j) + "," + str(len(ucontents[0]) - 1) + "," + ucontents[0][j].replace("\n", "") + "," + contents[i].replace("\n", "").replace( " ", "_").replace("-", "_") + "\n") k = k + 1 else: for i in range(1, len(contents[0])): ucontents = np.genfromtxt( path_out + "/" + contents[0][i].replace("\n", "").replace(" ", "_") + ".csv", delimiter=',', dtype='U100') #f=open(path_out+"/"+contents[i].replace("\n","").replace(" ","_")+".csv","r")#check underscore #ucontents =f.readlines() #f.close #print(len(ucontents.shape),ucontents) if (len(ucontents.shape) == 1): for j in range(1, len(ucontents)): ag.write( str(k) + "," + str(i) + "," + str(j) + "," + str(len(ucontents) - 1) + "," + ucontents[j].replace("\n", "") + "," + contents[0][i].replace("\n", "").replace( " ", "_").replace("-", "_") + "\n") k = k + 1 else: for j in range(1, len(ucontents[0])): ag.write( str(k) + "," + str(i) + "," + str(j) + "," + str(len(ucontents[0]) - 1) + "," + ucontents[0][j].replace("\n", "") + "," + contents[0][i].replace("\n", "").replace( " ", "_").replace("-", "_") + "\n") k = k + 1 ag.close()
import networkx as nx G = nx.DiGraph([ (1, 4), (1, 5), (1, 7), (2, 3), (2, 5), (2, 6), (3, 4), (3, 5), (5, 6), (6, 7) ]) A = nx.adjacency_matrix(G) print(A.todense()) print(list(nx.topological_sort(G))) print(list(nx.all_topological_sorts(G))) print(len(list(nx.all_topological_sorts(G)))) print(nx.is_directed_acyclic_graph(G))
def test_all_topological_sorts_1(self): DG = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 5)]) assert_equal(list(nx.all_topological_sorts(DG)), [[1, 2, 3, 4, 5]])
def __get_dependency_order(self): """ Use topological sort to get the order of execution. If a target task is specified, find the shortest path. """ if len(self._graph.nodes) == 0 and len(self._task_nodes) > 0: self._dependency_order = [ task for task_name, task in self._task_nodes.items() ] else: self._dependency_order = list(nx.topological_sort(self._graph)) if self.target: #Si tengo que ejecutar el DAG hasta cierto nodo, primero me fijo que nodo es: target_node = [ node for node in self._dependency_order if node.name == self.target ][0] target_idx = self._dependency_order.index(target_node) #Despues trunco la lista hasta el nodo, con esto estaria sacando todas las tareas que se iban a ejecutar despues: self._dependency_order = self._dependency_order[:target_idx + 1] #Con esto puedo armar otro grafo que solo contenga los nodos que se iban a ejecutar antes que target. reduced_task_nodes = { node.name: node for node in self._dependency_order } pruned_graph = make_graph_from_tasks(reduced_task_nodes) #Es posible que algunas tareas se ejecutaran antes que target pero que no fueran necesarias para target sino que para un nodo posterior. #Estas tareas quedarian desconectadas del target. Busco los subgrafos conectados: connected_subgraphs = list( nx.components.connected_component_subgraphs( pruned_graph.to_undirected())) #Si hay mas de uno es porque quedaron tareas que no llevan a ningun lado. Agarro el subgrafo con la tarea target: if len(connected_subgraphs) > 1: reachable_subgraph = [ g for g in connected_subgraphs if target_node in g.nodes ][0] else: reachable_subgraph = connected_subgraphs[0] #Armo el grafo de nuevo porque el algoritmo de subgrafos conectados necesita que sea un UAG. reduced_task_nodes = { node.name: node for node in reachable_subgraph.nodes } pruned_graph = make_graph_from_tasks(reduced_task_nodes) #Topological sort del grafo resultante me da las dependencias para el target task: self._dependency_order = list(nx.topological_sort(pruned_graph)) self._graph = pruned_graph priority_nodes = [ node for node in self._graph.nodes if 'priorize' in node.parameters and node.parameters['priorize'] ] if len(priority_nodes) > 0: #This can be improved, instead of searching all topological_sorts, we could just use one and keep track of all the #tasks that can be executed at any moment. If one of those tasks has priorize, then run it first. import itertools all_sorts = [ top for top in itertools.islice( nx.all_topological_sorts(self._graph), 100) ] sort_score = np.array([ sum([top.index(pnode) for pnode in priority_nodes]) for top in all_sorts ]) best_sort = all_sorts[np.argmin(sort_score)] self._dependency_order = best_sort for node in self._graph.nodes: if node.parameters.get('run_first', False): self._dependency_order.remove(node) self._dependency_order.insert(0, node)
def not_implemented(): G = nx.Graph([(1, 2), (2, 3)]) # convert to list to execute generator list(nx.all_topological_sorts(G))
def unfeasible(): DG = nx.DiGraph([(1, 2), (2, 3), (3, 4), (4, 2), (4, 5)]) # convert to list to execute generator list(nx.all_topological_sorts(DG))
def not_implemted_2(): G = nx.MultiGraph([(1, 2), (1, 2), (2, 3)]) list(nx.all_topological_sorts(G))
def test_all_topological_sorts_4(self): DG = nx.DiGraph() for i in range(7): DG.add_node(i) assert_equal(sorted(map(list, permutations(DG.nodes))), sorted(nx.all_topological_sorts(DG)))
with open(in_file_path, 'r') as infile: with open(out_file_path, 'w') as outfile: cases = int(infile.readline()) for case in range(cases): lines = int(infile.readline().rstrip()) alphabet = [] for l in range(lines): alphabet.append(infile.readline().rstrip()) if case in range(0, 100): graph = build_graph(alphabet) # print(alphabet) # print(graph) graph = networkx.DiGraph(graph) # print(graph) order = networkx.all_topological_sorts(graph) order = list(order) # print(order, len(order)) if len(order) > 1: order = "AMBIGUOUS" else: if len(order[0]) < 1: order = "AMBIGUOUS" else: order = " ".join(order[0]) print(order) outfile.write("Case #" + str(case + 1) + ": " + order + "\n")
def test_all_topological_sorts_multigraph_1(self): DG = nx.MultiDiGraph([(1, 2), (1, 2), (2, 3), (3, 4), (3, 5), (3, 5), (3, 5)]) assert_equal(sorted(nx.all_topological_sorts(DG)), sorted([[1, 2, 3, 4, 5], [1, 2, 3, 5, 4]]))
def not_implemted_2(): G = nx.MultiGraph([(1, 2), (1, 2), (2, 3)]) list(nx.all_topological_sorts(G))
def test_all_topological_sorts_multigraph_1(self): DG = nx.MultiDiGraph([(1, 2), (1, 2), (2, 3), (3, 4), (3, 5), (3, 5), (3, 5)]) assert (sorted(nx.all_topological_sorts(DG)) == sorted([[1, 2, 3, 4, 5], [1, 2, 3, 5, 4]]))
def save_units(G,path_out,glabels,Australia,asud_strat_file): if Australia: ASUD=pd.read_csv(asud_strat_file,',') for p in glabels: #process each group, removing nodes that are not part of that group, and other groups GD=G.copy() #temporary copy of full graph #print() #print(p,glabels[p].replace(" ","_").replace("-","_"),"----------------------") nlist=list(G.nodes) for n in nlist: # Calculate total number of groups and their names groups if('gid' in GD.nodes[n]): #normal node if(GD.nodes[n]['gid']!=p): #normal node but not part of current group GD.remove_node(n) else: #group node GD.remove_node(n) labels = {} for node in GD.nodes(): #local store of node labels labels[node] = G.nodes[node]['LabelGraphics']['text'].replace(" ","_").replace("-","_") cycles=nx.simple_cycles(GD) for cy in cycles: found=False if Australia: len_cy=len(cy) for i in range(len_cy-1): glabel_0=GD.nodes[cy[i]]['LabelGraphics']['text'] glabel_1=GD.nodes[cy[i+1]]['LabelGraphics']['text'] edge=ASUD.loc[(ASUD['over'] == glabel_0) & (ASUD['under'] == glabel_1) ] if(len(edge)==0 and (not('isGroup' in GD.nodes[cy[i]]) and not('isGroup' in GD.nodes[cy[i+1]]))): if(GD.has_edge(cy[i],cy[i+1])): continue else: warning_msg='map2loop warning 1: Stratigraphic relationship: '+ str(GD.nodes[cy[i]]['LabelGraphics']['text'])+' overlies '+str(GD.nodes[cy[i+1]]['LabelGraphics']['text'])+' removed to prevent cycle' warnings.warn(warning_msg) GD.remove_edge(cy[i],cy[i+1]) found=True if(not found): glabel_0=GD.nodes[cy[len_cy-1]]['LabelGraphics']['text'] glabel_1=GD.nodes[cy[0]]['LabelGraphics']['text'] edge=ASUD.loc[(ASUD['over'] == glabel_0) & (ASUD['under'] == glabel_1) ] if(len(edge)==0 and (not('isGroup' in GD.nodes[cy[len_cy-1]]) and not('isGroup' in GD.nodes[cy[0]]))): if( GD.has_edge(cy[len_cy-1],cy[0])): warning_msg='map2loop warning 1: Stratigraphic relationship: '+ str(GD.nodes[cy[len_cy-1]]['LabelGraphics']['text'])+' overlies '+str(GD.nodes[cy[0]]['LabelGraphics']['text'])+' removed to prevent cycle' warnings.warn(warning_msg) GD.remove_edge(cy[len_cy-1],cy[0]) found=True if(not found): warning_msg='map2loop warning 2: Stratigraphic relationship: '+ str(GD.nodes[cy[0]]['LabelGraphics']['text'])+' overlies '+str(GD.nodes[cy[1]]['LabelGraphics']['text'])+' removed to prevent cycle' warnings.warn(warning_msg) GD.remove_edge(cy[0],cy[1]) else: warning_msg='map2loop warning 3: Stratigraphic relationship: '+ str(GD.nodes[cy[0]]['LabelGraphics']['text'])+' overlies '+str(GD.nodes[cy[1]]['LabelGraphics']['text'])+' removed to prevent cycle' warnings.warn(warning_msg) GD.remove_edge(cy[0],cy[1]) plt.figure(p+1) #display strat graph for one group plt.title(glabels[p]) nx.draw_networkx(GD, pos=nx.kamada_kawai_layout(GD), arrows=True,with_labels=False) nx.draw_networkx_labels(GD,pos=nx.kamada_kawai_layout(GD), labels=labels, font_size=12,font_family='sans-serif') one=True if(one): nlist=list(nx.topological_sort(GD)) #one possible sorted directional graphs else: nlist=list(nx.all_topological_sorts(GD)) #all possible sorted directional graphs f = open(path_out+"/"+glabels[p].replace(" ","_").replace("-","_")+'.csv', 'w') if(one): f.write('Choice '+str(0)) for n in range(0,len(GD)): #display nodes for one sorted graph f.write(","+G.nodes[nlist[n]]['LabelGraphics']['text'].replace(" ","_").replace("-","_")) f.write('\n') else: for m in range(10): #process first ten sorted graphs f.write('Choice '+str(m)) for n in range(0,len(GD)): #display nodes for one sorted graph #print(nlist[m][n],G.nodes[nlist[m][n]]['LabelGraphics']['text'].replace(" ","_").replace("-","_")) f.write(","+G.nodes[nlist[m][n]]['LabelGraphics']['text'].replace(" ","_").replace("-","_")) #if(m<len(nlist)-1): #print("....") f.write('\n') f.close()