def test_is_strongly_connected(self): ncc=nx.number_strongly_connected_components for G,C in self.gc: if len(C)==1: assert_true(nx.is_strongly_connected(G)) else: assert_false(nx.is_strongly_connected(G))
def test_scipy_sparse_eigs(G, CN_name, self_link=False, seed_creation=False): eps = gm.epsilon print 'percentage of non-zero elements: '+str(float(np.count_nonzero(Transition_Matrix))/G.number_of_nodes()**2) print 'is strongly connected? '+str(nx.is_strongly_connected(G))+'\nis aperiodic? '+str(nx.is_aperiodic(G)) M = salsa.get_matrix(G, mat_type='hub', sparse=True) CN_index = G.nodes().index(CN_name) M = gm.convert_SL_and_CN_weights_to_val(M, val=eps, CN_idx=CN_index, stochastic_out=True) new_G = nx.DiGraph(M) print 'AFTER get matrix:\npercentage of non-zero elements: ' + str(float(M.getnnz())/G.number_of_nodes()**2) print 'is strongly connected? '+str(nx.is_strongly_connected(new_G))+'\nis aperiodic? '+str(nx.is_aperiodic(new_G)) print 'is stochastic? '+str(gm.check_if_stochastic_matrix(M.todense())) print M print M.shape[0] #M_pow = np.linalg.matrix_power(M.todense(), 111) #print M_pow e,ev=sp.sparse.linalg.eigen.arpack.eigs(M.copy().T, k=1,sigma=1, which='LM')#, maxiter=100000) h = ev/ev.sum() print e; print h; if (h.imag.sum() != 0.): print '##### COMPLEX VECTOR!!!! #####' print map(float,h.real) '''e1,ev1=sp.linalg.eig(M.todense(),left=True,right=False) m=e1.argsort()[-1] evMax1=np.array(ev1[:,m]).flatten() print '\n\tnp.linalg.eig(left)\n' + str(e1[m]) + '\n' + str(evMax1) ''' return
def test_hsdf_analysis(n=15, p=0.2, runs=10000, debug=None): for run in range(runs) if debug is None else [debug]: sdfg = random_sdf_graph(n, p, seed=run) vectors = core.check_consistency(sdfg) assert nx.is_strongly_connected(sdfg) # Analysis of single-rate equivalent hsdfg = transform.single_rate_equivalent(sdfg, vectors['q']) mg = make_marked_graph(hsdfg) # HSDF graph may not be strongly connected, compute its strongly connected components condensed = nx.DiGraph() idx = 0 scc_idx = {} graph_mcr = None for scc in nx.strongly_connected_components(mg): idx += 1 for v in scc: scc_idx[v] = idx cycletime, _, _ = mcr.compute_mcr(nx.subgraph(mg, scc), next(iter(scc))) condensed.add_node(idx, mcr=cycletime, size=len(scc)) graph_mcr = cycletime if graph_mcr is None else max( cycletime, graph_mcr) for v, w in mg.edges_iter(): if scc_idx[v] != scc_idx[w]: condensed.add_edge(scc_idx[v], scc_idx[w]) critical_size = mg.number_of_nodes() for v, data in condensed.nodes(data=True): d_in = condensed.in_degree(v) d_out = condensed.out_degree(v) if d_in == 0: critical_size = data['size'] if d_in == 0 and data['mcr'] < graph_mcr: raise AssertionError("Run {}: SCC {} has MCR {} < {}".format( run, v, data['mcr'], graph_mcr)) if d_in > 1 or d_out > 1: pass # raise AssertionError("Run {}: SCC {}: in-degree = {}, out-degree = {}".format(run, v, d_in, d_out)) if debug: import pdb pdb.set_trace() unfolded, _, _ = transform.unfold_depth_first(sdfg, vectors['q'], vectors['s'], vectors['q']) assert nx.is_strongly_connected(unfolded) print( "Run {:05}: MCR = {}, condensed: {} nodes. HSDF size: {}. Compression: {:.3f}" .format(run, graph_mcr, condensed.number_of_nodes(), hsdfg.number_of_nodes(), hsdfg.number_of_nodes() / critical_size))
def generate_random_digraph(n, p, low, high): for i in range(100): G = nx.gnp_random_graph(n, p, directed = True) if nx.is_strongly_connected(G): break if nx.is_strongly_connected(G) == False: print("Unable to generate strongly connected graph, try increase 'p'.") density = float(len(G.edges()))/(n*(n-1)) print("Density: {}".format(density)) for (n1, n2) in G.edges(): G[n1][n2]['weight']=random.randint(low, high) return G, density
def generateConnexeSensUnique(longueur, largeur, probarete, probsensunique, limite, fonctionpoids, parampoids): i = 0 g = generateSensUnique(longueur, largeur, probarete, probsensunique, fonctionpoids, parampoids) while not (nx.is_strongly_connected(g)) and i < limite: i += 1 g = generateSensUnique(longueur, largeur, probarete, probsensunique, fonctionpoids, parampoids) if nx.is_strongly_connected(g): return g else: raise nx.ExceededMaxIterations( 'Pas de graphe fortement connexe généré avant ' + str(limite) + ' itérations')
def directed_stats(self): # UG = nx.to_undirected(g) #claims to not have this function if nx.is_strongly_connected(g): sconl = nx.strongly_connected_components(g) else: sconl = 'NA - graph is not strongly connected' result = {#"""returns boolean""" 'scon': nx.is_strongly_connected(g), 'sconn': nx.number_connected_components(g), # """returns boolean""" 'dag': nx.is_directed_acyclic_graph(g), # """returns lists""" 'sconl': nx.strongly_connected_components(g), #Conl = connected_component_subgraphs(Ug) } return result
def test_hsdf_analysis(n = 15, p = 0.2, runs = 10000, debug = None): for run in range(runs) if debug is None else [debug]: sdfg = random_sdf_graph(n, p, seed = run) vectors = core.check_consistency(sdfg) assert nx.is_strongly_connected( sdfg ) # Analysis of single-rate equivalent hsdfg = transform.single_rate_equivalent( sdfg, vectors['q'] ) mg = make_marked_graph(hsdfg) # HSDF graph may not be strongly connected, compute its strongly connected components condensed = nx.DiGraph() idx = 0 scc_idx = {} graph_mcr = None for scc in nx.strongly_connected_components(mg): idx += 1 for v in scc: scc_idx[v] = idx cycletime, _, _ = mcr.compute_mcr(nx.subgraph(mg, scc), next(iter(scc))) condensed.add_node(idx, mcr = cycletime, size = len(scc)) graph_mcr = cycletime if graph_mcr is None else max(cycletime, graph_mcr) for v, w in mg.edges_iter(): if scc_idx[v] != scc_idx[w]: condensed.add_edge( scc_idx[v], scc_idx[w] ) critical_size = mg.number_of_nodes() for v, data in condensed.nodes(data = True): d_in = condensed.in_degree(v) d_out = condensed.out_degree(v) if d_in == 0: critical_size = data['size'] if d_in == 0 and data['mcr'] < graph_mcr: raise AssertionError("Run {}: SCC {} has MCR {} < {}".format(run, v, data['mcr'], graph_mcr)) if d_in > 1 or d_out > 1: pass # raise AssertionError("Run {}: SCC {}: in-degree = {}, out-degree = {}".format(run, v, d_in, d_out)) if debug: import pdb; pdb.set_trace() unfolded, _, _ = transform.unfold_depth_first( sdfg, vectors['q'], vectors['s'], vectors['q'] ) assert nx.is_strongly_connected( unfolded ) print("Run {:05}: MCR = {}, condensed: {} nodes. HSDF size: {}. Compression: {:.3f}".format(run, graph_mcr, condensed.number_of_nodes(), hsdfg.number_of_nodes(), hsdfg.number_of_nodes() / critical_size))
def string_chain_solution(lst: List[str]) -> bool: """ Checks if the list of string can be chained :param lst: list of lowercase no-spaces strings :return: True if chaining is possible else False """ """ idea: we create a graph with 26 nodes representing the alphabet. each string will be represented by an edge connecting the node of the first letter to the node of the last letter. then, we need to check if the graph contains an euler circuit (closed loop going exactly once through every edge). this is true if: 1. the in-degree and out-degree of each node is the same 2. the graph is strongly connected. notice that we need to use nx.MultiDiGraph in order to create a directed graph allowing parallel edges. """ g = nx.MultiDiGraph() for string in lst: first = string[0] last = string[-1] g.add_edge(first, last) for node in g.nodes: if g.out_degree(node) != g.in_degree(node): return False return nx.is_strongly_connected(g)
def component_stats(G, verbose): """Prints out various relevent stats about graphs concerning components. Parameters ---------- G : networkx.DiGraph verbose : bool Set to True if you want explanations of stats Returns ------- Note: Writes to terminal. """ explans = {} if verbose == True: explans['weakly-connected'] = "(There is an undirected path between each pair of nodes in the directed graph)" explans['strongly-connected'] = "(There is a directed path between each pair of nodes in the directed graph)" explans['semiconnected'] = "" else: explans['weakly-connected'] = "" explans['strongly-connected'] = "" explans['semiconnected'] = "" print "Is the graph weakly connected "+explans['weakly-connected'] +"? "+ str(nx.is_weakly_connected(G)) print "Number of weakly connected components: " + str(nx.number_weakly_connected_components(G)) print "Is the graph semiconnected "+explans['semiconnected']+ "? " + str(nx.is_semiconnected(G)) print "Is the graph strongly connected "+explans['strongly-connected']+ "? "+ str(nx.is_strongly_connected(G))
def get_radius(self): logging.info("Radius calculations") if nx.is_strongly_connected(self.graph) is False: logging.info("Graph is not strongly connected") sub_graphs = nx.strongly_connected_component_subgraphs(self.graph) logging.info("------------------Subgraphs-----------------") count = 0 for sg in sub_graphs: count += 1 logging.info("Graph has :" + str(count) + " strongly connected subgraphs") sub_graphs = nx.strongly_connected_component_subgraphs(self.graph) for sg in sub_graphs: logging.info("Number of nodes in subgraph is: " + str(len(sg.nodes()))) radius = nx.radius(sg) self.sub_graph_radius.append(radius) else: self.sub_graph_radius.append(nx.radius(self.graph)) self.graph_radius = max(self.sub_graph_radius) print "Max radius: {}".format(self.graph_radius)
def get_largest_component(G, strongly=False): """ Return the largest weakly or strongly connected component from a directed graph. Parameters ---------- G : graph strongly : bool, if True, return the largest strongly instead of weakly connected component Returns ------- G : graph """ start_time = time.time() original_len = len(G.nodes()) if strongly: # if the graph is not connected and caller did not request retain_all, retain only the largest strongly connected component if not nx.is_strongly_connected(G): G = max(nx.strongly_connected_component_subgraphs(G), key=len) log('Graph was not connected, retained only the largest strongly connected component ({:,} of {:,} total nodes) in {:.2f} seconds' .format(len(G.nodes()), original_len, time.time() - start_time)) else: # if the graph is not connected and caller did not request retain_all, retain only the largest weakly connected component if not nx.is_weakly_connected(G): G = max(nx.weakly_connected_component_subgraphs(G), key=len) log('Graph was not connected, retained only the largest weakly connected component ({:,} of {:,} total nodes) in {:.2f} seconds' .format(len(G.nodes()), original_len, time.time() - start_time)) return G
def is_eulerian(G): """Returns ``True`` if and only if ``G`` is Eulerian. An graph is *Eulerian* if it has an Eulerian circuit. An *Eulerian circuit* is a closed walk that includes each edge of a graph exactly once. Parameters ---------- G : NetworkX graph A graph, either directed or undirected. Examples -------- >>> nx.is_eulerian(nx.DiGraph({0: [3], 1: [2], 2: [3], 3: [0, 1]})) True >>> nx.is_eulerian(nx.complete_graph(5)) True >>> nx.is_eulerian(nx.petersen_graph()) False Notes ----- If the graph is not connected (or not strongly connected, for directed graphs), this function returns ``False``. """ if G.is_directed(): # Every node must have equal in degree and out degree and the # graph must be strongly connected return (all(G.in_degree(n) == G.out_degree(n) for n in G) and nx.is_strongly_connected(G)) # An undirected Eulerian graph has no vertices of odd degree and # must be connected. return all(d % 2 == 0 for v, d in G.degree()) and nx.is_connected(G)
def __init__(self, g: nx.Graph): self.__g = g self.__data_dict = dict() self.__communities = dict() self.__pagerank = dict() self.__hits = dict() self.__conn_comp = list() self.__bridges = list() self.__local_bridges = list() self.__neigh_overlap = dict() self.__clustering_coefficients = dict() if nx.is_directed(self.__g): self.__data_dict['Type'] = "Directed" self.__data_dict['Connected'] = nx.is_strongly_connected(self.__g) else: self.__data_dict['Type'] = "Undirected" self.__data_dict['Connected'] = nx.is_connected(self.__g) self.__degree_stats() self.__graph_props() self.__basic_info() self.__communities_props() self.__link_analysis() self.__connected_components() if self.__data_dict["Type"] == "Undirected": self.__find_bridges_overlap()
def metrics_on_degree_sequence(self): # number of nodes n = len(self.network.nodes()) # isolate the sequence of degrees degree_sequence = list(self.network.degree()) # comput number of edges and the metrics on the degree sequence nb_nodes = n nb_arr = len(self.network.edges()) avg_degree = np.mean(np.array(degree_sequence)[:, 1]) med_degree = np.median(np.array(degree_sequence)[:, 1]) max_degree = max(np.array(degree_sequence)[:, 1]) min_degree = np.min(np.array(degree_sequence)[:, 1]) print("Number of nodes : " + str(nb_nodes)) print("Number of edges : " + str(nb_arr)) print("Maximum degree : " + str(max_degree)) print("Minimum degree : " + str(min_degree)) print("Average degree : " + str(avg_degree)) print("Median degree : " + str(med_degree)) print() print('This is a weakly connected network: ', nx.is_weakly_connected(self.network)) print('This is a strongly connected network: ', nx.is_strongly_connected(self.network)) print()
def netstats_listsdi(graph): G = graph # UG = nx.to_undirected(G) #claims to not have this function if nx.is_strongly_connected(G): sconl = nx.strongly_connected_components(G) else: sconl = 'NA - graph is not strongly connected' result = {#"""returns boolean""" 'scon': nx.is_strongly_connected(G), 'sconn': nx.number_connected_components(G), # """returns boolean""" 'dag': nx.is_directed_acyclic_graph(G), # """returns lists""" 'sconl': nx.strongly_connected_components(G), # Conl = connected_component_subgraphs(UG) } return result
def answer_three(): # Note: strongly_connected needs direction, weakly_connected needs only connections G = answer_one() s_con = nx.is_strongly_connected(G) w_con = nx.is_weakly_connected(G) return (s_con, w_con)
def is_eulerian(G): """Returns True if and only if `G` is Eulerian. A graph is *Eulerian* if it has an Eulerian circuit. An *Eulerian circuit* is a closed walk that includes each edge of a graph exactly once. Parameters ---------- G : NetworkX graph A graph, either directed or undirected. Examples -------- >>> nx.is_eulerian(nx.DiGraph({0: [3], 1: [2], 2: [3], 3: [0, 1]})) True >>> nx.is_eulerian(nx.complete_graph(5)) True >>> nx.is_eulerian(nx.petersen_graph()) False Notes ----- If the graph is not connected (or not strongly connected, for directed graphs), this function returns False. """ if G.is_directed(): # Every node must have equal in degree and out degree and the # graph must be strongly connected return (all(G.in_degree(n) == G.out_degree(n) for n in G) and nx.is_strongly_connected(G)) # An undirected Eulerian graph has no vertices of odd degree and # must be connected. return all(d % 2 == 0 for v, d in G.degree()) and nx.is_connected(G)
def create_shortest_path_matrix(weighted=False, discount_highways=False): G = nx.DiGraph() logging.info("Loading graph to NetworkX from database...") c = connection.cursor() if discount_highways: c.execute("SELECT l.beg_node_id, l.end_node_id, (CASE WHEN l.link_type='1' THEN 0.5 WHEN l.link_type='2' THEN 0.5 ELSE 1.0 END) FROM microsim_link l") else: c.execute("SELECT l.beg_node_id, l.end_node_id, l.length/l.lane_count AS resistance FROM microsim_link l") G.add_weighted_edges_from(c.fetchall()) logging.debug("Road network is strongly connected: %s" % repr(nx.is_strongly_connected(G))) logging.info("Computing shortest paths...") if weighted: sp = nx.all_pairs_dijkstra_path_length(G) else: sp = nx.all_pairs_shortest_path_length(G) logging.info("Converting shortest paths into matrix...") c.execute("SELECT ROW_NUMBER() OVER (ORDER BY id), beg_node_id, end_node_id FROM microsim_link") links = c.fetchall() N_LINKS = len(links) shortest_paths = np.zeros((N_LINKS, N_LINKS)) for col_idx, _, col_end_node in links: for row_idx, _, row_end_node in links: if col_idx == row_idx: continue nodes = sp[col_end_node] if row_end_node not in nodes: shortest_paths[row_idx - 1, col_idx - 1] = float(N_LINKS) else: shortest_paths[row_idx - 1, col_idx - 1] = nodes[row_end_node] logging.info("Shortest path matrix complete.") return shortest_paths
def draw_graph(nodes, edges, graphs_dir, default_lang='all'): lang_graph = nx.MultiDiGraph() lang_graph.add_nodes_from(nodes) for edge in edges: if edges[edge] == 0: lang_graph.add_edge(edge[0], edge[1]) else: lang_graph.add_edge(edge[0], edge[1], weight=float(edges[edge]), label=str(edges[edge])) # print graph info in stdout # degree centrality print('-----------------\n\n') print(default_lang) print(nx.info(lang_graph)) try: # When ties are associated to some positive aspects such as friendship or collaboration, # indegree is often interpreted as a form of popularity, and outdegree as gregariousness. DC = nx.degree_centrality(lang_graph) max_dc = max(DC.values()) max_dc_list = [item for item in DC.items() if item[1] == max_dc] except ZeroDivisionError: max_dc_list = [] # https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%BB%D0%B5%D0%BA%D1%81%D0%BD%D1%8B%D0%B5_%D1%81%D0%B5%D1%82%D0%B8 print('maxdc', str(max_dc_list), sep=': ') # assortativity coef AC = nx.degree_assortativity_coefficient(lang_graph) print('AC', str(AC), sep=': ') # connectivity print("Слабо-связный граф: ", nx.is_weakly_connected(lang_graph)) print("количество слабосвязанных компонент: ", nx.number_weakly_connected_components(lang_graph)) print("Сильно-связный граф: ", nx.is_strongly_connected(lang_graph)) print("количество сильносвязанных компонент: ", nx.number_strongly_connected_components(lang_graph)) print("рекурсивные? компоненты: ", nx.number_attracting_components(lang_graph)) print("число вершинной связности: ", nx.node_connectivity(lang_graph)) print("число рёберной связности: ", nx.edge_connectivity(lang_graph)) # other info print("average degree connectivity: ", nx.average_degree_connectivity(lang_graph)) print("average neighbor degree: ", sorted(nx.average_neighbor_degree(lang_graph).items(), key=itemgetter(1), reverse=True)) # best for small graphs, and our graphs are pretty small print("pagerank: ", sorted(nx.pagerank_numpy(lang_graph).items(), key=itemgetter(1), reverse=True)) plt.figure(figsize=(16.0, 9.0), dpi=80) plt.axis('off') pos = graphviz_layout(lang_graph) nx.draw_networkx_edges(lang_graph, pos, alpha=0.5, arrows=True) nx.draw_networkx(lang_graph, pos, node_size=1000, font_size=12, with_labels=True, node_color='green') nx.draw_networkx_edge_labels(lang_graph, pos, edges) # saving file to draw it with dot-graphviz # changing overall graph view, default is top-bottom lang_graph.graph['graph'] = {'rankdir': 'LR'} # marking with blue nodes with maximum degree centrality for max_dc_node in max_dc_list: lang_graph.node[max_dc_node[0]]['fontcolor'] = 'blue' write_dot(lang_graph, os.path.join(graphs_dir, default_lang + '_links.dot')) # plt.show() plt.savefig(os.path.join(graphs_dir, 'python_' + default_lang + '_graph.png'), dpi=100) plt.close()
def is_strongly_connected(G): # checking connectivity # the goal of the network is to be strongly connected if nx.is_strongly_connected(G): print('The directed graph is strongly connected') else: print('The directed graph is not strongly connected.')
def _update_after_countermeasure(self, target): new_components = [] if target in self.links_to_strong_components: component_id = self.links_to_strong_components[target] subgraph = self.nxGraph.subgraph( self.strong_components[component_id]['nodes']) is_still_strong = is_strongly_connected(subgraph) if is_still_strong: return else: self._remove_strong_component(component_id) # Find new components strong_components_nodes = get_strongly_connected_components( subgraph) # Add new components to list of components for component in strong_components_nodes: new_components.append(self.components_index) self._workout_strong_component(component) searcher = GraphSearcher(self.previousCopy) nodes_to_target = searcher.get_sources_to_target_node(target) self._update_nodes_threat(nodes_to_target) # Remove newly created component from update list for index in new_components: self.strong_components_to_update.remove(index)
def write_distance_info(G, report_file): report_file.write("===DISTANCE_INFO_STRONGLY_CONNECTED===\n") if nx.is_strongly_connected(G): report_file.write("Center: {}\n".format(nx.center(G))) report_file.write("Diameter: {}\n".format(nx.diameter(G))) report_file.write("Periphery: {}\n".format(nx.periphery(G))) report_file.write("Radius: {}\n".format(nx.radius(G))) else: report_file.write("Center: +INF\n") report_file.write("Diameter: +INF\n") report_file.write("Periphery: +INF\n") report_file.write("Radius: +INF\n") report_file.write("===DISTANCE_INFO_WEAKLY_CONNECTED===\n") if nx.is_weakly_connected(G): undirected_G = nx.to_undirected(G) report_file.write("Center: {}\n".format(nx.center(undirected_G))) report_file.write("Diameter: {}\n".format(nx.diameter(undirected_G))) report_file.write("Periphery: {}\n".format(nx.periphery(undirected_G))) report_file.write("Radius: {}\n".format(nx.radius(undirected_G))) else: report_file.write("Center: +INF\n") report_file.write("Diameter: +INF\n") report_file.write("Periphery: +INF\n") report_file.write("Radius: +INF\n")
def answer_three(): # Your Code Here G = answer_one() is_strongly_connected = nx.is_strongly_connected(G) is_weakly_connected = nx.is_weakly_connected(G) return (is_strongly_connected, is_weakly_connected) # Your Answer Here
def gen_network(graph,machines,basedata): """ Generates an LLD network from a graph distributing participants in a list of machines """ network = ET.Element('network') #network.set('type',graphtype) network.set('participants',str(graph.number_of_nodes())) network.set('edges',str(graph.size())) network.set('density',str(NX.density(graph))) network.set('connected',str(NX.is_weakly_connected(graph))) network.set('stronglyconnected',str(NX.is_strongly_connected(graph))) for node in graph.nodes_iter(): nodelement = ET.SubElement(network,'participant') nodelement.set('id','participant'+str(node)) hostelem = ET.SubElement(nodelement,'host') #hostelem.text = 'node'+str(int(node) % len(machines)) hostelem.text = machines[int(node) % len(machines)] portelem = ET.SubElement(nodelement,'port') portelem.text = str(20500+int(node)) baseelem = ET.SubElement(nodelement,'basedata') baseelem.text = basedata nodelement.append(gen_dynamic()) for source in gen_sources(graph,node): nodelement.append(source) return network
def get_largest_component(G, strongly=False): """ Return the largest weakly or strongly connected component from a directed graph. Parameters ---------- G : networkx multidigraph strongly : bool if True, return the largest strongly instead of weakly connected component Returns ------- networkx multidigraph """ original_len = len(list(G.nodes())) if strongly: # if the graph is not connected and caller did not request retain_all, retain only the largest strongly connected component if not nx.is_strongly_connected(G): G = max(nx.strongly_connected_component_subgraphs(G), key=len) else: # if the graph is not connected and caller did not request retain_all, retain only the largest weakly connected component if not nx.is_weakly_connected(G): G = max(nx.weakly_connected_component_subgraphs(G), key=len) return G
def test_synthetic_network_with_custom_stops(): # Load in the GeoJSON as a JSON and convert to a dictionary geojson_path = fixture('synthetic_east_bay.geojson') with open(geojson_path, 'r') as gjf: reference_geojson = json.load(gjf) # Add in specific, custom stops under new properties key custom_stops = [[-122.29225158691406, 37.80876678753658], [-122.28886127471924, 37.82341261847038], [-122.2701072692871, 37.83005652796547]] reference_geojson['features'][0]['properties']['stops'] = custom_stops G1 = load_synthetic_network_as_graph(reference_geojson) # Sanity check the outputs against the custom stops input assert len(list(G1.nodes())) == (len(custom_stops) + 2) assert len(list(G1.edges())) == (len(custom_stops) + 1) # Go back to the GeoJSON and set optional bidirectional flag reference_geojson['features'][0]['properties']['bidirectional'] = True G2 = load_synthetic_network_as_graph(reference_geojson) # We re-use the same stop nodes for both directions nodes = list(G2.nodes()) assert len(nodes) == (len(custom_stops) + 2) # Double the number of edges as before edges = list(G2.edges()) assert len(edges) == (len(custom_stops) + 1) * 2 # But now, by asking for a bidirectional graph, we can assert strong assert nx.is_strongly_connected(G2)
def component(self): rslt = {} if self.directed == 'directed': rslt['is_strongly_connected'] = nx.is_strongly_connected( self.graph) strong = nx.strongly_connected_components(self.graph) strong_nodes = [] for n in strong: strong_nodes.append(list(n)[0]) rslt['strongly_connected'] = strong_nodes rslt[ 'number_strongly_connected_components'] = nx.number_strongly_connected_components( self.graph) rslt['is_semiconnected'] = nx.is_semiconnected(self.graph) weak = nx.weakly_connected_components(self.graph) weak_nodes = [] for n in weak: weak_nodes.append(list(n)[0]) rslt['wealy_connected'] = weak_nodes rslt['is_weakly_connected'] = nx.is_weakly_connected(self.graph) rslt[ 'number_weakly_connected_components'] = nx.number_weakly_connected_components( self.graph) fname_component = self.DIR + '/component.json' with open(fname_component, "w") as f: json.dump(rslt, f, cls=SetEncoder, indent=2) print(fname_component)
def get_network_stats(g): """ Compute basic properties of a network :param g: input network as an NetworkX graph :return: dictionary with basic network properties as keys """ result = {} result['num_nodes'] = nx.number_of_nodes(g) result['num_edges'] = nx.number_of_edges(g) result['transitivity'] = nx.transitivity(g) if nx.is_directed(g): if nx.is_weakly_connected(g): result['average_shortest_path'] = nx.average_shortest_path_length( g) if nx.is_strongly_connected(g): result['diameter'] = nx.diameter(g) else: result['average_shortest_path'] = nx.average_shortest_path_length(g) result['diameter'] = nx.diameter(g) result['reciprocity'] = nx.reciprocity(g) return result
def find_all_path(self): # here we used a undirected graph to find path for # strongly conn graph and non-strongly conn graph if is_strongly_connected(self.create_graph('di')): graph = self.create_graph('di') else: graph = self.create_graph('') followers = set(self.nodes) - self.leaders followers_paths = dict() for node in followers: generator = all_simple_paths(graph, source=node, target=self.leaders) paths = list() for path in generator: paths.append(path) followers_paths[node] = paths # dict with list of lists self.followers_paths = followers_paths
def answer_three(): G = answer_one() part1 = nx.is_strongly_connected(G) part2 = nx.is_weakly_connected(G) return part1,part2
def connected_watts_strogatz_graph(n, k, p, tries=100): """Returns a connected Watts–Strogatz small-world graph. Attempts to generate a connected graph by repeated generation of Watts–Strogatz small-world graphs. An exception is raised if the maximum number of tries is exceeded. Parameters ---------- n : int The number of nodes k : int Each node is joined with its `k` nearest neighbors in a ring topology. p : float The probability of rewiring each edge tries : int Number of attempts to generate a connected graph. ----- """ for i in range(tries): G = watts_strogatz_graph(n, k, p) if nx.is_strongly_connected(G): return G # raise nx.NetworkXError('Maximum number of tries exceeded') print('Warning: Maximum number of tries exceeded: the network ' 'is NOT strongly connected') return G
def connected_directed_networkgraph(n=20): G = nx.DiGraph() nodes = [i for i in range(1,n+1)] cyclenodes = cycle(nodes) G.add_nodes_from(nodes) # add n nodes # ## agent につき1~2本の in/out edge を生成 # inum = np.random.choice((1,2,),1)[0] # onum = np.random.choice((1,2,),1)[0] for i in range(0,n): ## agent につき1~2本の in/out edge を生成 inum = np.random.choice((1,2,3,),1)[0] onum = np.random.choice((1,2,3,),1)[0] ## 各agentの周辺4 nodeへランダムに edge 生成 neighbors = cyclenodes.forward(i,4) + cyclenodes.backward(i,4) ineighbors = np.random.choice(neighbors,inum,replace=False) oneighbors = np.random.choice(neighbors,onum,replace=False) for j in ineighbors: G.add_edge(nodes[i],j) for j in oneighbors: G.add_edge(j,nodes[i]) if not nx.is_strongly_connected(G): raise Exception() else: print("connected") (adjMat, maxdeg) = __network_constructure(G) return (G, adjMat, maxdeg)
def reduce (self, collapse=False) : """Merge the nodes that avec the same DTX (distance to exit) - always if collapse is True - only if they are SCC themselves otherwise """ if collapse : classes = [v for k, v in sorted(self._nodeattr("dtx").items())] name = "dtx-min" def label (num, members) : return "(%s)" % num def attrs (num, members) : return {"dtx" : self.nodes[iter(members).next()]["dtx"], "shape" : "hexagon" if any(self.nodes[m]["init"] for m in members) else "circle"} else : classes = [] for nodes in self._nodeattr("dtx").values() : if nx.is_strongly_connected(self.subgraph(nodes)) : classes.append(nodes) else : classes.extend({n} for n in nodes) classes.sort(key=min) name = "dtx-scc" def label (num, members) : if len(members) == 1 : first = iter(members).next() return "%s/%s" % (first, self.nodes[first]["dtx"]) else : return "(%s)" % num def attrs (num, members) : return {"dtx" : self.nodes[iter(members).next()]["dtx"], "shape" : "hexagon" if any(self.nodes[m]["init"] for m in members) else "circle"} return ReducedKernelGraph.build(self, classes, label, attrs, name, "circo")
def load_graph(graph_name): folder_path = path.join('graphs', graph_name) graph_data = deserialize_dict( file_path=path.join(folder_path, 'graph_data.pkl.gz')) graph = ox.load_graphml(filename='graph.graphml', folder=folder_path) # graph = nx.MultiDiGraph(nx.read_graphml(path.join(folder_path, 'graph.graphml'), node_type=int)) if not nx.is_strongly_connected(graph): graph = ox.get_largest_component(graph, strongly=True) node_mapping = {node: i for i, node in enumerate(sorted(graph.nodes()))} graph = nx.relabel_nodes(graph, node_mapping) # Ensure nodes and edges are ordered consistently G = nx.MultiDiGraph() for node, data in sorted(graph.nodes(data=True), key=lambda t: t[0]): data['demand'] = 0 G.add_node(node, **data) for src, dst, data in sorted(graph.edges(data=True), key=lambda t: (t[0], t[1])): # Remove parallel edges and self-loops if src == dst or (src in G and dst in G[src]): continue # Dummy data for compatibility with plotter data['zero'] = 0 G.add_edge(src, dst, key=0, **data) G.graph['crs'] = graph_data['crs'] G.graph['name'] = graph_data['name'] G = ox.project_graph(G, to_crs=graph_data['crs']) return G.to_directed()
def create_connected_graph(N, E): G = nx.random_tree(N) if nx.is_connected(G) == False: raise Exception('Not a spanning tree!') for (i, j) in G.edges: #Adds data to spanning tree portion of graph p = random.random() q = 0.5 * p G.edges[i, j]['length'] = -np.log(p) G.edges[i, j]['interdicted_length'] = -np.log(q) + np.log(p) G_comp = nx.complete_graph(N) while G.number_of_edges() < 0.5 * E: #generates remaining edges with data edge = random.sample(list(set(G_comp.edges) - set(G.edges)), 1) for (i, j) in edge: p = random.random() q = 0.5 * p G.add_edge(i, j, length=-np.log(p), interdicted_length=-np.log(q) + np.log(p)) G = G.to_directed() if nx.is_strongly_connected(G) == False: raise Exception('Directed graph is not strongly connected') nx.draw(G, with_labels=True) plt.show() plt.savefig("path.png") return G
def get_relation_node_free_graph(self): if nx.is_strongly_connected(self): raise ArgGraphException(('Cannot produce relation node free graph.' 'Arggraph contains cycles.')) if False in [self.out_degree(node) <= 1 for node in self.nodes()]: raise ArgGraphException(('Cannot produce relation node free graph.' 'Nodes with multiple outgoing edges.')) a = ArgGraph(self) if ('relation-node-free' in a.graph and a.graph['relation-node-free'] == True): return a # reduce multi-source relations to adu.addsource->adu for rel_node in [ node for node, d in a.nodes(data=True) if a.out_degree(node) >= 1 and d['type'] == 'rel' ]: sources = sorted_nicely([ source for source in a.predecessors(rel_node) if a.node[source]['type'] == 'adu' ]) for source in sources[1:]: a.remove_edge(source, rel_node) a.add_edge(source, sources[0], type="add") # first reduce rel->rel remove_nodes = [] remove_edges = [] for (src, trg, d) in a.edges(data=True): if a.node[src]['type'] == 'rel' and a.node[trg]['type'] == 'rel': src_pre = a.predecessor_by_edge_type(src, 'src')[0] trg_pre = a.predecessor_by_edge_type(trg, 'src')[0] a.remove_edge(src, trg) a.add_edge(src_pre, trg_pre, type=d['type']) remove_edges.append(( src_pre, src, )) remove_nodes.append(src) for src, trg in remove_edges: a.remove_edge(src, trg) for node in remove_nodes: a.remove_node(node) # then reduce rel->adu (remaining relnodes) for (src, trg, d) in a.edges(data=True): if a.node[src]['type'] == 'rel' and a.node[trg]['type'] == 'adu': src_pre = a.predecessors(src)[0] a.add_edge(src_pre, trg, type=d['type']) a.remove_edge(src_pre, src) a.remove_edge(src, trg) a.remove_node(src) a.graph['relation-node-free'] = True return a
def test_load_call_graph_return_edges_file_granularity(self): # Act graph = self.target.load_call_graph(granularity=Gran.FILE) # Assert self.assertTrue(nx.is_strongly_connected(graph)) for (u, v) in nx.get_edge_attributes(graph, 'call'): self.assertTrue('return' in graph[v][u])
def check_strongly_connected(self): # Checks strongly connected components and returns the number of nodes in components with at least 2 nodes if nx.is_strongly_connected(self.network): print('Directed graph is strongly connected for all nodes') elif nx.is_weakly_connected(self.network): print('Directed graph is only weakly connected') else: print('Directed graph is not connected at all')
def prog_27(fname): graph = nx.DiGraph() f = open(fname) ns,es = map(int, f.readline().strip().split()) graph.add_nodes_from(range(1,ns+1)) for line in f: e1,e2 = map(int, line.strip().split()) graph.add_edge(e1,e2) f.close() print nx.is_strongly_connected(graph) # print 'xxxxxxxx' print nx.number_strongly_connected_components(graph)
def test_networkx_methods(): reducible_G = nx.DiGraph(np.matrix([[1,0],[0,1]])) print 'reducible- is strongly connected? ' + str(nx.is_strongly_connected(reducible_G)) #False print 'reducible- strongly connected components: ' + str(nx.strongly_connected_components(reducible_G)) #[[0], [1]] print 'reducible- is aperiodic? ' + str(nx.is_aperiodic(reducible_G)) #True irreducible_periodic_G = nx.DiGraph(np.matrix([[0,1],[1,0]])) print '\nirreducible_periodic- is strongly connected? ' + str(nx.is_strongly_connected(irreducible_periodic_G)) #True print 'irreducible_periodic- strongly connected components: ' + str(nx.strongly_connected_components(irreducible_periodic_G)) #[[0, 1]] print 'irreducible_periodic- is aperiodic? ' + str(nx.is_aperiodic(irreducible_periodic_G)) #False (2) ergodic_G = nx.DiGraph(np.matrix([[0,1,1,0],[1,0,0,1],[0,1,0,0],[0,1,0,0]])) modified_G = nx.DiGraph(salsa.get_matrix(ergodic_G, mat_type='hub', sparse=False)) print 'modified- is strongly connected? ' + str(nx.is_strongly_connected(modified_G)) #False print 'modified- strongly connected components: ' + str(nx.strongly_connected_components(modified_G)) #[[0, 2, 3], [1]] print 'modified- is aperiodic? ' + str(nx.is_aperiodic(modified_G)) #True return
def test_load_call_graph_return_edges_file_granularity(self): # Act test_graph = self.test_loader.load_call_graph(granularity=Gran.FILE) # Assert call_edges = nx.get_edge_attributes(test_graph, 'call') self.assertTrue(nx.is_strongly_connected(test_graph)) for (u, v) in call_edges: self.assertTrue('return' in test_graph[v][u])
def get_relation_node_free_graph(self): if nx.is_strongly_connected(self): raise ArgGraphException(('Cannot produce relation node free graph.' 'Arggraph contains cycles.')) if False in [self.out_degree(node) <= 1 for node in self.nodes()]: raise ArgGraphException(('Cannot produce relation node free graph.' 'Nodes with multiple outgoing edges.')) a = ArgGraph(self) if ('relation-node-free' in a.graph and a.graph['relation-node-free'] == True): return a # reduce multi-source relations to adu.addsource->adu for rel_node in [node for node, d in a.nodes(data=True) if a.out_degree(node) >= 1 and d['type'] == 'rel']: sources = sorted_nicely( [source for source in a.predecessors(rel_node) if a.node[source]['type'] == 'adu'] ) for source in sources[1:]: a.remove_edge(source, rel_node) a.add_edge(source, sources[0], type="add") # first reduce rel->rel remove_nodes = [] remove_edges = [] for (src, trg, d) in a.edges(data=True): if a.node[src]['type'] == 'rel' and a.node[trg]['type'] == 'rel': src_pre = a.predecessor_by_edge_type(src, 'src')[0] trg_pre = a.predecessor_by_edge_type(trg, 'src')[0] a.remove_edge(src, trg) a.add_edge(src_pre, trg_pre, type=d['type']) remove_edges.append((src_pre, src, )) remove_nodes.append(src) for src, trg in remove_edges: a.remove_edge(src, trg) for node in remove_nodes: a.remove_node(node) # then reduce rel->adu (remaining relnodes) for (src, trg, d) in a.edges(data=True): if a.node[src]['type'] == 'rel' and a.node[trg]['type'] == 'adu': src_pre = a.predecessors(src)[0] a.add_edge(src_pre, trg, type=d['type']) a.remove_edge(src_pre, src) a.remove_edge(src, trg) a.remove_node(src) a.graph['relation-node-free'] = True return a
def output_conectivity_info (graph, path): """Output connectivity information about the graph. graph : (networkx.Graph) path: (String) contains the path to the output file """ with open(path, 'w') as out: out.write('***Conectivity***\n') out.write('Is weakly connected: %s\n' % nx.is_weakly_connected(graph)) out.write('Number of weakly connected components: %d\n' % nx.number_weakly_connected_components(graph)) out.write('Is strongly connected: %s\n' % nx.is_strongly_connected(graph)) out.write('Number of strongly connected components: %d' % nx.number_strongly_connected_components(graph))
def test_eig_error(): #graph_file = '/home/michal/SALSA_files/tmp/real_run/graph_11' #G = gm.read_graph_from_file(graph_file) graph_list = [(354, 354, {'weight': 0.5}),\ (354, 13291, {'weight': 0.25}),\ (354, 11354, {'weight': 0.25}),\ (15204, 15204, {'weight': 0.5}),\ (15204, 14639, {'weight': 0.5}),\ (11210, 6898, {'weight': 0.25}),\ (11210, 11210, {'weight': 0.5}),\ (11210, 11354, {'weight': 0.25}),\ (13291, 354, {'weight': 0.5}),\ (13291, 13291, {'weight': 0.5}),\ (14639, 13236, {'weight': 0.16666666666666666}),\ (14639, 6898, {'weight': 0.16666666666666666}),\ (14639, 15204, {'weight': 0.25}),\ (14639, 14639, {'weight': 0.41666666666666663}),\ (6898, 6898, {'weight': 0.6111111111111112}),\ (6898, 13236, {'weight': 0.1111111111111111}),\ (6898, 11210, {'weight': 0.16666666666666666}),\ (6898, 14639, {'weight': 0.1111111111111111}),\ (13236, 6898, {'weight': 0.3333333333333333}),\ (13236, 13236, {'weight': 0.3333333333333333}),\ (13236, 14639, {'weight': 0.3333333333333333}),\ (11354, 11210, {'weight': 0.25}),\ (11354, 354, {'weight': 0.25}),\ (11354, 11354, {'weight': 0.5})] #(11354, 11354, {'weight': 0.5})] G = nx.DiGraph(graph_list) #print G.edges(data=True) print '--- eig_calc: is sub graph stochastic? ' + str(gm.check_if_stochastic_matrix(nx.to_numpy_matrix(G)))#; sys.stdout.flush() print '--- eig_calc: is sub graph strongly connected? ' + str(nx.is_strongly_connected(G))#; sys.stdout.flush() print '--- eig_calc: is sub graph aperiodic? ' + str(nx.is_aperiodic(G));# sys.stdout.flush() #np_mat = nx.to_numpy_matrix(G) #print 'det= '+ str(np.linalg.det(np_mat)) print salsa.eig_calc(G) '''try: print salsa.eig_calc(G) except RuntimeError: max_weight = max(e[2]['weight'] for e in G.edges_iter(data=True)) noise = 1e-13 for e in G.edges_iter(data=True): if e[2]['weight'] == max_weight: e[2]['weight'] += noise if not gm.check_if_stochastic_matrix(nx.to_numpy_matrix(G)): nx.stochastic_graph(G, copy=False) print salsa.eig_calc(G)''' return
def test_enterprise_graph_properties(self): """ EnterpriseTopology graph must be directed, containt 1577 nodes, be strongly connected and the paths need to be symmetric""" topo = self.topo self.assertTrue(topo.graph.is_directed()) self.assertEqual(len(topo.graph.nodes()) + len(topo.leaves), 1577) self.assertTrue(nx.is_strongly_connected(topo.graph)) for src in topo.graph.nodes(): for dst in topo.graph.nodes(): self.assertEqual(topo.paths[src][dst], list(reversed(topo.paths[dst][src])))
def mcr_apx(g, upper= True, estimate_mcr = None): assert g.is_consistent() assert nx.is_strongly_connected(g) # mrsdfg = transform.multi_rate_equivalent(g) pess = transform.single_rate_apx(g, upper) mg = make_marked_graph( pess ) #print("size of HSDFG: {}".format(mg.number_of_nodes())) try: ratio, cycle, _ = mcr.compute_mcr( mg, estimate = Fraction( estimate_mcr, g.tpi ) if estimate_mcr is not None else None) except mcr.InfeasibleException as ex: ratio, cycle = None, ex.cycle if ratio is None: return None, cycle else: return ratio * g.tpi, cycle
def get_largest_component(G, strongly=False): """ Return a subgraph of the largest weakly or strongly connected component from a directed graph. Parameters ---------- G : networkx multidigraph strongly : bool if True, return the largest strongly instead of weakly connected component Returns ------- G : networkx multidigraph the largest connected component subgraph from the original graph """ start_time = time.time() original_len = len(list(G.nodes())) if strongly: # if the graph is not connected retain only the largest strongly connected component if not nx.is_strongly_connected(G): # get all the strongly connected components in graph then identify the largest sccs = nx.strongly_connected_components(G) largest_scc = max(sccs, key=len) G = induce_subgraph(G, largest_scc) msg = ('Graph was not connected, retained only the largest strongly ' 'connected component ({:,} of {:,} total nodes) in {:.2f} seconds') log(msg.format(len(list(G.nodes())), original_len, time.time()-start_time)) else: # if the graph is not connected retain only the largest weakly connected component if not nx.is_weakly_connected(G): # get all the weakly connected components in graph then identify the largest wccs = nx.weakly_connected_components(G) largest_wcc = max(wccs, key=len) G = induce_subgraph(G, largest_wcc) msg = ('Graph was not connected, retained only the largest weakly ' 'connected component ({:,} of {:,} total nodes) in {:.2f} seconds') log(msg.format(len(list(G.nodes())), original_len, time.time()-start_time)) return G
def all_eulerian_cycles(g,start=None) : if not isinstance(g,nx.MultiDiGraph) : raise Exception("expect nx.MultiDiGraph") if not nx.euler.is_eulerian(g) : raise Exception("g is not eulerian") all_graphs = set([g]) while True: tosimplify_g = next(ifilter(lambda gr : not is_simple(gr), all_graphs),None) if not tosimplify_g : break multivertex = next(ifilter(lambda v : in_degree(tosimplify_g,v) > 1,tosimplify_g.nodes()),None) assert multivertex for incoming in tosimplify_g.in_edges(multivertex) : for outgoing in tosimplify_g.out_edges(multivertex) : #modify simplify_g to add the bypass edge newvertex = Node(multivertex.kmer) tosimplify_g.add_edge(incoming[0],newvertex) tosimplify_g.add_edge(newvertex,outgoing[1]) tosimplify_g.remove_edge(*incoming) tosimplify_g.remove_edge(*outgoing) simplified = tosimplify_g.copy() if nx.is_strongly_connected(simplified) : all_graphs.add(simplified) #else : #print "not sc : ", simplified.edges() #revert all modifications tosimplify_g.add_edge(*outgoing) tosimplify_g.add_edge(*incoming) tosimplify_g.remove_edge(newvertex,outgoing[1]) tosimplify_g.remove_edge(incoming[0],newvertex) assert len(tosimplify_g.in_edges(newvertex)) == 0 assert len(tosimplify_g.out_edges(newvertex)) == 0 tosimplify_g.remove_node(newvertex) all_graphs.remove(tosimplify_g) for g in all_graphs : assert nx.euler.is_eulerian(g) start = next(ifilter(lambda n : n.start==True,g.nodes()),None) assert start != None yield nx.euler.eulerian_circuit(g,start)
def validate_cuts(G, s, t, solnValue, partition, capacity, flow_func): assert_true(all(n in G for n in partition[0]), msg=msg.format(flow_func.__name__)) assert_true(all(n in G for n in partition[1]), msg=msg.format(flow_func.__name__)) cutset = compute_cutset(G, partition) assert_true(all(G.has_edge(u, v) for (u, v) in cutset), msg=msg.format(flow_func.__name__)) assert_equal(solnValue, sum(G[u][v][capacity] for (u, v) in cutset), msg=msg.format(flow_func.__name__)) H = G.copy() H.remove_edges_from(cutset) if not G.is_directed(): assert_false(nx.is_connected(H), msg=msg.format(flow_func.__name__)) else: assert_false(nx.is_strongly_connected(H), msg=msg.format(flow_func.__name__))
def validate_ibgp(anm): import networkx as nx #TODO: repeat for ibgp v6 #TODO: test if overlay is present, if not then warn if not anm.has_overlay("ibgp_v4"): return # no ibgp v4 - eg if ip addressing disabled g_ibgp_v4 = anm['ibgp_v4'] for asn, devices in ank_utils.groupby("asn", g_ibgp_v4): asn_subgraph = g_ibgp_v4.subgraph(devices) graph = asn_subgraph._graph # get subgraph if not nx.is_strongly_connected(graph): g_ibgp_v4.log.warning("iBGP v4 topology for ASN%s is disconnected" % asn) #TODO: list connected components - but not the primary? else: g_ibgp_v4.log.debug("iBGP v4 topology for ASN%s is connected" % asn)
def nodes_by_eccentricity(graph): if len(graph) == 1: return graph.nodes() # need to crop the global shortest paths otherwise get #NetworkXError: Graph not connected: infinite path length eccentricities = {} try: eccentricities = nx.eccentricity(graph) except nx.exception.NetworkXError: # If not strongly connected, perform eccentricities per connected component if not nx.is_strongly_connected(graph): #TODO: provide this function inside ANK, add memoization for intensive operation for component_nodes in nx.strongly_connected_components(graph): eccentricities.update(nx.eccentricity(graph.subgraph(component_nodes))) # sort nodes by name, stability sort ensures that lexical order is used as tie-breaker for equal eccen. nodes_sorted = sorted(graph.nodes(), key = lambda x: x.fqdn) return sorted(nodes_sorted, key = lambda n: eccentricities[n])
def is_connected(C): """ Return `True` if the square connection matrix `C` is connected, i.e., every unit is reachable from every other unit, otherwise `False`. Note ---- This function only performs the check if the NetworkX package is available: https://networkx.github.io/ """ if nx is None: return True G = nx.from_numpy_matrix(C, create_using=nx.DiGraph()) return nx.is_strongly_connected(G)
def is_eulerian(G): """Return True if G is an Eulerian graph, False otherwise. An Eulerian graph is a graph with an Eulerian circuit. Parameters ---------- G : graph A NetworkX Graph Examples -------- >>> nx.is_eulerian(nx.DiGraph({0:[3], 1:[2], 2:[3], 3:[0, 1]})) True >>> nx.is_eulerian(nx.complete_graph(5)) True >>> nx.is_eulerian(nx.petersen_graph()) False Notes ----- This implementation requires the graph to be connected (or strongly connected for directed graphs). """ if G.is_directed(): # Every node must have equal in degree and out degree for n in G.nodes_iter(): if G.in_degree(n) != G.out_degree(n): return False # Must be strongly connected if not nx.is_strongly_connected(G): return False else: # An undirected Eulerian graph has no vertices of odd degrees for v, d in G.degree_iter(): if d % 2 != 0: return False # Must be connected if not nx.is_connected(G): return False return True
def test_on_directed_strongly_connected_graph(self): """ Test on a small directed strongly connected graph. """ # make the strongly connected directed graph: params_dscg = {'num_nodes': 200, 'num_edges': 1800, 'seed': 0, 'directed': True} graph = make_graph(**params_dscg) assert(nx.is_strongly_connected(graph)) # first run dijkstra_sssp dist, _ = dijkstra_sssp.solve(graph, source=0, weight='weight') # then networkx's dijkstra nx_dist = nx.single_source_dijkstra_path_length(graph, source=0, weight='weight') # finally, compare results inf = float('inf') for node in graph.nodes_iter(): if dist[node] != inf: # node was reachable self.assertEqual(dist[node], nx_dist[node]) else: # node was unreachable self.assertTrue(node not in nx_dist) self.assertEqual(dist[node], inf)
def _transition_matrix(G, nodelist=None, weight='weight', walk_type=None, alpha=0.95): """Returns the transition matrix of G. This is a row stochastic giving the transition probabilities while performing a random walk on the graph. Depending on the value of walk_type, P can be the transition matrix induced by a random walk, a lazy random walk, or a random walk with teleportation (PageRank). Parameters ---------- G : DiGraph A NetworkX graph nodelist : list, optional The rows and columns are ordered according to the nodes in nodelist. If nodelist is None, then the ordering is produced by G.nodes(). weight : string or None, optional (default='weight') The edge data key used to compute each value in the matrix. If None, then each edge has weight 1. walk_type : string or None, optional (default=None) If None, `P` is selected depending on the properties of the graph. Otherwise is one of 'random', 'lazy', or 'pagerank' alpha : real (1 - alpha) is the teleportation probability used with pagerank Returns ------- P : NumPy array transition matrix of G. Raises ------ NetworkXError If walk_type not specified or alpha not in valid range """ import scipy as sp from scipy.sparse import identity, spdiags if walk_type is None: if nx.is_strongly_connected(G): if nx.is_aperiodic(G): walk_type = "random" else: walk_type = "lazy" else: walk_type = "pagerank" M = nx.to_scipy_sparse_matrix(G, nodelist=nodelist, weight=weight, dtype=float) n, m = M.shape if walk_type in ["random", "lazy"]: DI = spdiags(1.0 / sp.array(M.sum(axis=1).flat), [0], n, n) if walk_type == "random": P = DI * M else: I = identity(n) P = (I + DI * M) / 2.0 elif walk_type == "pagerank": if not (0 < alpha < 1): raise nx.NetworkXError('alpha must be between 0 and 1') # this is using a dense representation M = M.todense() # add constant to dangling nodes' row dangling = sp.where(M.sum(axis=1) == 0) for d in dangling[0]: M[d] = 1.0 / n # normalize M = M / M.sum(axis=1) P = alpha * M + (1 - alpha) / n else: raise nx.NetworkXError("walk_type must be random, lazy, or pagerank") return P
import networkx as nx G = nx.DiGraph() u = [0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9] v = [1, 5, 7, 7, 8, 9, 0, 3, 3, 0, 0, 4, 8, 9, 9, 2, 5, 0, 1, 5, 3, 4, 6, 9, 2, 8, 9, 4, 6, 6, 6, 6, 3, 3, 4, 6, 7, 7, 0, 7] w = zip (u,v) #w = [(0,1),(0,1),(1,2),(1,3),(1,4),(1,5),(1,5),(1,6),(2,0),(2,0),(3,2),(3,2),(4,3),(4,7),(5,4),(5,9),(5,9),(6,7),(6,9),(7,3),(7,8),(8,1),(8,7),(9,6),(9,8)] G.add_edges_from(w) p = nx.is_strongly_connected(G) print(p) for i in G.edges(): print("\n") for path in nx.all_simple_paths(G,source=i[0], target=i[1]): print(i) print(path)
def backward_reachability(self,system,inputs,show_dfs=False,verbose=0,max_fixed_point_size=4,environment=None,plt=None): accepted_set = self.graph['accept'] initial_state_found = False accepted_set_circled = False control_dict = {str(u):u for u in inputs} initial_control_set = set([(a,None) for a in accepted_set]) initial_accepted_set = accepted_set initial_fixed_point_iterator = DijkstraFixedPoint(self,self.generate_all_predecessor_set(initial_accepted_set),initial_accepted_set) to_visit = collections.deque([(initial_control_set,initial_fixed_point_iterator)]) iter_loop = 0 while to_visit and not (initial_state_found and accepted_set_circled): e = to_visit[-1] accepted_control,fixed_point_iterator = e accepted_set = set([x[0] for x in accepted_control]) if verbose==2: print " "*len(to_visit) + "| iter "+str(len(to_visit)) if verbose==1: pass found,nodes = fixed_point_iterator.next_fixed_point(max_fixed_point_size) if not found: if len(to_visit)>1: to_visit.pop() else: print "No solution found" return iter_loop += 1 if found: #print "."*len(accepted_set) + "|"*len(nodes) outgoing_edges = [(u,v) for u,l in nodes.items() for v in self.get_labelled_successors(u)[l] if v in accepted_set] #need_fairness = not all([u[0]==v[0] for u,v in outgoing_edges]) need_fairness = not all([any([v[0]==u[0] for v in self.get_labelled_successors(n)[l] if (v in accepted_set) and v!=u]) for n,l in nodes.items() for u in self.get_labelled_successors(n)[l] if u not in accepted_set]) if verbose==3: print "Need Fairness:",need_fairness if need_fairness: print "!!!!!!!!!!!!!!!!!!", iter_loop controls = [control_dict[l] for l in nodes.values()] sG = nx.DiGraph() # convert = {n:i for i,n in enumerate(nodes.keys())} # edges = [] keep_edges = [(u,v)for u,l in nodes.items() if l!=None for v in self.get_labelled_successors(u)[l]] sG = nx.DiGraph(self.subgraph(nodes.keys())) sG.remove_edges_from(set(sG.edges()).difference(set(keep_edges))) try: nx.set_node_attributes(sG,'control',{n:control_dict[l] for n,l in nodes.items() if n in sG.nodes()}) except KeyError: print sG.edges() print nodes.keys() raise KeyError # check if accepted states are accessible from every nodes: # print nx.is_strongly_connected(sG),self.subgraph(nodes.keys()).edges() if nx.is_strongly_connected(sG)==False: continue if verbose==2: print sG.edges(data=True) #fair_control = system.is_loop_fair(controls) fair_control = system.is_graph_fair(sG) if fair_control or need_fairness==False: if verbose==2: print "need_fairness",need_fairness,"fair_control",fair_control,[str(c) for c in controls] print "Add fair loop",nodes X = accepted_control.union(set(nodes.items())) node_set = [x[0] for x in X] Y = self.generate_all_predecessor_set(node_set) it = DijkstraFixedPoint(self,Y,node_set) to_visit.append((X,it)) else: if verbose==2: print "Unfair loop",controls new_set = accepted_set.union(set(nodes.keys())) if self.graph['initial'].issubset(new_set): initial_state_found = True if verbose==2: print "Path to initial_set found!!!!" cycle_accept_set = [(u,l) for u in self.graph['accept'] for l,succ in self.get_labelled_successors(u).items() if set(succ).issubset(new_set)] if environment: soluce = accepted_control.union(set(nodes.items())) print soluce node_controls = {n:(control_dict[l] if l else None) for n,l in soluce} environment.show_controls(plt,node_controls,"automaton/iter"+str(iter_loop)+".png") print "Accept cycle",len(cycle_accept_set),"Initial set found",self.graph['initial'].issubset(new_set) if cycle_accept_set and self.graph['initial'].issubset(new_set): soluce = accepted_control.union(set(nodes.items())) print "Solution found!!!" print sG.edges() break if verbose==0: sys.stdout.write(str(len(accepted_set)) +"/" +str(len(nodes)) + "\t" + str(iter_loop)+'\r') sys.stdout.flush() if show_dfs: c = {n:"red" for n in accepted_set} c.update({n:"green" for n in nodes}) ec = {e:"red" for e in [(u,v) for u,l in accepted_control if l!=None for v in self.get_labelled_successors(u)[l]]} ec.update( {e:"blue" for e in [(u,v) for u,l in nodes.items() if l!=None for v in self.get_labelled_successors(u)[l]]} ) self.show("buchi",colors=c,edges_color=ec) raw_input() print len(to_visit) if verbose==3: G = copy.deepcopy(self) keep_edges = [(u,v)for u,l in nodes.items() if l!=None for v in self.get_labelled_successors(u)[l]] keep_nodes = [n for e in keep_edges for n in e] print keep_nodes G.remove_nodes_from(list(set(G.nodes()).difference(set(keep_nodes)))) G.remove_edges_from(list(set(G.edges()).difference(set(keep_edges)))) G.graph['accept'] = G.graph['accept'].intersection(set(keep_nodes)) G.graph['initial'] = G.graph['initial'].intersection(set(keep_nodes)) c = {n:"red" for n in accepted_set.intersection(set(keep_nodes))} c.update({n:"green" for n in set(nodes.keys()).intersection(set(keep_nodes))}) ec = {e:"blue" for e in [(u,v) for u,l in nodes.items() if l!=None for v in self.get_labelled_successors(u)[l]] if e in keep_edges} G.show("buchi",colors=c,edges_color=ec) cycle_accept_set = [(u,l) for u in self.graph['accept'] for l,succ in self.get_labelled_successors(u).items() if set(succ).issubset(new_set)] if verbose==2: print cycle_accept_set solution = {u:l for u,l in soluce} for u,l in cycle_accept_set: solution[u] = l if verbose==2: print solution plan = copy.deepcopy(self) for n,l in solution.items(): plan.remove_labeled_edge_except(n,l) #plan.show("plan_all") plan.remove_ambiguites() plan.minimize() # plan.show("plan2") # return if verbose==2: print self.graph['initial'] nx.set_node_attributes(plan,"apply_control",None) control = nx.get_node_attributes(plan,"apply_control") for n in plan.nodes(): c = list(plan.get_successor_labels(n)) if len(c)==0: print "Control not found:", n, s else: s = c[0] if len(c)!=1: print "Too many controls",n,c s = c[0] control[n] = control_dict[s] nx.set_node_attributes(plan,"apply_control",control) return plan
def test_is_strongly_connected(self): for G, C in self.gc: if len(C) == 1: assert_true(nx.is_strongly_connected(G)) else: assert_false(nx.is_strongly_connected(G))