def find_feasible_two_edge_path(graph: nx.Graph, matching: Dict[Any, Any]) -> Optional[Tuple[Any, Any, Any]]: # This path has the form top1 -> bottom -> top2 or bottom1 -> top -> bottom2 # first: must be in the left part of the graph and in matching # second: must be in the right part of the graph and in matching # third: is also in the left part of the graph and but must not be in matching for top, bottom in matching.items(): if top in top_nodes(graph) and bottom in bottom_nodes(graph): for new_bottom in graph.neighbors(top): if new_bottom not in matching.values(): return (bottom, top, new_bottom) for new_top in graph.neighbors(bottom): if new_top not in matching: return (top, bottom, new_top) return None
def sorensen_index(G: nx.Graph, i, j): i_neighbourhood = set(G.neighbors(i)) j_neighbourhood = set(G.neighbors(j)) degreeSum = G.degree(i) + G.degree(j) if degreeSum == 0: return 0 return len(i_neighbourhood.intersection(j_neighbourhood)) / degreeSum
def _compute_ricci_curvature(G: nx.Graph, weight="weight", **kwargs): """ Compute Ricci curvature of edges and nodes. The node Ricci curvature is defined as the average of node's adjacency edges. :param G: A NetworkX graph. :param weight: The edge weight used to compute Ricci curvature. Default: "weight". :return G: A networkx graph with "ricciCurvature" on nodes and edges. """ if not nx.get_edge_attributes(G, weight): print('Edge weight not detected in graph, use "weight" as default edge weight.') for (v1, v2) in G.edges(): G[v1][v2][weight] = 1.0 # compute Ricci curvature for all edges edge_ricci = _compute_ricci_curvature_edges(G, weight=weight, **kwargs) # Assign edge Ricci curvature from result to graph G nx.set_edge_attributes(G, edge_ricci, "ricciCurvature") # Compute node Ricci curvature for n in G.nodes(): rc_sum = 0 # sum of the neighbor Ricci curvature if G.degree(n) != 0: for nbr in G.neighbors(n): if 'ricciCurvature' in G[n][nbr]: rc_sum += G[n][nbr]['ricciCurvature'] # Assign the node Ricci curvature to be the average of node's adjacency edges G.nodes[n]['ricciCurvature'] = rc_sum / G.degree(n) logger.debug("node %s, Ricci Curvature = %f" % (n, G.nodes[n]['ricciCurvature'])) return G
def bfs(G: nx.Graph, destination: str, start: str = "SportsComplex") -> (List[str], Set[str]): """ Searches for a path from *destination* from *start* in the graph *G*. A path is a list of nodes from start you need to pass to reach destination. Returns the path and a set of nodes visited during the search """ if start == destination: return [] frontier = deque([start]) explored = set() solution = [] visited = set() while True: if not frontier: return [] node = frontier.popleft() explored.add(node) solution.append(node) for adj in G.neighbors(node): visited.add(adj) if adj not in explored and adj not in frontier: if adj == destination: return solution, visited frontier.appendleft(adj)
def HEM(graph: nx.Graph): nodes = graph.nodes() rnd.shuffle(nodes) matched = dict([(n, 'unmatched') for n in nodes]) max_matching = list() for node in nodes: if (matched[node] == 'matched'): continue adj_nodes = graph.neighbors(node) rnd.shuffle(adj_nodes) max_adj_node = None max_weight = 0 for adj_node in adj_nodes: if (matched[adj_node] == 'matched'): continue adj_edge_weight = graph[node][adj_node]['weight'] if (adj_edge_weight > max_weight): max_adj_node = adj_node max_weight = adj_edge_weight if (max_adj_node != None): max_matching.append((node, max_adj_node)) matched[node] = 'matched' matched[max_adj_node] = 'matched' return max_matching
def a_star(graph: nx.Graph, start, goal, heuristic): """A* :param graph: :param start: :param goal: :param heuristic: :return: """ frontier = PriorityQue() visited = dict() frontier.push(0, 0, start) while len(frontier): _, sofar, current = frontier.pop() ns = [*graph.neighbors(current)] to_goals = heuristic(ns, [goal]) for ind, n in enumerate(ns): if n in visited: continue edge_len = graph.edges[current, n].get('weight', 1) to_goal = to_goals[ind] visited[n] = current, edge_len if goal == n: return backtrack(visited, start, goal) frontier.push(sofar + edge_len + to_goal, sofar + edge_len, n) return None, None
def heuristic_search(graph: nx.Graph, start, goal, heuristic): """Heuristic Search :param graph: :param start: :param goal: :param heuristic: :return: """ frontier = PriorityQue() visited = dict() frontier.push(0, start) while len(frontier): _, current = frontier.pop() ns = [*graph.neighbors(current)] to_goals = heuristic(ns, [goal]) for ind, n in enumerate(ns): if n in visited: continue # only used to compute path length edge_len = graph.edges[current, n].get('weight', 1) to_goal = to_goals[ind] visited[n] = current, edge_len if goal == n: return backtrack(visited, start, goal) frontier.push(to_goal, n) return None, None
def planar_independent_set( graph: Graph, black_list: List = list(), degree_lim=INDEPENDENT_SET_LEMMA_DEGREE) -> Set[Point]: """ Assuming the graph is planar, then computes an independent set of size at least n/18 in which every node has degree at most 8. O(n) time. (Note: assume the graph is planar because it is computationally expensive to check) :param graph: networkx Graph (assumed planar) :param black_list: list of nodes that should not be in the independent set :param degree_lim: nodes in independent set have degree at most this :return: set of graph nodes """ unmarked_nodes = { node for node in graph.nodes_iter() if graph.degree(node) <= degree_lim and node not in black_list } independent_set = set() while len(unmarked_nodes) > 0: node = unmarked_nodes.pop() independent_set.add(node) unmarked_nodes -= set(graph.neighbors(node)) return independent_set
def c_0(clique: list, graph: nx.Graph): """Generates the set :math:`C_0` of nodes that are connected to all nodes in the input clique subgraph. The set :math:`C_0` is defined in :cite:`pullan2006phased` and is used to determine nodes that can be added to the current clique to grow it into a larger one. **Example usage:** >>> graph = nx.complete_graph(10) >>> clique = [0, 1, 2, 3, 4] >>> c_0(clique, graph) [5, 6, 7, 8, 9] Args: clique (list[int]): a subgraph specified by a list of nodes; the subgraph must be a clique graph (nx.Graph): the input graph Returns: list[int]: a list containing the :math:`C_0` nodes for the clique """ if not is_clique(graph.subgraph(clique)): raise ValueError("Input subgraph is not a clique") clique = set(clique) c_0_nodes = [] non_clique_nodes = set(graph.nodes) - clique for i in non_clique_nodes: if clique.issubset(graph.neighbors(i)): c_0_nodes.append(i) return c_0_nodes
def dynamic_infected_neighbours(network: nx.Graph, **kwargs): """ Counts infected neighbours for all nodes Args: network: networkx Graph **kwargs: See below Keyword Args: state (dict): Required if `network` doesn't have 'state' for each node. See: 'graphflow.analysis.metrics' Returns: dict: dictionary keyed by nodes id into dict of neighbours counts with given status (S,I,R) See Also: 'graphflow.analysis.metrics' """ status = nx.get_node_attributes(network, 'status') infected = {} for node in network.nodes(): infected[node] = 0 neighbours = network.neighbors(node) # id's for nb in neighbours: if status[nb] == 'I': infected[node] += 1 return infected
def action_blocking(g: nx.Graph, player): free_nodes = g.graph['free'] free_nodes_set = set(free_nodes) opponent = 3 - player opponent_nodes = g.graph[str(opponent)] if not opponent_nodes: return action_weight(g) opponent_neighbors = set() for node in opponent_nodes: opponent_neighbors |= set(g.neighbors(node)) free_opponent_neighbors = free_nodes_set.intersection(opponent_neighbors) free_opponent_neighbors = list(free_opponent_neighbors) if not free_opponent_neighbors: return action_weight(g) max_node = -1 max_value = -1 for node in free_opponent_neighbors: weight_free = 0 for edge in g.edges(node, data=True): if edge[1] in free_nodes_set: weight_free += edge[2]['w'] if weight_free > max_value: max_value = weight_free max_node = node return max_node
def get_rings (start_node: int, graph: nx.Graph, neigh_size) -> List[List[int]]: ''' Performs BFS from the start node and returns a list of lists containing nodes degrees, sorted by distance from the start node. ''' q = collections.deque() q.appendleft((start_node, 0)) visited = [False for i in range(graph.number_of_nodes())] visited[start_node] = True rings = [] while len(q) > 0: (curr, dist) = q.pop() if dist>neigh_size: return rings if len(rings) <= dist: rings.append([]) rings[dist].append(graph.degree(curr)) for neigh in graph.neighbors(curr): if not visited[neigh]: visited[neigh] = True q.appendleft((neigh, dist+1)) return rings
def _get_neighbor_labels(self, X: nx.Graph): neighbor_indices = [[n_v for n_v in X.neighbors(v)] for v in list(X.nodes)] neighbor_labels = [] for n_indices in neighbor_indices: neighbor_labels.append( sorted([X.nodes[v]['label'] for v in n_indices])) return neighbor_labels
def s(gm: Graph, gt: Graph, x: Example) -> float: """ Return the similarity of model and cluster graphs in the neighborhood of an example Parameters: ------- gm: the graph produced by a base model from a training set gt: the graph produced by clustering on the testing set x: the example central to the neighborhoods being compared Returns: ------- a real valued 0 <= s <= 1 denoting the ratio of common neighbors of x between gm and gt """ gm_neighbors = set(gm.neighbors(x)) gt_neighbors = set(gt.neighbors(x)) intersect = len(gm_neighbors & gt_neighbors) union = len(gm_neighbors | gt_neighbors) return intersect / union if union > 0 else 0
def generate_graph(self): graph = Graph() # populate cities: g = self.iter_all_strings() for _ in range(self.node_count): self.cities.append(next(g)) # to make a connected graph, all nodes should be connected. connected = self.cities[:1] not_connected = self.cities[1:] for city in not_connected: connected_with = self.random.choice(connected) graph.add_edge(connected_with, city) # if the number of neighbors (edges) for connecting city is over max_path, remove it from connected, # so it doesn't overflow no more. if len(list(graph.neighbors(connected_with))) == self.max_paths: connected.remove(connected_with) connected.append(city) for city in connected: neighbors = list(graph.neighbors(city)) edge_count = self.random.randint(self.min_paths - len(neighbors), self.max_paths - len(neighbors)) if edge_count < 1: continue connectable = [ c for c in connected if c not in neighbors and c != city ] if not connectable: continue for _ in range(edge_count): if not connectable: break connected_with = self.random.choice(connectable) if len(list( graph.neighbors(connected_with))) >= self.max_paths: connectable.remove(connected_with) continue graph.add_edge(city, connected_with) # same applies, so when we reach max path, remove it from the connectable pool connectable.remove(connected_with) gc.collect() return graph
def get_neighbour_edge_of_edge_community(G: nx.Graph, edge_community: Set): result = set() community_nodes = get_node_from_edge_community(edge_community) for node in community_nodes: for neighbour in G.neighbors(node): if neighbour not in community_nodes: result.add((node, neighbour) if node < neighbour else (neighbour, node)) return result
def polygon_skeleton(polygon, density=10): """ Given a buffer polygon, return a skeleton graph. """ skeleton = Graph() points = [] for ring in polygon_rings(polygon): points.extend(densify_line(list(ring.coords), density)) if len(points) <= 4: # don't bother with this one return skeleton print >> stderr, ' ', len(points), 'perimeter points', rbox = '\n'.join( ['2', str(len(points))] + ['%.2f %.2f' % (x, y) for (x, y) in points] + [''] ) qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE) output, error = qvoronoi.communicate(rbox) voronoi_lines = output.splitlines() if qvoronoi.returncode: raise _QHullFailure('Failed with code %s' % qvoronoi.returncode) vert_count, poly_count = map(int, voronoi_lines[1].split()[:2]) for (index, line) in enumerate(voronoi_lines[2:2+vert_count]): point = Point(*map(float, line.split()[:2])) if point.within(polygon): skeleton.add_node(index, dict(point=point)) for line in voronoi_lines[2+vert_count:2+vert_count+poly_count]: indexes = map(int, line.split()[1:]) for (v, w) in zip(indexes, indexes[1:] + indexes[:1]): if v not in skeleton.node or w not in skeleton.node: continue v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point'] line = LineString([(v1.x, v1.y), (v2.x, v2.y)]) if line.within(polygon): skeleton.add_edge(v, w, dict(line=line, length=line.length)) removing = True while removing: removing = False for index in skeleton.nodes(): if skeleton.degree(index) == 1: depth = skeleton.node[index].get('depth', 0) if depth < 20: other = skeleton.neighbors(index)[0] skeleton.node[other]['depth'] = depth + skeleton.edge[index][other]['line'].length skeleton.remove_node(index) removing = True print >> stderr, 'contain', len(skeleton.edge), 'internal edges.' return skeleton
def bfs_base_points_euclid(g: nx.Graph, min_dist: float, source: int = -1) -> np.ndarray: """ Performs a BFS on a weighted graph. Only nodes with a minimum euclidian distance get added to the result. The graph nodes must contain the attribute 'position' as a numpy array with x,y,z position. Args: g: The weighted networkx graph on which the BFS should be performed. Nodes must have a position attribute with their xyz positions as a numpy array, e.g. g.nodes[0]['position'] = np.array([1,2,3]) source: The source node from which the BFS should start. Default is -1 which stands for a random node min_dist: The minimum distance between nodes in the BFS result. Returns: np.ndarray with nodes sorted recording to the result of the filtered BFS """ if source == -1: source = np.random.randint(g.number_of_nodes()) visited = [source] chosen = [source] # add all neighbors with respective weights neighbors = g.neighbors(source) de = deque([(i, 0) for i in neighbors]) while de: curr, buddy = de.pop() if curr not in visited: visited.append(curr) # only nodes with minimum distance to other chosen nodes get added buddy_pos = g.nodes[chosen[buddy]]['position'] pos = g.nodes[curr]['position'] if np.linalg.norm(buddy_pos - pos) >= min_dist: clear = True for node in chosen: if np.linalg.norm(pos - g.nodes[node]['position']) < min_dist: clear = False break if clear: buddy = len(chosen) chosen.append(curr) # add all neighbors with their weights added to the current weight neighbors = g.neighbors(curr) de.extendleft([(i, buddy) for i in neighbors if i not in visited]) # return only chosen nodes return np.array(chosen)
def clustering_coefficients_set_intersection(graph: Graph) -> dict: coefficients = {} for v in graph.nodes: v_neighbors = set(graph.neighbors(v)) v_neighbors_len = len(v_neighbors) if v_neighbors_len > 1: n_triangles = 0 for u in v_neighbors: n_triangles += len(v_neighbors.intersection( graph.neighbors(u))) coeff = n_triangles / (v_neighbors_len * (v_neighbors_len - 1)) coefficients[v] = coeff else: coefficients[v] = 0 return coefficients
def __neighbor_nested_property(graph: nx.Graph, nested: List[str], local_prop_nested: List[List[int]], constraint_nested: List[Tuple[int, int]], self_satisfy_nested: List[bool], **kwargs) -> Tuple[List[int], int]: assert isinstance(nested, list) assert isinstance(local_prop_nested, list) assert isinstance(constraint_nested, list) assert isinstance(self_satisfy_nested, list) assert len(nested) == len(local_prop_nested) == len( constraint_nested) == len(self_satisfy_nested) # not empty if nested: fn = nested[0] local_prop = local_prop_nested[0] constraint_min, constraint_max = constraint_nested[0] self_satisfy = self_satisfy_nested[0] else: raise ValueError("Can't loop forever") if local_prop is None: local_prop = [] # calculate the other property inner_labels, _ = tagger_dispatch( fn, nested=nested[1:], local_prop_nested=local_prop_nested[1:], constraint_nested=constraint_nested[1:], self_satisfy_nested=self_satisfy_nested[1:], **kwargs)(graph) num_1s = sum(inner_labels) graph = nx.convert_node_labels_to_integers(graph, label_attribute="old-name") labels = [] for node in graph: node_satisfy = True if self_satisfy: node_satisfy = bool(inner_labels[node]) if node_satisfy and (graph.node[node]['color'] in local_prop or len(local_prop) == 0): neighbors = graph.neighbors(node) neigh_1s = sum(inner_labels[i] for i in neighbors) if constraint_max >= (num_1s - neigh_1s) >= constraint_min: labels.append(1) else: labels.append(0) else: labels.append(0) return np.array(labels).astype(int), int(any(l > 0 for l in labels))
def check_largura(G: nx.Graph): for i in fila: fila.remove(i) for j in G.neighbors(i): if j not in visitados: visitados.append(j) fila.append(j) li_comp.append(j) check_largura(G)
def local_network_neighbors(graph: nx.Graph, node) -> list: return list( filter( lambda adjacency: get_node_type(graph, adjacency[ 0]) == NodeType.COMPUTER, graph[list( filter( lambda neighbor_node: get_node_type( graph, neighbor_node) == NodeType.ROUTER, graph.neighbors(node)))[0]].items()))
def largest_first(graph: nx.Graph, m: List[int]) -> Dict[int, int]: """ Largest First colouring algorithm :param graph: graph :param m: mapping of available number of each colour :return: mapping node->colour :raises NoColoursRemainingException: when m threshold couldn't be achieved """ max_c = len(m)-1 nodes = list(graph.nodes) ct = {} cv = np.zeros(len(m)) vt = [] dt = [] for i in range(len(nodes)): vt.append(i) dt.append(len([u for u in graph.neighbors(nodes[i])])) d = dt[i] j = i while j > 0 and dt[j] < d: dt[j] = dt[j - 1] vt[j] = vt[j - 1] j -= 1 vt[j] = i dt[j] = d ct[nodes[vt[0]]] = 0 cv[0] = 1 for i in range(1, len(vt)): c = {} for u in graph.neighbors(nodes[vt[i]]): if u in ct: c[ct[u]] = True color = 0 while color in c or cv[color] >= m[color]: color += 1 if color > max_c: raise NoColoursRemainingException ct[nodes[vt[i]]] = color cv[color] += 1 return ct
def a_star(self, graph: nx.Graph, start_node, goal_node): if start_node is goal_node: self.endSearch = True self.visited.append(start_node) return queue = [start_node] cost_so_far = {start_node: 0} while len(queue) > 0 and not self.endSearch: fn = {} s = queue.pop(0) self.visited.append(s) print("Drive to", s, " Estate", end="\n") first_closed_index: int = -1 for i in graph.neighbors(s): if i in self.closed: minimum = min(self.closed.index(i), first_closed_index) first_closed_index = self.closed.index( i) if first_closed_index is -1 else minimum continue if len(list(graph.neighbors(s))) is 1: self.closed.append(s) current_weight = graph.get_edge_data(s, i).get('weight') fn[i] = float(self.heuristics.get(i)) + float( current_weight) + cost_so_far.get(s) if len(fn) < 1 and first_closed_index > -1: key = self.closed[first_closed_index] self.closed.pop(first_closed_index) current_weight = graph.get_edge_data(s, key).get('weight') fn[key] = float(self.heuristics.get(key)) + float( current_weight) + cost_so_far.get(s) if len(fn) < 1: raise Exception("No Path to Destination Exists!") min_key = self.get_min_key(fn) if min_key in self.visited: index = self.visited.index(min_key) self.closed.append(self.visited[index + 1]) self.closed.append(self.visited[index - 1]) cost_so_far[min_key] = float(cost_so_far.get(s)) + float( graph.get_edge_data(s, min_key).get('weight')) queue.append(min_key) if min_key is goal_node: self.endSearch = True self.visited.append(min_key) break
def get_surely_reached_nodes(H: nx.Graph): currentlyListening = list(H.nodes) currentlyTransmitting = [0] currentlyListening.remove(0) currentlySleeping = [] reachedNodes = [] # every iteration of the while is a slot while(True): activeInNextSlot = [] collectiveNeighborhood = [] for transmitting in currentlyTransmitting: reachedNodes.append(transmitting) # get neighbors from every transmitting node # but only those who are still listening neighborhood = H.neighbors(transmitting) neighborhood = list(set(neighborhood) & set(currentlyListening)) # set of all currently reachable nodes, with repetitions. # If a node appears more than once, it means that it # would detect a collision in the next slot collectiveNeighborhood.extend(neighborhood) # collective neighborhood now contains listening nodes # that will receive the message on next slot or will detect a collision # count how many times a node appears in the neighborhood count = Counter(collectiveNeighborhood) for node in count: # if it appears just once, it won't detect a collision if(count[node] == 1): activeInNextSlot.append(node) # next slot arrives # who transmitted, goes to sleep currentlySleeping.extend(currentlyTransmitting) # who went to sleep is not listening any more currentlyListening = list(set(currentlyListening) - set(currentlySleeping)) # who is now going to transmit is not listening any more too currentlyListening = list(set(currentlyListening) - set(activeInNextSlot)) # who was reached is now transmitting currentlyTransmitting = activeInNextSlot reachedNodes = list(set(reachedNodes) | set(activeInNextSlot)) if(len(currentlyListening) == 0 or len(currentlyTransmitting) == 0): break return reachedNodes
def append_rand_edge(g: nx.Graph, depth: int = 0) -> object: rn1 = get_rand_node(g) exclude_nodes = [rn1] exclude_nodes.extend(g.neighbors(rn1)) rn2: object = get_rand_node_excluding(g, exclude_nodes) g.add_edge(rn1, rn2) if depth == 0: return g else: return append_rand_edge(g, depth - 1)
def total_ts_2(c: nx.Graph): user = c.graph['user'] sum_ts = 0 for n in c.neighbors(user): edge = c[user][n]['relationship'] sum_ts += edge.tie_strength_2() return sum_ts
def bfs(g: nx.Graph, start_node: Hashable) -> List[Hashable]: """ Do an breadth-first search and returns list of nodes in the visited order :param g: input graph :param start_node: starting node for search :return: list of nodes in the visited order """ list_ = list(g.neighbors(start_node)) len_graph = g.number_of_nodes() list2 = [start_node] while len(list2) < len_graph: for i in range(len(list_) - 1): if list_[0] not in list2: list2.append(list_[0]) list_ += list(g.neighbors(list_[0])) list_.remove(list_[0]) # nx.draw(g, with_labels=True) # plt.show() return list2
def transform(g: Graph, c_as): g.ip_prefixes = PyTricia() for n in g.nodes(): cust = set() prov = set() peer = set() for n1, n2 in g.edges(n): e = g.edges[n1, n2] if e['rel'] == 'pc': cust.add(n2) elif e['rel'] == 'cp': prov.add(n2) elif e['rel'] == 'pp': peer.add(n2) # g.node[n]['asn'] = n g.node[n]['customers'] = cust g.node[n]['providers'] = prov g.node[n]['peers'] = peer g.node[n]['ip-prefixes'] = set() # g.node[n]['ip'] = None g.node[c_as]['ip-prefixes'].add("1.1.1.1/24") g.ip_prefixes["1.1.1.1/24"] = c_as for node_id in g.nodes(): node_obj = g.node[node_id] node_obj['adj-ribs-in'] = {n: PyTricia() for n in g.neighbors(node_id)} node_obj['rib'] = PyTricia() node_obj['adj-ribs-out'] = { n: PyTricia() for n in g.neighbors(node_id) } node_obj['local_policy'] = PyTricia() for n in g.nodes(): g.node[n]['rib'] = PyTricia() for prefix in g.node[n]['ip-prefixes']: update_initial_rib(g.node[n]['rib'], prefix, True) # out_ribs = G.node[n]['adj-ribs-out'] # for d in out_ribs: # update_initial_rib(out_ribs[d], prefix, n) g.node[n]['adj-ribs-in'] = {n: PyTricia() for n in g.neighbors(n)} g.node[n]['adj-ribs-out'] = {n: PyTricia() for n in g.neighbors(n)}
def argmax_dsat(g: nx.Graph): max_ = [] v_ = -1 for n in g.nodes: if c[n] == -1: neighbours = g.neighbors(n) unique_colours_ = {c[i] for i in neighbours} if len(unique_colours_) > len(max_): max_ = unique_colours_ v_ = n return v_, max_
def normalized_cut(graph: nx.Graph, community: object, summary: bool = True) -> object: """Normalized variant of the Cut-Ratio .. math:: f(S) = \\frac{c_S}{2m_S+c_S} + \\frac{c_S}{2(m−m_S )+c_S} where :math:`m` is the number of graph edges, :math:`m_S` is the number of community internal edges and :math:`c_S` is the number of community nodes. :param graph: a networkx/igraph object :param community: NodeClustering object :param summary: boolean. If **True** it is returned an aggregated score for the partition is returned, otherwise individual-community ones. Default **True**. :return: If **summary==True** a FitnessResult object, otherwise a list of floats. Example: >>> from cdlib.algorithms import louvain >>> from cdlib import evaluation >>> g = nx.karate_club_graph() >>> communities = louvain(g) >>> mod = evaluation.normalized_cut(g,communities) :References: 1.Shi, J., Malik, J.: Normalized cuts and image segmentation. Departmental Papers (CIS), 107 (2000) """ graph = convert_graph_formats(graph, nx.Graph) values = [] for com in community.communities: coms = nx.subgraph(graph, com) ms = len(coms.edges()) edges_outside = 0 for n in coms.nodes(): neighbors = graph.neighbors(n) for n1 in neighbors: if n1 not in coms: edges_outside += 1 try: ratio = (float(edges_outside) / ((2 * ms) + edges_outside)) + float(edges_outside) / ( 2 * (len(graph.edges()) - ms) + edges_outside) except: ratio = 0 values.append(ratio) if summary: return FitnessResult(min=min(values), max=max(values), score=np.mean(values), std=np.std(values)) return values
def polygon_dots_skeleton(polygon, points): ''' ''' skeleton = Graph() rbox = '\n'.join( ['2', str(len(points))] + ['%.2f %.2f' % (x, y) for (x, y) in points] + [''] ) qvoronoi = Popen('qvoronoi o'.split(), stdin=PIPE, stdout=PIPE) output, error = qvoronoi.communicate(rbox) voronoi_lines = output.splitlines() if qvoronoi.returncode: raise _QHullFailure('Failed with code %s' % qvoronoi.returncode) vert_count, poly_count = map(int, voronoi_lines[1].split()[:2]) for (index, line) in enumerate(voronoi_lines[2:2+vert_count]): point = Point(*map(float, line.split()[:2])) if point.within(polygon): skeleton.add_node(index, dict(point=point)) for line in voronoi_lines[2+vert_count:2+vert_count+poly_count]: indexes = map(int, line.split()[1:]) for (v, w) in zip(indexes, indexes[1:] + indexes[:1]): if v not in skeleton.node or w not in skeleton.node: continue v1, v2 = skeleton.node[v]['point'], skeleton.node[w]['point'] line = LineString([(v1.x, v1.y), (v2.x, v2.y)]) if line.within(polygon): skeleton.add_edge(v, w, dict(line=line, length=line.length)) removing = True while removing: removing = False for index in skeleton.nodes(): if skeleton.degree(index) == 1: depth = skeleton.node[index].get('depth', 0) if depth < 20: other = skeleton.neighbors(index)[0] skeleton.node[other]['depth'] = depth + skeleton.edge[index][other]['line'].length skeleton.remove_node(index) removing = True logging.debug('found %d skeleton edges' % len(skeleton.edge)) return skeleton