def test_complete(): """ In complete graphs each node is a dominating set. Thus the dominating set has to be of cardinality 1. """ K4 = nx.complete_graph(4) assert_equal(len(nx.dominating_set(K4)), 1) K5 = nx.complete_graph(5) assert_equal(len(nx.dominating_set(K5)), 1)
def test_complete(): """ In complete graphs each node is a dominating set. Thus the dominating set has to be of cardinality 1. """ K4 = nx.complete_graph(4) assert len(nx.dominating_set(K4)) == 1 K5 = nx.complete_graph(5) assert len(nx.dominating_set(K5)) == 1
def dominant_set_topic_rank(): #dominant_set conn = sqlite3.connect("zhihu.db") following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 50000) and user_url in (select user_url from User where agree_num > 50000)', conn) #following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 10000) and user_url in (select user_url from User where agree_num > 10000)', conn) G = nx.DiGraph() for d in following_data.iterrows(): G.add_edge(d[1][0], d[1][1]) dominant_set = nx.dominating_set(G) print 'user number in dominant set:', len(dominant_set) #topics answered by users in dominant_set user_topic_data = pd.read_sql('select user_url, topic from UserTopic', conn) topicdict = defaultdict(int) i = 0#counter for row in user_topic_data.iterrows(): user_url = row[1][0] topic = row[1][1] if user_url in dominant_set: topicdict[topic] += 1 i += 1 #if i % 100 == 0: #print i conn.close() topicsorted = sorted(topicdict.items(), key=lambda x: x[1], reverse=True) # topic top 100 for t in topicsorted[:100]: print t[0],t[1]
def dominant_set_topic_rank(): ''' 热门话题分析 ''' conn = sqlite3.connect("zhihu.db") following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 30000) and user_url in (select user_url from User where agree_num > 30000)', conn) G = nx.DiGraph() for d in following_data.iterrows(): G.add_edge(d[1][0], d[1][1]) #获得支配集 dominant_set = nx.dominating_set(G) print('支配集中的用户数量:', len(dominant_set)) #支配集中用户回答的话题 user_topic_data = pd.read_sql('select user_url, topic from UserTopic', conn) topicdict = defaultdict(int) i = 0 #counter for row in user_topic_data.iterrows(): user_url = row[1][0] topic = row[1][1] if user_url in dominant_set: topicdict[topic] += 1 i += 1 #if i % 100 == 0: #print i conn.close() topicsorted = sorted(topicdict.items(), key=lambda x: x[1], reverse=True) #前10的话题 for t in topicsorted[:10]: print(t[0],t[1])
def ds_spt(G, start_node): """ find a dominating set, from which we construct a subgraph by the union of all pairwise shortest paths. then run trimMST on the subgraph. """ subgraph = nx.Graph() ds = nx.dominating_set(G, start_node) subgraph.add_nodes_from(ds) shortest_paths = nx.all_pairs_dijkstra_path(G) shortest_paths = dict(shortest_paths) # add all edges/nodes in shortest paths to subgraph for source in ds: for target in ds: if source != target: # path is a list of nodes along the s-t path path = shortest_paths[source][target] for i in range(len(path) - 1): node_from = path[i] node_to = path[i + 1] weight = G[node_from][node_to]['weight'] if not subgraph.has_node(node_from): subgraph.add_node(node_from) if not subgraph.has_node(node_to): subgraph.add_node(node_to) if not subgraph.has_edge(node_from, node_to): subgraph.add_edge(node_from, node_to, weight=weight) #tree = trimMST.solve(subgraph) tree = nx.minimum_spanning_tree(subgraph) return tree
def dominant_set_topic_rank(): #dominant_set conn = sqlite3.connect("zhihu.db") following_data = pd.read_sql( 'select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 50000) and user_url in (select user_url from User where agree_num > 50000)', conn) #following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 10000) and user_url in (select user_url from User where agree_num > 10000)', conn) G = nx.DiGraph() for d in following_data.iterrows(): G.add_edge(d[1][0], d[1][1]) dominant_set = nx.dominating_set(G) print 'user number in dominant set:', len(dominant_set) #topics answered by users in dominant_set user_topic_data = pd.read_sql('select user_url, topic from UserTopic', conn) topicdict = defaultdict(int) i = 0 #counter for row in user_topic_data.iterrows(): user_url = row[1][0] topic = row[1][1] if user_url in dominant_set: topicdict[topic] += 1 i += 1 #if i % 100 == 0: #print i conn.close() topicsorted = sorted(topicdict.items(), key=lambda x: x[1], reverse=True) # topic top 100 for t in topicsorted[:100]: print t[0], t[1]
def graph_stats(G): result = {} try: # https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.flow.min_cost_flow.html#networkx.algorithms.flow.min_cost_flow # demand maybe from strongly_connected_components # TODO: revisit this # calculate_demand(G) # result["min_cost_flow"] = nx.min_cost_flow(G, capacity="inverse_weight", weight="weight") result["pagerank"] = nx.pagerank(G) result["betweenness_centrality"] = nx.betweenness_centrality(G) result["degree_centrality"] = nx.degree_centrality(G) result["eccentricity"] = nx.eccentricity(G) result["average_node_connectivity"] = nx.average_node_connectivity(G) result["dominating_set"] = nx.dominating_set(G) result["strongly_connected_components"] = list(nx.strongly_connected_components(G)) except Exception: pass return result
def _generate_nlist(): G = self.graph # TODO: imaginative, but shit. revise. isolates = set(nx.isolates(G)) independent = set(nx.maximal_independent_set(G)) - isolates dominating = set(nx.dominating_set(G)) - independent - isolates rest = set(G.nodes()) - dominating - independent - isolates nlist = list(map(sorted, filter(None, (isolates, independent, dominating, rest)))) return nlist
def DirectedGraphFeature(df, dfOrigin, part): indexs, files = df.index, dfOrigin.file_id.unique() for col in apiSet: df[col + '_graph_degree'] = 0 df[col + '_graph_in_degree'] = 0 df[col + '_graph_cental_degree'] = 0 df[col + '_graph_center'] = 0 for index, file in zip(indexs, files): X = pd.read_csv('./' + part + '/' + str(index) + '.csv') api = X.groupby(by='tid').apply(lambda x: ' '.join(x.api)) api = pd.DataFrame(api) api.rename(columns={0: 'api_call'}, inplace=True) G = nx.DiGraph() for row in api.index: apiCall = (api.loc[row, 'api_call']).split(' ') for i in range(len(apiCall) - 1): G.add_edge(apiCall[i], apiCall[i + 1]) if (len(G) <= 1): continue df.loc[index, 'dir_density'] = nx.density(G) df.loc[index, 'dir_order'] = G.order() df.loc[index, 'dir_size'] = G.size() #(left, right, cover_size) = {}, {}, 0 #if (bipartite.is_bipartite(G)): #left, right = nx.bipartite.sets(G) #matching = nx.bipartite.maximum_matching(G) #vertex_cover = nx.bipartite.to_vertex_cover(G, matching) #cover_size = len(set(G) - vertex_cover) #print(left, right, cover_size) #df.loc[index, 'dir_left'] = len(left) #df.loc[index, 'dir_gright'] = len(right) #df.loc[index, 'dir_graph_degree'] = cover_size df.loc[index, 'dir_dominating_set'] = len(set(nx.dominating_set(G))) df.loc[index, 'dir_transitivity'] = nx.transitivity(G) df.loc[index, 'dir_is_strongly_connected'] = int(nx.is_strongly_connected(G)) df.loc[index, 'dir_is_weakly_connected'] = int(nx.is_weakly_connected(G)) Degree = G.degree() OutDegree = nx.out_degree_centrality(G) CentalDrgree = nx.degree_centrality(G) for x in G.nodes(): df.loc[index, x+'_graph_degree'] = Degree[x] df.loc[index, x+'_graph_in_degree'] = OutDegree[x] df.loc[index, x+'_graph_cental_degree'] = CentalDrgree[x] print(index) return df
def get_dominating_sets(G2): """get all possible dominating sets by iterating all nodes""" dominating_sets = set() # list of sets for start_with in G2: dominating_set = frozenset( nx.dominating_set(G2, start_with) ) # sets of sets, the inner sets must be frozenset objects. dominating_sets.add(dominating_set) return dominating_sets
def _post_dominate(self, reversed_graph, n1, n2): """ Checks whether n1 post-dominates n2 in the *original* (not reversed) graph :param reversed_graph: The reversed networkx.DiGraph instance :param n1: Node 1 :param n2: Node 2 :return: True/False """ ds = networkx.dominating_set(reversed_graph, n1) return n2 in ds
def _post_dominate(self, reversed_graph, n1, n2): """ Checks whether `n1` post-dominates `n2` in the *original* (not reversed) graph. :param reversed_graph: The reversed networkx.DiGraph instance. :param n1: Node 1. :param n2: Node 2. :returns: True/False. """ ds = networkx.dominating_set(reversed_graph, n1) return n2 in ds
def _post_dominate(reversed_graph, n1, n2): """ Checks whether `n1` post-dominates `n2` in the *original* (not reversed) graph. :param reversed_graph: The reversed networkx.DiGraph instance. :param n1: Node 1. :param n2: Node 2. :returns: True/False. """ ds = networkx.dominating_set(reversed_graph, n1) return n2 in ds
def greedy_summarize(G, k, c, degree_weight): selected = [] dom = [] #print("g1: " + str(G.nodes[1])) largest_degree_vs = sorted(G.nodes.keys(), key=lambda i: G.nodes[i]['weight'] + G.degree()[ i] * degree_weight)[-k:] for i in largest_degree_vs: depth = int(G.nodes[i]['weight'] * c) selected += bfs_expansion(G, i, depth_limit=depth) dom += nx.dominating_set(G, i) selected = set(selected).intersection(set(dom)) return nx.subgraph(G, selected)
def dominate(G): def prune(g): nonlocal min_dist, minT copy = g.copy() try: cycles = nx.find_cycle(g) for cycle in cycles: e = random.choice(cycle) copy.remove_edge(e[0], e[1]) if is_valid_network(G, copy): d = average_pairwise_distance_fast(copy) if d < min_dist: min_dist = d minT = copy.copy() prune(copy) except: e = random.choice(g.edges()) copy.remove_edge(e[0], e[1]) if is_valid_network(G, copy): d = average_pairwise_distance_fast(copy) if d < min_dist: min_dist = d minT = copy.copy() prune(copy) S = nx.dominating_set(G) edges_between = [] for e in G.edges(): if e[0] in S and e[1] in S: edges_between.append T = nx.Graph() for node in S: T.add_node(node) for e in edges_between: T.add_edge(e[0], e[1]) if is_valid_network(G, T): minT = T.copy() else: minT = nx.minimum_spanning_tree(G) min_dist = average_pairwise_distance(minT) for _ in range(300): prune(T) return minT
def print_stats(G): try: calculate_demand(G) print("min_cost_flow") # https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.flow.min_cost_flow.html#networkx.algorithms.flow.min_cost_flow # demand maybe from strongly_connected_components print(nx.min_cost_flow(G, capacity="inverse_weight", weight="weight")) print("pagerank") print(nx.pagerank(G)) print("average_node_connectivity") print(nx.average_node_connectivity(G)) print("dominating_set") print(nx.dominating_set(G)) print("strongly_connected_components") print(list(nx.strongly_connected_components(G))) except Exception: pass
def dominating_set_strategy(G, num_seeds): ''' Picks top degreed nodes from dominating set(ds) of input graph. If there are less nodes in the ds than num_seeds, then we pick from top degreed nodes of the input graph. A dominating set for a graph G = (V, E) is a node subset D of V such that every node not in D is adjacent to at least one member of D. Args: G -- the input graph num_seeds -- the number of seed nodes to select Returns: list of output nodes based on DS strategy ''' ds_nodes = nx.dominating_set(G) nodes_to_remove = G.nodes() - ds_nodes subgraph = G.copy() subgraph.remove_nodes_from(nodes_to_remove) assert (len(G.nodes()) > len(subgraph.nodes())) number_of_nodes = num_seeds if len(ds_nodes) < num_seeds: number_of_nodes = len(ds_nodes) centralities_dict = nx.degree_centrality(subgraph) sorted_centralities = nlargest(number_of_nodes, centralities_dict.items(), key=operator.itemgetter(1)) node_keys = [i[0] for i in sorted_centralities] nodes_top_degrees = degree_centrality_strategy(G, num_seeds) # In case we need more seed nodes, we simply pull from the top degreed nodes of the input graph i = 0 while (len(node_keys) != num_seeds): if nodes_top_degrees[i] not in node_keys: node_keys.append(nodes_top_degrees[i]) i += 1 assert (len(node_keys) == num_seeds) return node_keys
def compute_features(self): self.add_feature( "size_dominating_set", lambda graph: len(list(nx.dominating_set(graph))), "The number of nodes in the dominating set", InterpretabilityScore(3), ) self.add_feature( "size_min_dominating_set", lambda graph: len(list(min_weighted_dominating_set(graph))), "The number of nodes in the minimum weighted dominating set", InterpretabilityScore(3), ) self.add_feature( "size_min_edge_dominating_set", lambda graph: len(list(min_edge_dominating_set(graph))), "The number of nodes in the minimum edge dominating set", InterpretabilityScore(3), )
def dominating_set_strategy(G, num_seeds, num_rounds): dominating_set = list(nx.dominating_set(G)) # Obtaining seeds nodes from selecting the highest deg from the dominating seeds = [] degrees = G.degree(dominating_set) i = 0 for k in sorted(degrees, key=lambda k: k[1], reverse=True): seeds.append(k[0]) i += 1 if i >= num_seeds: break # if the size of dominating set is smaller than num of seed, randomly # select if len(seeds) < num_rounds: remaining_nodes = list(G.nodes()) for node in dominating_set: if node in remaining_nodes: remaining_nodes.remove(node) np.random.shuffle(remaining_nodes) for i in range(num_rounds - len(seeds)): seeds.append(remaining_nodes[i]) return seeds * num_rounds
def playing(airports, routes): G = create_route_graph(airports, routes) print(G[1555][344]) G.edge[1555][344]['color'] = 'blue' # defining a new attribute for an edge print(G[1555][344]) print(G[1555]) # all connections print(nx.info(G)) print(G.degree(1555)) print(G.neighbors(1555)) print(nx.info(G, 1555)) print(nx.has_path(G, source=1555, target=18)) # Reykjavik print(nx.has_path(G, source=1555, target=3416)) print(nx.has_path(G, source=1555, target=3878)) print(nx.dijkstra_path(G, 1555, 18)) print(nx.is_connected(G)) low = min(nx.degree(G)) high = max(nx.degree(G)) print(low, high) # dh = nx.degree_histogram(G) # for i in range(low, len(dh)): # bar = ''.join(dh[i] * ['*']) # print("%2s (%2s) %s" % (i, dh[i], bar)) I = G.copy() for node in nx.nodes(I): if (I.node[node]['country'] != "Italy"): I.remove_node(node) print(nx.info(I)) # [len(c) for c in sorted(nx.connected_components(I), key=len, reverse=True)] # for c in sorted(nx.connected_components(I)): # print(c) print(len(nx.dominating_set(I, 1555))) # plt.hist(sorted(nx.degree(G).values()), bins=50) # plt.show(block=True) # # plt.hist(sorted(nx.degree(I).values()), bins=20) # plt.show(block=True) # # plt.clf() # nx.draw(I) # plt.show(block=True) for node in I.nodes(): I.node[node]['pos'] = (I.node[node]['long'], I.node[node]['lat']) # plt.clf() # nx.draw(I, nx.get_node_attributes(I, 'pos')) # plt.show() plt.clf() nx.draw_networkx_nodes(I, nx.get_node_attributes(I, 'pos'), node_shape='.', node_size=50) nx.draw_networkx_edges(I, nx.get_node_attributes(I, 'pos'), width=0.2, alpha=0.5) plt.show() for node in I.nodes(): if (I.degree(node) > 1): I.node[node]['size'] = I.degree(node) * 10 else: I.node[node]['size'] = 5 plt.clf() nx.draw_networkx_nodes( I, nx.get_node_attributes(I, 'pos'), node_size=[v for v in nx.get_node_attributes(I, 'size').values()]) nx.draw_networkx_edges(I, nx.get_node_attributes(I, 'pos'), width=0.2, alpha=0.5) plt.show() for node in I.nodes(): if (I.node[node]['name'] == 'Fiumicino'): I.node[node]['color'] = 'blue' elif (I.node[node]['name'] == 'Malpensa'): I.node[node]['color'] = 'green' else: I.node[node]['color'] = 'red' plt.clf() nx.draw_networkx_nodes( I, nx.get_node_attributes(I, 'pos'), node_size=[v for v in nx.get_node_attributes(I, 'size').values()], node_color=[v for v in nx.get_node_attributes(I, 'color').values()]) nx.draw_networkx_edges(I, nx.get_node_attributes(I, 'pos'), width=0.2, alpha=0.5) plt.show(block=True)
def edge_connectivity(G, s=None, t=None): r"""Returns the edge connectivity of the graph or digraph G. The edge connectivity is equal to the minimum number of edges that must be removed to disconnect G or render it trivial. If source and target nodes are provided, this function returns the local edge connectivity: the minimum number of edges that must be removed to break all paths from source to target in G. This is a flow based implementation. The algorithm is based in solving a number of max-flow problems (ie local st-edge connectivity, see local_edge_connectivity) to determine the capacity of the minimum cut on an auxiliary directed network that corresponds to the minimum edge cut of G. It handles both directed and undirected graphs. Parameters ---------- G : NetworkX graph Undirected or directed graph s : node Source node. Optional (default=None) t : node Target node. Optional (default=None) Returns ------- K : integer Edge connectivity for G, or local edge connectivity if source and target were provided Examples -------- >>> # Platonic icosahedral graph is 5-edge-connected >>> G = nx.icosahedral_graph() >>> nx.edge_connectivity(G) 5 Notes ----- This is a flow based implementation of global edge connectivity. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_ ) and computing local max flow (see local_edge_connectivity) between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_ . For directed graphs, the algorithm does n calls to the max flow function. This is an implementation of algorithm 8 in [1]_ . We use the Ford and Fulkerson algorithm to compute max flow (see ford_fulkerson). See also -------- local_node_connectivity node_connectivity local_edge_connectivity max_flow ford_fulkerson References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ # Local edge connectivity if s is not None and t is not None: if s not in G: raise nx.NetworkXError("node %s not in graph" % s) if t not in G: raise nx.NetworkXError("node %s not in graph" % t) return local_edge_connectivity(G, s, t) # Global edge connectivity if G.is_directed(): # Algorithm 8 in [1] if not nx.is_weakly_connected(G): return 0 # initial value for lambda is min degree (\delta(G)) L = min(G.degree().values()) # reuse auxiliary digraph H = _aux_digraph_edge_connectivity(G) nodes = G.nodes() n = len(nodes) for i in range(n): try: L = min(L, local_edge_connectivity(G, nodes[i], nodes[i + 1], aux_digraph=H)) except IndexError: # last node! L = min(L, local_edge_connectivity(G, nodes[i], nodes[0], aux_digraph=H)) return L else: # undirected # Algorithm 6 in [1] if not nx.is_connected(G): return 0 # initial value for lambda is min degree (\delta(G)) L = min(G.degree().values()) # reuse auxiliary digraph H = _aux_digraph_edge_connectivity(G) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating sets will always be of one node # thus we return min degree return L for w in D: L = min(L, local_edge_connectivity(G, v, w, aux_digraph=H)) return L
network_file, 'r' ) #note: with nx.Graph (undirected), there are 2951 edges, with nx.DiGraph (directed), there are 3272 edges M = nx.DiGraph() next(edges_file) #ignore the first line for e in edges_file: interaction = e.split() assert len(interaction) >= 2 source, target = str(interaction[0]), str(interaction[1]) M.add_edge(source, target) two_way_edges = 0 for n in M.nodes(): for targeted_by_n in M[n].keys(): if n in M[targeted_by_n].keys(): two_way_edges += 1 print(M.number_of_nodes(), " nodes, ", M.number_of_edges(), " edges, ", len(nx.dominating_set(M)), " dominating set, ", two_way_edges / 2, " bi-directional edges") #print (list(M.degree().values())) linewidths = 0 #node border nodelist = M.nodes() node_size = [M.degree(a_node) for a_node in nodelist] node_color = node_size style = 'dotted' width = 0.1 vmin = 30 #min(list(M.degree().values())) vmax = 800 #max(list(M.degree().values())) with_labels = False cmap = plt.get_cmap('jet') print("draw()..")
def minimum_edge_cut(G, s=None, t=None): r"""Returns a set of edges of minimum cardinality that disconnects G. If source and target nodes are provided, this function returns the set of edges of minimum cardinality that, if removed, would break all paths among source and target in G. If not, it returns a set of edges of minimum cardinality that disconnects G. Parameters ---------- G : NetworkX graph s : node Source node. Optional (default=None) t : node Target node. Optional (default=None) Returns ------- cutset : set Set of edges that, if removed, would disconnect G. If source and target nodes are provided, the set contians the edges that if removed, would destroy all paths between source and target. Examples -------- >>> # Platonic icosahedral graph has edge connectivity 5 >>> G = nx.icosahedral_graph() >>> len(nx.minimum_edge_cut(G)) 5 >>> # this is the minimum over any pair of nodes >>> from itertools import combinations >>> for u,v in combinations(G, 2): ... assert(len(nx.minimum_edge_cut(G,u,v)) == 5) ... Notes ----- This is a flow based implementation of minimum edge cut. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_) and computing the maximum flow between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_. For directed graphs, the algorithm does n calls to the max flow function. This is an implementation of algorithm 8 in [1]_. We use the Ford and Fulkerson algorithm to compute max flow (see ford_fulkerson). See also -------- node_connectivity edge_connectivity minimum_node_cut max_flow ford_fulkerson References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ # reuse auxiliary digraph H = _aux_digraph_edge_connectivity(G) # Local minimum edge cut if s and t are not None if s is not None and t is not None: if s not in G: raise nx.NetworkXError('node %s not in graph' % s) if t not in G: raise nx.NetworkXError('node %s not in graph' % t) return minimum_st_edge_cut(H, s, t) # Global minimum edge cut # Analog to the algoritm for global edge connectivity if G.is_directed(): # Based on algorithm 8 in [1] if not nx.is_weakly_connected(G): raise nx.NetworkXError('Input graph is not connected') # Initial cutset is all edges of a node with minimum degree deg = G.degree() min_deg = min(deg.values()) node = next(n for n,d in deg.items() if d==min_deg) min_cut = G.edges(node) nodes = G.nodes() n = len(nodes) for i in range(n): try: this_cut = minimum_st_edge_cut(H, nodes[i], nodes[i+1]) if len(this_cut) <= len(min_cut): min_cut = this_cut except IndexError: # Last node! this_cut = minimum_st_edge_cut(H, nodes[i], nodes[0]) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut else: # undirected # Based on algorithm 6 in [1] if not nx.is_connected(G): raise nx.NetworkXError('Input graph is not connected') # Initial cutset is all edges of a node with minimum degree deg = G.degree() min_deg = min(deg.values()) node = next(n for n,d in deg.items() if d==min_deg) min_cut = G.edges(node) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating set will always be of one node # thus we return min_cut, which now contains the edges of a node # with minimum degree return min_cut for w in D: this_cut = minimum_st_edge_cut(H, v, w) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut
def test_raise_dominating_set(): G = nx.path_graph(4) D = nx.dominating_set(G, start_with=10)
def findDominatingSet(self, graph): print "Algorithm: NetworkX" dominating_set = nx.dominating_set(graph); dominating_set = list(dominating_set) return dominating_set;
import networkx as nx import matplotlib.pyplot as plt G = nx.gnm_random_graph(15, 22, seed=12345) fig, ax = plt.subplots() pos = nx.circular_layout(G) nx.draw(G, pos=pos, ax=ax, with_labels=True) ax.set_title("Network with minimum spanning tree overlaid") min_span_tree = nx.minimum_spanning_tree(G) print(list(min_span_tree.edges)) # [(0, 13), (0, 7), (0, 5), (1, 13), (1, 11), # (2, 5), (2, 9), (2, 8), (2, 3), (2, 12), # (3, 4), (4, 6), (5, 14), (8, 10)] nx.draw_networkx_edges(min_span_tree, pos=pos, ax=ax, width=1.5, edge_color="r") dominating_set = nx.dominating_set(G) print("Dominating set", dominating_set) # Dominating set {0, 1, 2, 4, 10, 14} plt.show()
def edge_connectivity(G, s=None, t=None): r"""Returns the edge connectivity of the graph or digraph G. The edge connectivity is equal to the minimum number of edges that must be removed to disconnect G or render it trivial. If source and target nodes are provided, this function returns the local edge connectivity: the minimum number of edges that must be removed to break all paths from source to target in G. This is a flow based implementation. The algorithm is based in solving a number of max-flow problems (ie local st-edge connectivity, see local_edge_connectivity) to determine the capacity of the minimum cut on an auxiliary directed network that corresponds to the minimum edge cut of G. It handles both directed and undirected graphs. Parameters ---------- G : NetworkX graph Undirected or directed graph s : node Source node. Optional (default=None) t : node Target node. Optional (default=None) Returns ------- K : integer Edge connectivity for G, or local edge connectivity if source and target were provided Examples -------- >>> # Platonic icosahedral graph is 5-edge-connected >>> G = nx.icosahedral_graph() >>> nx.edge_connectivity(G) 5 Notes ----- This is a flow based implementation of global edge connectivity. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_ ) and computing local max flow (see local_edge_connectivity) between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_ . For directed graphs, the algorithm does n calls to the max flow function. This is an implementation of algorithm 8 in [1]_ . We use the Ford and Fulkerson algorithm to compute max flow (see ford_fulkerson). See also -------- local_node_connectivity node_connectivity local_edge_connectivity max_flow ford_fulkerson References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ # Local edge connectivity if s is not None and t is not None: if s not in G: raise nx.NetworkXError('node %s not in graph' % s) if t not in G: raise nx.NetworkXError('node %s not in graph' % t) return local_edge_connectivity(G, s, t) # Global edge connectivity if G.is_directed(): # Algorithm 8 in [1] if not nx.is_weakly_connected(G): return 0 # initial value for lambda is min degree (\delta(G)) L = min(G.degree().values()) # reuse auxiliary digraph H = _aux_digraph_edge_connectivity(G) nodes = G.nodes() n = len(nodes) for i in range(n): try: L = min( L, local_edge_connectivity(G, nodes[i], nodes[i + 1], aux_digraph=H)) except IndexError: # last node! L = min( L, local_edge_connectivity(G, nodes[i], nodes[0], aux_digraph=H)) return L else: # undirected # Algorithm 6 in [1] if not nx.is_connected(G): return 0 # initial value for lambda is min degree (\delta(G)) L = min(G.degree().values()) # reuse auxiliary digraph H = _aux_digraph_edge_connectivity(G) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating sets will always be of one node # thus we return min degree return L for w in D: L = min(L, local_edge_connectivity(G, v, w, aux_digraph=H)) return L
def print(graph, precision): return Utils.print_set(nx.dominating_set(graph), precision)
def test_dominating_set_error(): G = nx.path_graph(4) D = nx.dominating_set(G, start_with=10)
def test_dominating_set(): G = nx.gnp_random_graph(100, 0.1) D = nx.dominating_set(G) assert_true(nx.is_dominating_set(G, D)) D = nx.dominating_set(G, start_with=0) assert_true(nx.is_dominating_set(G, D))
def edge_connectivity(G, s=None, t=None, flow_func=None): r"""Returns the edge connectivity of the graph or digraph G. The edge connectivity is equal to the minimum number of edges that must be removed to disconnect G or render it trivial. If source and target nodes are provided, this function returns the local edge connectivity: the minimum number of edges that must be removed to break all paths from source to target in G. Parameters ---------- G : NetworkX graph Undirected or directed graph s : node Source node. Optional. Default value: None. t : node Target node. Optional. Default value: None. flow_func : function A function for computing the maximum flow among a pair of nodes. The function has to accept at least three parameters: a Digraph, a source node, and a target node. And return a residual network that follows NetworkX conventions (see :meth:`maximum_flow` for details). If flow_func is None, the default maximum flow function (:meth:`edmonds_karp`) is used. See below for details. The choice of the default function may change from version to version and should not be relied on. Default value: None. Returns ------- K : integer Edge connectivity for G, or local edge connectivity if source and target were provided Examples -------- >>> # Platonic icosahedral graph is 5-edge-connected >>> G = nx.icosahedral_graph() >>> nx.edge_connectivity(G) 5 You can use alternative flow algorithms for the underlying maximum flow computation. In dense networks the algorithm :meth:`shortest_augmenting_path` will usually perform better than the default :meth:`edmonds_karp`, which is faster for sparse networks with highly skewed degree distributions. Alternative flow functions have to be explicitly imported from the flow package. >>> from networkx.algorithms.flow import shortest_augmenting_path >>> nx.edge_connectivity(G, flow_func=shortest_augmenting_path) 5 If you specify a pair of nodes (source and target) as parameters, this function returns the value of local edge connectivity. >>> nx.edge_connectivity(G, 3, 7) 5 If you need to perform several local computations among different pairs of nodes on the same graph, it is recommended that you reuse the data structures used in the maximum flow computations. See :meth:`local_edge_connectivity` for details. Notes ----- This is a flow based implementation of global edge connectivity. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_ ) and computing local maximum flow (see :meth:`local_edge_connectivity`) between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_ . For directed graphs, the algorithm does n calls to the maximum flow function. This is an implementation of algorithm 8 in [1]_ . See also -------- :meth:`local_edge_connectivity` :meth:`local_node_connectivity` :meth:`node_connectivity` :meth:`maximum_flow` :meth:`edmonds_karp` :meth:`preflow_push` :meth:`shortest_augmenting_path` References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ if (s is not None and t is None) or (s is None and t is not None): raise nx.NetworkXError('Both source and target must be specified.') # Local edge connectivity if s is not None and t is not None: if s not in G: raise nx.NetworkXError('node %s not in graph' % s) if t not in G: raise nx.NetworkXError('node %s not in graph' % t) return local_edge_connectivity(G, s, t, flow_func=flow_func) # Global edge connectivity # reuse auxiliary digraph and residual network H = build_auxiliary_edge_connectivity(G) R = build_residual_network(H, 'capacity') kwargs = dict(flow_func=flow_func, auxiliary=H, residual=R) if G.is_directed(): # Algorithm 8 in [1] if not nx.is_weakly_connected(G): return 0 # initial value for \lambda is minimum degree L = min(G.degree().values()) nodes = G.nodes() n = len(nodes) for i in range(n): kwargs['cutoff'] = L try: L = min(L, local_edge_connectivity(G, nodes[i], nodes[i+1], **kwargs)) except IndexError: # last node! L = min(L, local_edge_connectivity(G, nodes[i], nodes[0], **kwargs)) return L else: # undirected # Algorithm 6 in [1] if not nx.is_connected(G): return 0 # initial value for \lambda is minimum degree L = min(G.degree().values()) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating sets will always be of one node # thus we return min degree return L for w in D: kwargs['cutoff'] = L L = min(L, local_edge_connectivity(G, v, w, **kwargs)) return L
def test_raise_dominating_set(): with pytest.raises(nx.NetworkXError): G = nx.path_graph(4) D = nx.dominating_set(G, start_with=10)
def test_dominating_set(): G = nx.gnp_random_graph(100, 0.1) D = nx.dominating_set(G) assert nx.is_dominating_set(G, D) D = nx.dominating_set(G, start_with=0) assert nx.is_dominating_set(G, D)
def test_dominating_set(): for i in range(5): G = nx.gnp_random_graph(100, 0.1) D = nx.dominating_set(G) assert_true(is_dominating_set(G, D))
def minimum_edge_cut(G, s=None, t=None, flow_func=None): r"""Returns a set of edges of minimum cardinality that disconnects G. If source and target nodes are provided, this function returns the set of edges of minimum cardinality that, if removed, would break all paths among source and target in G. If not, it returns a set of edges of minimum cardinality that disconnects G. Parameters ---------- G : NetworkX graph s : node Source node. Optional. Default value: None. t : node Target node. Optional. Default value: None. flow_func : function A function for computing the maximum flow among a pair of nodes. The function has to accept at least three parameters: a Digraph, a source node, and a target node. And return a residual network that follows NetworkX conventions (see :meth:`maximum_flow` for details). If flow_func is None, the default maximum flow function (:meth:`edmonds_karp`) is used. See below for details. The choice of the default function may change from version to version and should not be relied on. Default value: None. Returns ------- cutset : set Set of edges that, if removed, would disconnect G. If source and target nodes are provided, the set contians the edges that if removed, would destroy all paths between source and target. Examples -------- >>> # Platonic icosahedral graph has edge connectivity 5 >>> G = nx.icosahedral_graph() >>> len(nx.minimum_edge_cut(G)) 5 You can use alternative flow algorithms for the underlying maximum flow computation. In dense networks the algorithm :meth:`shortest_augmenting_path` will usually perform better than the default :meth:`edmonds_karp`, which is faster for sparse networks with highly skewed degree distributions. Alternative flow functions have to be explicitly imported from the flow package. >>> from networkx.algorithms.flow import shortest_augmenting_path >>> len(nx.minimum_edge_cut(G, flow_func=shortest_augmenting_path)) 5 If you specify a pair of nodes (source and target) as parameters, this function returns the value of local edge connectivity. >>> nx.edge_connectivity(G, 3, 7) 5 If you need to perform several local computations among different pairs of nodes on the same graph, it is recommended that you reuse the data structures used in the maximum flow computations. See :meth:`local_edge_connectivity` for details. Notes ----- This is a flow based implementation of minimum edge cut. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_) and computing the maximum flow between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_. For directed graphs, the algorithm does n calls to the max flow function. The function raises an error if the directed graph is not weakly connected and returns an empty set if it is weakly connected. It is an implementation of algorithm 8 in [1]_. See also -------- :meth:`minimum_st_edge_cut` :meth:`minimum_node_cut` :meth:`stoer_wagner` :meth:`node_connectivity` :meth:`edge_connectivity` :meth:`maximum_flow` :meth:`edmonds_karp` :meth:`preflow_push` :meth:`shortest_augmenting_path` References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ if (s is not None and t is None) or (s is None and t is not None): raise nx.NetworkXError("Both source and target must be specified.") # reuse auxiliary digraph and residual network H = build_auxiliary_edge_connectivity(G) R = build_residual_network(H, "capacity") kwargs = dict(flow_func=flow_func, residual=R, auxiliary=H) # Local minimum edge cut if s and t are not None if s is not None and t is not None: if s not in G: raise nx.NetworkXError("node %s not in graph" % s) if t not in G: raise nx.NetworkXError("node %s not in graph" % t) return minimum_st_edge_cut(H, s, t, **kwargs) # Global minimum edge cut # Analog to the algoritm for global edge connectivity if G.is_directed(): # Based on algorithm 8 in [1] if not nx.is_weakly_connected(G): raise nx.NetworkXError("Input graph is not connected") # Initial cutset is all edges of a node with minimum degree node = min(G, key=G.degree) min_cut = set(G.edges(node)) nodes = list(G) n = len(nodes) for i in range(n): try: this_cut = minimum_st_edge_cut(H, nodes[i], nodes[i + 1], **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut except IndexError: # Last node! this_cut = minimum_st_edge_cut(H, nodes[i], nodes[0], **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut else: # undirected # Based on algorithm 6 in [1] if not nx.is_connected(G): raise nx.NetworkXError("Input graph is not connected") # Initial cutset is all edges of a node with minimum degree node = min(G, key=G.degree) min_cut = set(G.edges(node)) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating set will always be of one node # thus we return min_cut, which now contains the edges of a node # with minimum degree return min_cut for w in D: this_cut = minimum_st_edge_cut(H, v, w, **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut
for i in range(10000): sample = np.random.normal(12, 2) if sample < 0: sample = 2 elif sample > 45: sample = 42 idx = np.random.permutation(len(e))[:int(sample)] #print(idx) edg = e[idx] G = nx.empty_graph(10) G.add_edges_from(edg) mat = np.zeros((10, 10), dtype=int) for i in edg: mat[tuple(i)] = True mat[tuple(i[::-1])] = True X.append(mat.reshape(1, -1)[0]) label = len(nx.dominating_set(G)) y.append(int(label)) count += label print(i, label) y = np.asarray(y) X = np.asarray(X) import pickle pickle_out = open('domination.pickle', 'wb') pickle.dump((X, y), pickle_out) pickle_out.close() pickle_in = open('domination.pickle', 'rb') X, y = pickle.load(pickle_in) print(type(X), type(X[0][0])) print("X shape", len(X), X[0].shape) print("y shape", len(y))
print "Edges of G" print G.edges() # G = nx.petersen_graph() conn = 1 while conn < 3: G = nx.gnm_random_graph(10, 20) conn = nx.node_connectivity(G) print "Nodes of G " print G.nodes() print "Edges of G" print G.edges() print "Connectivity of G is %d" % (nx.node_connectivity(G)) D = nx.dominating_set(G) print "Dominators" print D nx.draw_circular(G) plt.show() nx.draw(G) plt.show()
def findDominatingSet(self, graph): dominatingSet = nx.dominating_set(graph); print "GA" return dominatingSet;
def test_dominating_set(): for i in range(5): G = nx.gnp_random_graph(100,0.1) D = nx.dominating_set(G) assert_true(is_dominating_set(G,D))
def minimum_edge_cut(G, s=None, t=None, flow_func=None): r"""Returns a set of edges of minimum cardinality that disconnects G. If source and target nodes are provided, this function returns the set of edges of minimum cardinality that, if removed, would break all paths among source and target in G. If not, it returns a set of edges of minimum cardinality that disconnects G. Parameters ---------- G : NetworkX graph s : node Source node. Optional. Default value: None. t : node Target node. Optional. Default value: None. flow_func : function A function for computing the maximum flow among a pair of nodes. The function has to accept at least three parameters: a Digraph, a source node, and a target node. And return a residual network that follows NetworkX conventions (see :meth:`maximum_flow` for details). If flow_func is None, the default maximum flow function (:meth:`edmonds_karp`) is used. See below for details. The choice of the default function may change from version to version and should not be relied on. Default value: None. Returns ------- cutset : set Set of edges that, if removed, would disconnect G. If source and target nodes are provided, the set contains the edges that if removed, would destroy all paths between source and target. Examples -------- >>> # Platonic icosahedral graph has edge connectivity 5 >>> G = nx.icosahedral_graph() >>> len(nx.minimum_edge_cut(G)) 5 You can use alternative flow algorithms for the underlying maximum flow computation. In dense networks the algorithm :meth:`shortest_augmenting_path` will usually perform better than the default :meth:`edmonds_karp`, which is faster for sparse networks with highly skewed degree distributions. Alternative flow functions have to be explicitly imported from the flow package. >>> from networkx.algorithms.flow import shortest_augmenting_path >>> len(nx.minimum_edge_cut(G, flow_func=shortest_augmenting_path)) 5 If you specify a pair of nodes (source and target) as parameters, this function returns the value of local edge connectivity. >>> nx.edge_connectivity(G, 3, 7) 5 If you need to perform several local computations among different pairs of nodes on the same graph, it is recommended that you reuse the data structures used in the maximum flow computations. See :meth:`local_edge_connectivity` for details. Notes ----- This is a flow based implementation of minimum edge cut. For undirected graphs the algorithm works by finding a 'small' dominating set of nodes of G (see algorithm 7 in [1]_) and computing the maximum flow between an arbitrary node in the dominating set and the rest of nodes in it. This is an implementation of algorithm 6 in [1]_. For directed graphs, the algorithm does n calls to the max flow function. The function raises an error if the directed graph is not weakly connected and returns an empty set if it is weakly connected. It is an implementation of algorithm 8 in [1]_. See also -------- :meth:`minimum_st_edge_cut` :meth:`minimum_node_cut` :meth:`stoer_wagner` :meth:`node_connectivity` :meth:`edge_connectivity` :meth:`maximum_flow` :meth:`edmonds_karp` :meth:`preflow_push` :meth:`shortest_augmenting_path` References ---------- .. [1] Abdol-Hossein Esfahanian. Connectivity Algorithms. http://www.cse.msu.edu/~cse835/Papers/Graph_connectivity_revised.pdf """ if (s is not None and t is None) or (s is None and t is not None): raise nx.NetworkXError('Both source and target must be specified.') # reuse auxiliary digraph and residual network H = build_auxiliary_edge_connectivity(G) R = build_residual_network(H, 'capacity') kwargs = dict(flow_func=flow_func, residual=R, auxiliary=H) # Local minimum edge cut if s and t are not None if s is not None and t is not None: if s not in G: raise nx.NetworkXError('node %s not in graph' % s) if t not in G: raise nx.NetworkXError('node %s not in graph' % t) return minimum_st_edge_cut(H, s, t, **kwargs) # Global minimum edge cut # Analog to the algorithm for global edge connectivity if G.is_directed(): # Based on algorithm 8 in [1] if not nx.is_weakly_connected(G): raise nx.NetworkXError('Input graph is not connected') # Initial cutset is all edges of a node with minimum degree node = min(G, key=G.degree) min_cut = set(G.edges(node)) nodes = list(G) n = len(nodes) for i in range(n): try: this_cut = minimum_st_edge_cut(H, nodes[i], nodes[i + 1], **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut except IndexError: # Last node! this_cut = minimum_st_edge_cut(H, nodes[i], nodes[0], **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut else: # undirected # Based on algorithm 6 in [1] if not nx.is_connected(G): raise nx.NetworkXError('Input graph is not connected') # Initial cutset is all edges of a node with minimum degree node = min(G, key=G.degree) min_cut = set(G.edges(node)) # A dominating set is \lambda-covering # We need a dominating set with at least two nodes for node in G: D = nx.dominating_set(G, start_with=node) v = D.pop() if D: break else: # in complete graphs the dominating set will always be of one node # thus we return min_cut, which now contains the edges of a node # with minimum degree return min_cut for w in D: this_cut = minimum_st_edge_cut(H, v, w, **kwargs) if len(this_cut) <= len(min_cut): min_cut = this_cut return min_cut
def dominating_set_partition(graph, nodes): prime_nodes = nx.dominating_set(graph) return ''