def join_overlapping_vertices(graph: Graph, vertex1, vertex2, layer): """ Joins two vertices by moving all edges from vertex2 to vertex1 . and then removes vertex2. 'vertex1', 'vertex2' - vertices to join, should be overlapping Returns vertex1 if joined. Returns None if vertices are not overlapped. """ vertex1_x, vertex1_y = graph.nodes()[vertex1]['position'] vertex2_x, vertex2_y = graph.nodes()[vertex2]['position'] if math.isclose(vertex1_x, vertex2_x) \ and math.isclose(vertex1_y, vertex2_y): vertex1_neighbours = get_neighbors_at(graph, vertex1, layer) vertex2_neighbours = get_neighbors_at(graph, vertex2, layer) for vertex2_neighbour in vertex2_neighbours: if vertex2_neighbour not in vertex1_neighbours: graph.add_edge(vertex1, vertex2_neighbour) graph.remove_node(vertex2) return vertex1 return None
def join_overlapping_vertices(graph: Graph, vertex1, vertex2, layer): """ Joins two vertices by moving all edges from `vertex2` to `vertex1`, then it removes `vertex2`. 'vertex1', 'vertex2' - vertices to join, should be overlapping Returns vertex1 if joined. Returns None if vertices are not overlapping. """ v1_pos = graph.nodes()[vertex1]['position'] v2_pos = graph.nodes()[vertex2]['position'] if is_close(v1_pos, v2_pos): vertex1_neighbors = get_neighbors_at(graph, vertex1, layer) vertex2_neighbors = get_neighbors_at(graph, vertex2, layer) for vertex2_neighbor in vertex2_neighbors: if vertex2_neighbor not in vertex1_neighbors: graph.add_edge(vertex1, vertex2_neighbor) graph.remove_node(vertex2) return vertex1 return None
def P3(graph: nx.Graph, hyp_b, hyp_is, hyp_f, image: Image): __assert_hyper_edge(graph, [hyp_b], 'B') __assert_hyper_edge(graph, hyp_is, 'I') __assert_hyper_edge(graph, [hyp_f]) hyp_f_data = graph.node[hyp_f] hyp_b_data = graph.node[hyp_b] hyp_f_neighbour_ids = list(graph.neighbors(hyp_f)) if len(hyp_f_neighbour_ids) != 1: raise ValueError('F should have 1 neighbour') for hyp_i in hyp_is: if hyp_f_neighbour_ids[0] not in list(graph.neighbors(hyp_i)): raise ValueError('I is not connected with F1 via neighbour') hyp_f_neighbour_data = graph.node[hyp_f_neighbour_ids[0]] if hyp_f_data['label'] == Direction.N.name: if hyp_f_data['x'] != hyp_f_neighbour_data['x'] or hyp_f_data[ 'y'] <= hyp_f_neighbour_data['y']: raise ValueError('F hyperedge has weird position') if hyp_f_data['x'] != hyp_b_data['x'] or hyp_f_data['y'] >= hyp_b_data[ 'y']: raise ValueError('F hyperedge has weird position (B)') elif hyp_f_data['label'] == Direction.S.name: if hyp_f_data['x'] != hyp_f_neighbour_data['x'] or hyp_f_data[ 'y'] >= hyp_f_neighbour_data['y']: raise ValueError('F hyperedge has weird position') if hyp_f_data['x'] != hyp_b_data['x'] or hyp_f_data['y'] <= hyp_b_data[ 'y']: raise ValueError('F hyperedge has weird position (B)') elif hyp_f_data['label'] == Direction.E.name: if hyp_f_data['x'] <= hyp_f_neighbour_data['x'] or hyp_f_data[ 'y'] != hyp_f_neighbour_data['y']: raise ValueError('F hyperedge has weird position') if hyp_f_data['x'] >= hyp_b_data['x'] or hyp_f_data['y'] != hyp_b_data[ 'y']: raise ValueError('F hyperedge has weird position (B)') elif hyp_f_data['label'] == Direction.W.name: if hyp_f_data['x'] >= hyp_f_neighbour_data['x'] or hyp_f_data[ 'y'] != hyp_f_neighbour_data['y']: raise ValueError('F hyperedge has weird position') if hyp_f_data['x'] <= hyp_b_data['x'] or hyp_f_data['y'] != hyp_b_data[ 'y']: raise ValueError('F hyperedge has weird position (B)') else: raise ValueError('F hyperedge has weird label') new_node_position = (hyp_b_data['x'], hyp_b_data['y']) new_node_id = get_node_id(new_node_position) __add_new_node(graph, image, new_node_id, new_node_position) # add v __add_hyperedges_between_neighbour_nodes( graph, hyp_b, new_node_id, new_node_position) # add 1-b-v-b-2 for hyp_i in hyp_is: __add_edges_between_nodes(graph, new_node_id, hyp_i) # add v-i and v-i __add_edges_between_nodes(graph, new_node_id, hyp_f) # add v-f1 graph.remove_node(hyp_b)
def merge_mwvc_constraints(agt1: str, G1: nx.Graph, agt2: str, G2: nx.Graph) -> (nx.Graph, nx.Graph): """ Merge the weights associated to the nodes of type 'dec_var' that have the same 'name'. It assigns :param agt1: The name of agent 1 :param G1: The gadget graph associated to agent 1 :param agt2: The name of agent 2 :param G2: The gadget graph associated to agent 2 :return: The pairs of gadget (gadget1 and gadget2) associated to agents 1 and 2, reps. processed after the merging operation. """ shared_dec_vars = [ n for n in G1.nodes() for m in G2.nodes() if n == m and G1.nodes[n]['type'] == 'dec_var' ] for u in shared_dec_vars: if agt1 <= agt2: G1.nodes[u]['weight'] += G2.nodes[u]['weight'] for e in G2.edges(u): G1.add_edge(e[0], e[1], w=G2.get_edge_data(*e)['w']) G2.remove_node(u) else: G2.nodes[u]['weight'] += G1.nodes[u]['weight'] for e in G1.edges(u): G2.add_edge(e[0], e[1], w=G1.get_edge_data(*e)['w']) G1.remove_node(u) return G1, G2
def lp_reduction(graph: nx.Graph): """ Delete high-degree (degre > budget) vertices :param graph: copy of graph to reduce :param budget: parameter k :return: (new_graph, vc) """ lpsoln = utils.halfint_lpvc(graph) num_half = 0 lpvals = set(lpsoln.values()) if 1 in lpvals or 0 in lpvals: print("#" * 80) print(set(lpsoln.values())) print("#" * 80) vc = set() for u, lpval in lpsoln.items(): if lpval <= 0.25: graph.remove_node(u) elif lpval >= 0.75: vc.add(u) graph.remove_node(u) else: num_half += 1 #if num_half == len(lpsoln): # print("all half", check_all_half_lp(graph, lpsoln)) # sys.exit() return graph, vc, sum(lpsoln.values())
def remove_edge_order(self, g: nx.Graph, list_edges) -> Tuple[int]: new_graph = None delete_edge = () orphan_node = None for i, delete_edge in enumerate(list_edges): new_graph = g.copy() new_graph.remove_edge(*delete_edge) if nx.classes.function.is_empty(new_graph): delete_edge = () break elif nx.is_connected(new_graph): list_edges.pop(i) break orphan_nodes = [ nid for nid, degree in new_graph.degree if degree == 0 ] if len(orphan_nodes) == 1: orphan_node = orphan_nodes[0] list_edges.pop(i) break if len(delete_edge) > 0: g.remove_edge(*delete_edge) if orphan_node != None: g.remove_node(orphan_node) return delete_edge
def on_grounded_button_clicked(self): current_item = self.collection_list.currentItem() self.collections_grounded.clear() self.grounded_list.clear() G = self.collections[self.collection_list.row(current_item)] item = QListWidgetItem("Released") try: icon = graph(G, self.grounded_list.iconSize().width(), self.ground_engine) except EngineError as e: self.engineErrorMsg(e) return item.setIcon(icon) self.collections_grounded.append(G) self.grounded_list.addItem(item) for node in G.nodes: G_ = Graph(G) G_.remove_node(node) error = False for H in self.collections_grounded: if is_isomorphic(G_, H): error = True if error: continue item = QListWidgetItem("link_{} constrainted".format(node)) icon = graph(G, self.grounded_list.iconSize().width(), self.ground_engine, except_node=node) item.setIcon(icon) self.collections_grounded.append(G_) self.grounded_list.addItem(item) self.grounded_merge.setEnabled(bool(self.grounded_list.count()))
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 drop_diff_point(G1: nx.Graph, G2: nx.Graph): nodes = list(G1.nodes()) for node in nodes: if not (node in G2): G1.remove_node(node) nodes = list(G2.nodes()) for node in nodes: if not (node in G1): G2.remove_node(node)
def remove_node(self, n): try: if len(self.adj[n]) == 1: # allowed for leaf node Graph.remove_node(self, n) else: raise NetworkXError( "deleting interior node %s not allowed in tree" % (n)) except KeyError: # NetworkXError if n not in self raise NetworkXError("node %s not in graph" % n)
def _rm_empty_unit(processor: Graph, unit: object) -> None: """Remove a unit from the given processor. `processor` is the processor to remove the unit from. `unit` is the unit to remove. """ warning("No capabilities defined for unit %s, removing...", unit) processor.remove_node(unit)
def remove_node(self, node): """ Remove node from network. """ if node not in self.nodes(): logger.error("Node not in network") return Graph.remove_node(self, node) del self.pos[node] del self.labels[node] node.network = None logger.info('Node with id %d is removed.' % node.id)
def remove_node(self, node): """ Remove node from network. """ if node not in self.nodes(): logger.error("Node not in network") return Graph.remove_node(self, node) del self.pos[node] del self.labels[node] node.network = None logger.debug('Node with id %d is removed.' % node.id)
def get_graph(edges): G = Graph() G.add_weighted_edges_from(edges) nodes = G.nodes() print(f'Num initial nodes after MIN_DIST: {len(nodes)}') for n in nodes: if G.degree(n) < MIN_DEGREE: G.remove_node(n) print(f'Num nodes after degree filter: {len(G.nodes())}') return G
def remove_edge(self, u, v=None): if v is None: (u, v) = u if self.degree(u) == 1 or self.degree(v) == 1: # leaf edge Graph.remove_edge(self, u, v) else: # interior edge raise NetworkXError( "deleting interior edge %s-%s not allowed in tree" % (u, v)) if self.degree(u) == 0: # OK to remove remaining isolated node Graph.remove_node(self, u) if self.degree(v) == 0: # OK to remove remaining isolated node Graph.remove_node(self, v)
def assign_registers_to_line_or_cycle(start: int, graph: nx.Graph, num_length: int) \ -> Tuple[Sequence[int], Sequence[int], int, int]: """ From the start node assign registers as they are laid out in the ideal circuit diagram in [CDKM96]_. Assumes that the there are no dead ends in the graph, and any available neighbor can be selected from the start without any further checks. :param start: a node in the graph from which to start the assignment :param graph: a graph with an unambiguous assignment from the start node, e.g. a cycle or line :param num_length: the length of the bitstring representation of one summand :return: the necessary registers and ancilla labels for implementing an adder program to add the numbers a and b. The output can be passed directly to :func:`adder` """ if 2 * num_length + 2 > nx.number_of_nodes(graph): raise ValueError( "There are not enough qubits in the graph to support the computation." ) graph = graph.copy() register_a = [] register_b = [] # set the node at start, and assign the carry_ancilla to this node. node = start carry_ancilla = node neighbors = list(graph.neighbors(node)) idx = 0 while idx < 2 * num_length: # remove the last assigned node to ensure it is not reassigned. last_node = node graph.remove_node(last_node) # crawl to an arbitrary neighbor node if possible. If not, the assignment has failed. if len(neighbors) == 0: raise ValueError("Encountered dead end; assignment failed.") node = neighbors[0] neighbors = list(graph.neighbors(node)) # alternate between assigning nodes to the b register and a register, starting with b if (idx % 2) == 0: register_b.append(node) else: register_a.append(node) idx += 1 # assign the z_ancilla to a neighbor of the last assignment to a z_ancilla = next(graph.neighbors(node)) return register_a, register_b, carry_ancilla, z_ancilla
def P2(graph: nx.Graph, hyperedge_id, image: Image): __assert_hyper_edge(graph, hyperedge_id) hyperedge_data = graph.node[hyperedge_id] new_node_position = (hyperedge_data['x'], hyperedge_data['y']) new_node_id = get_node_id(new_node_position) old_depth = hyperedge_data.get("depth", 0) new_depth = old_depth + 1 __add_new_node(graph, image, new_node_id, new_node_position) __add_hypereges_between_nodes(graph, hyperedge_id, new_node_id, new_node_position, new_depth) __add_direction_hyperedges(graph, new_node_id, create_direction_calulcator(old_depth)) graph.remove_node(hyperedge_id)
def add_city_geocode(network: nx.Graph): cities = network.nodes latitude, longitude = get_geocode(cities) for city, lat in latitude.items(): if isclose(lat, 999.0) or type(lat) != type(1.0): try: network.remove_node(city) except Exception as e: print(e) nx.set_node_attributes(network, latitude, 'Latitude') nx.set_node_attributes(network, longitude, 'Longitude') return network
def precompute(words, length): words = [w for w in words if len(w) == length] by_letters = group_by_key_func(words, lambda w: "".join(sorted(w))) graph = Graph() by_subletters = defaultdict(list) for key in by_letters: counts = tuple(Counter(key).items()) for differing_letters in [1, 2]: for subletters in combinations(counts, len(counts) - differing_letters): by_subletters[subletters].append(key) for group in by_subletters.values(): for u, v in combinations(group, 2): u_counts = Counter(u) v_counts = Counter(v) less = None more = None for letter in u_counts.keys() | v_counts.keys(): if u_counts[letter] == v_counts[letter]: continue elif u_counts[letter] == v_counts[letter] + 1 and more is None: more = letter elif u_counts[letter] == v_counts[letter] - 1 and less is None: less = letter else: break else: assert less and more graph.add_edge(u, v) components = list(networkx.connected_components(graph)) nodes = list(max(components, key=len)) graph: networkx.Graph = graph.subgraph(nodes).copy() degree = graph.degree leaves = [node for node in nodes if degree[node] == 1] for leaf in leaves: while True: neighbors = list(graph.neighbors(leaf)) if len(neighbors) != 1: break graph.remove_node(leaf) leaf = neighbors[0] result = {} for node in graph: neighbors = list(graph.neighbors(node)) assert len(neighbors) > 1 result[node] = [by_letters[node], neighbors] return result
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 = list(map(int, voronoi_lines[1].split()[:2])) for (index, line) in enumerate(voronoi_lines[2:2 + vert_count]): point = Point(*list(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 = list(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
def remove_topic_nodes(graph: nx.Graph) -> None: """Drops topic nodes from the graph.""" logger.info("Dropping topic nodes") logger.info( f"Original graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges" ) drop = set() for node in graph.nodes: if graph.nodes[node]["kind"] == "topic": drop.add(node) for node in drop: graph.remove_node(node) logger.info( f"Updated graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges" )
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
def singleSourceSP(G: nx.Graph, A_i: list): """Return node: (dist, p(node)) for A_i Arguments: G {nx.Graph} -- [description] A_i {list} -- [description] """ virtNodeId = len(G.nodes()) G.add_node(virtNodeId) G.add_weighted_edges_from([(i, virtNodeId, 0) for i in A_i]) distances, paths = nx.single_source_dijkstra(G, virtNodeId) G.remove_node(virtNodeId) path = {node: paths[node][1] for node in paths if node != virtNodeId} return distances, path
def dijkstra(graph: Graph, source: int, target: int): graph.nodes[source]["distance"] = 0 while graph.nodes: shortest_path_node = get_node_with_minimal_distance(graph) if target == shortest_path_node: return graph.nodes[target]["distance"] for neighbour in graph.neighbors(shortest_path_node): alt = graph.nodes[shortest_path_node]["distance"] + \ graph.get_edge_data(shortest_path_node, neighbour)["weight"] if alt < graph.nodes[neighbour]["distance"]: graph.nodes[neighbour]["distance"] = alt graph.remove_node(shortest_path_node) return graph
def _rm_dead_end(processor: Graph, dead_end: object, in_ports: typing.Container[object]) -> None: """Remove a dead end from the given processor. `processor` is the processor to remove the dead end from. `dead_end` is the dead end to remove. `in_ports` are the processor original input ports. A dead end is a port that looks like an output port after optimization actions have cut it off real output ports. """ if dead_end in in_ports: # an in-port turned in-out port raise DeadInputError("No feasible path found from input port " f"${DeadInputError.PORT_KEY} to any output ports", dead_end) warning("Dead end detected at unit %s, removing...", dead_end) processor.remove_node(dead_end)
def apply_clustering(graph: networkx.Graph, cluster_dict): """ Takes a graph and a dictionary of [cluster head - cluster member list] and changes the graph to represent the clustered graph, i.e. only display the cluster heads and their connectivity. :param graph: a networkx.Graph :param cluster_dict: cluster heads as keys, cluster members as values :return: """ # create adjacency matrix for clusters cluster_adj = dict() if len(cluster_dict) > 1: for cluster_head1 in cluster_dict: for cluster_head2 in cluster_dict: if cluster_head1 == cluster_head2: continue cluster1 = cluster_dict[cluster_head1] | {cluster_head1} cluster2 = cluster_dict[cluster_head2] | {cluster_head2} if edge_exists(graph, cluster1, cluster2): try: cluster_adj[cluster_head1].append(cluster_head2) except KeyError: cluster_adj[cluster_head1] = [cluster_head2] # remove all nodes that are not cluster heads for node in graph.nodes(): if node not in cluster_adj: graph.remove_node(node) # remove all old edges graph.remove_edges_from(graph.edges()) for n1 in cluster_adj: for n2 in cluster_adj[n1]: graph.add_edge(n1, n2) else: # only one cluster head for node in graph.nodes(): if node not in cluster_dict: graph.remove_node(node) return graph
def embed_chain(chain, hardware_graph: nx.Graph): current_deg = len(hardware_graph) for node in hardware_graph: deg = hardware_graph.degree(node) if deg < current_deg: current_node = node embedding = {current_node: chain[0]} for log_qb in chain[1:]: current_deg = len(hardware_graph) for neighbor in hardware_graph.neighbors(current_node): deg = hardware_graph.degree(neighbor) if deg < current_deg: new_node = neighbor current_deg = deg embedding[new_node] = log_qb hardware_graph.remove_node(current_node) current_node = new_node new_node = None hardware_graph.remove_node(current_node) return embedding
def remove_edge(self, g: nx.Graph) -> Tuple[int]: random.seed(42) new_graph = None delete_edge = () tried_edges = [] orphan_node = None # if g.number_of_nodes() == g.number_of_edges() + 1: # return None while True: delete_edge = random.choice(list(g.edges)) while set(delete_edge) in tried_edges: delete_edge = random.choice(list(g.edges)) # print(delete_edge) new_graph = g.copy() new_graph.remove_edge(*delete_edge) tried_edges.append(set(delete_edge)) if nx.classes.function.is_empty(new_graph): delete_edge = () break elif nx.is_connected(new_graph): break orphan_nodes = [ nid for nid, degree in new_graph.degree if degree == 0 ] if len(orphan_nodes) == 1: orphan_node = orphan_nodes[0] break if len(delete_edge) > 0: g.remove_edge(*delete_edge) if orphan_node != None: g.remove_node(orphan_node) return delete_edge
def monopolar_partition(input_graph, k): DEBUG = False #initialization G = input_graph A_init = Graph() #an empty graph B_init = input_graph Q = [ [A_init, B_init], ] # deliberately double-depth Q to manage 'branches' #loop body for branch in Q: A = branch[0] if DEBUG == True: print "A " print A.nodes() B = branch[1] if DEBUG == True: print "B " print B.nodes() if nx.number_of_nodes(A) > k: continue #reject branch p2s = forbidden_graphs(B) if DEBUG == True: print "p2s " print p2s if p2s == []: return True break else: p2s = p2s[0] for vertex in p2s: A_new = nx.union(A, nx.subgraph(input_graph, vertex)) B_new = Graph(B) B_new.remove_node(vertex) Q.append([A_new, B_new]) #all else fails return False
def on_grounded_button_clicked(self): """Grounded combinations.""" current_item = self.collection_list.currentItem() self.collections_grounded.clear() self.grounded_list.clear() G = self.collections[self.collection_list.row(current_item)] item = QListWidgetItem("Released") try: icon = graph(G, self.grounded_list.iconSize().width(), self.ground_engine) except EngineError as e: self.engineErrorMsg(e) return item.setIcon(icon) self.collections_grounded.append(G) self.grounded_list.addItem(item) def isomorphic(G: Graph, l: List[Graph]) -> bool: for H in l: if is_isomorphic(G, H): return True return False for node in G.nodes: G_ = Graph(G) G_.remove_node(node) if isomorphic(G_, self.collections_grounded): continue item = QListWidgetItem("link_{}".format(node)) icon = graph(G, self.grounded_list.iconSize().width(), self.ground_engine, except_node=node) item.setIcon(icon) self.collections_grounded.append(G_) self.grounded_list.addItem(item) self.grounded_merge.setEnabled(bool(self.grounded_list.count()))
def approximate_minimal_edge_length_for_graph(graph: nx.Graph, max_length: float, max_angle: float, scale: np.ndarray): nodes_with_degree_of_two = [ node for node in graph.nodes if graph.degree(node) == 2 ] for node_id in nodes_with_degree_of_two: current_node = graph.nodes[node_id] neighbors = list(graph.neighbors(node_id)) neighbor1 = graph.nodes[neighbors[0]] neighbor2 = graph.nodes[neighbors[1]] vector1 = get_vector_between_nodes(neighbor1, current_node, scale) vector2 = get_vector_between_nodes(current_node, neighbor2, scale) new_edge_vector = get_vector_between_nodes(neighbor1, neighbor2, scale) distance_between_combined_edges = vector_length(new_edge_vector) angle = calculate_angle_between_vectors(vector1, vector2) if angle <= max_angle and distance_between_combined_edges <= max_length: graph.remove_edges_from([(neighbors[0], node_id), (node_id, neighbors[1])]) graph.remove_node(node_id) graph.add_edge(neighbors[0], neighbors[1])
def remove_node(self, n): Graph.remove_node(self, n) self.fh.write("Remove node: %s\n" % n)
def solve(): from networkx import Graph, number_connected_components from heap.heap import heap def up(p): r, c = divmod(p,C) return (R-1 if r==0 else r-1)*C + c def down(p): r, c = divmod(p,C) return (0 if r==R-1 else r+1)*C + c def left(p): r, c = divmod(p,C) return r*C + (C-1 if c==0 else c-1) def right(p): r, c = divmod(p,C) return r*C + (0 if c==C-1 else c+1) def link(a,b): G.add_edge(('start',a),('end',b)) H[b] += 1 R, C = map(int,input().split()) N = R*C G = Graph() H = heap({n:0 for n in range(N)}) for p in range(N): G.add_node(('start',p)) G.add_node(('end',p)) for p, x in enumerate(x for _ in range(R) for x in input().strip()): if x == '|': link(p,up(p)) link(p,down(p)) elif x == '-': link(p,left(p)) link(p,right(p)) elif x == '/': link(p,down(left(p))) link(p,up(right(p))) elif x == '\\': link(p,up(left(p))) link(p,down(right(p))) while H[H.peek()] <= 1: p, ins = H.popitem() if ins == 0: # There is a sqaure such that no other square points to it. # It's impossible for a lemming to get here. # So there are no proper ways to arrange this. return 0 else: # There is exactly one edge leading into p. # Remove the relevant nodes. _, q = next(iter(G['end',p])) r = next(r for _, r in G['start',q] if r != p) G.remove_node(('end',p)) G.remove_node(('start',q)) # If q now points to p, the other square that q points to # has one fewer square pointing to it. H[r] -= 1 # Now all remaining nodes are cycles, and there are exatly two ways # to choose the directions for each cycle. return pow(2,number_connected_components(G),1000003)
class LangGraph(object): """ A graph of all the relationships in a document and/or sentence """ def __init__(self, directed=False): """ Builds a graph out of the given document """ self.isDirected = directed #a graph that is meant to be full of class Instance if self.isDirected: self.graph = DiGraph() else: self.graph = Graph() self.start = None #an Instance #keep the graph also according to temporal, redundant probably needs #refactoring self.temporal = None self.temporalMap = None def setStart(self, start): """ Sets the starting instance, also builds the temporal ordering of the graph """ self.start = start self.temporal = self.narrativeOrder() self.temporalMap = self.narrativeMapping() def indexToInst(self, index): """ Returns the instance corresponding to the given index """ result = index #if the index is an int, lookup the instance associated with it if type(index) == int: result = self.temporal[index] return result def instToIndex(self, instance): """ Return the index associated with the instance """ return self.temporalMap[instance] def narrativeOrder(self): """ Returns the instances in narrative order """ results = [] node = self.start prev = None #while there are more nodes, keep adding them while node is not None: #record the current node results.append(node) #get the connected nodes fringe = [n for n in self.adj(node, WORD_EDGE) if n != prev] nextNode = fringe[0] if fringe else None #advance to the next node prev = node node = nextNode return results def narrativeMapping(self): """ Makes the mapping from instances to their narrative index """ return {inst:i for i,inst in enumerate(self.temporal)} def addNode(self, node): """ Adds a node to the graph """ self.graph.add_node(node) def addEdge(self, start, end, type): """ Adds an edge between the two instances """ #if the edge exists, just add the type if self.graph.has_edge(start, end): self.addType(start, end, type) else: self.graph.add_edge(start, end, TYPES=set([type])) def removeEdge(self, start, end, edgeType): """ Removes an edge with a given type from the edge type """ #remove the type self.removeType(start, end, edgeType) #if there are no types, remove the edge itself types = self.edgeTypes(start, end) #remove the edge if not len(types) and self.graph.has_edge(start, end): self.graph.remove_edge(start, end) def addType(self, start, end, type): """ Adds a type between the edges """ #look for existing types types = self.graph[start][end].get(TYPES, set()) #add the new type types.add(type) self.graph[start][end][TYPES] = types def removeType(self, start, end, edgeType): """ Removes the type on the edge """ for prefix in [PARENT, CHILD]: edgeType = removePrefix(prefix, edgeType) types = self.graph[start][end][TYPES] #if the types contains the edge, remove if edgeType in types: types.remove(edgeType) def hasType(self, start, end, type): """ Returns true if the edge between the two nodes has the given type """ return type in self.edgeTypes(start, end) def singleEdgeTypes(self, start, end): """ Returns the types on the edge if any, or an empty set is returned """ #make sure we are using instances rather than indexes start = self.indexToInst(start) end = self.indexToInst(end) data = self.graph.get_edge_data(start,end) result = set() #if there is data, get the types if data is not None: result = data.get(TYPES, set()) return result def edgeTypes(self, start, end): """ Returns the types on the edge if any, or an empty set is returned """ if self.isDirected: parent = addPrefixes(PARENT, self.singleEdgeTypes(end, start)) child = addPrefixes(CHILD, self.singleEdgeTypes(start, end)) types = parent.union(child) else: types = self.singleEdgeTypes(start, end) return types def allEdgeTypes(self): """ Returns all the edge types """ results = set() #collect all the edges with all the types for s,e,types in self.allEdges(): #look up the edge types to make sure everything is covered for edgeType in types: results.add(edgeType) #add in the reverse types for edgeType in self.edgeTypes(e,s): results.add(edgeType) return results def allEdges(self): """ Yield all the edges in the graph """ for start, end in self.graph.edges(): yield start, end, self.edgeTypes(start, end) def contains(self, instance): """ Returns true if the graph contains the instance """ return self.graph.has_node(instance) def instances(self): """ Return all the instances in the graph """ return self.graph.nodes() def edges(self, instance): """ Returns all the edges connected to this instance """ inst = self.indexToInst(instance) #make get the directed edges if self.isDirected: results = [t for _, t in self.graph.out_edges(inst)] + [t for t, _ in self.graph.in_edges(inst)] else: results = self.graph.adj[inst] return results def docType(self): """ Returns the document type (String) """ return self.temporal[0].event.docType def adj(self, instance, type=None): """ Returns the adjancent node with a given type """ return [other for other in self.edges(instance) if self.hasType(instance, other, type) or type is None] def nonNarrativeAdj(self, instance, returnIndex=False): """ Returns the nodes that are not adjancent to the given instance """ results = [] #add each node if it has a non-narrative (temporal) connection for node in self.edges(instance): #get the non narrative types edgeTypes = nonNarrativeTypes(self.edgeTypes(instance, node)) #if there is a non-narrative edge, add it if edgeTypes: #lookup the index of the node nodeMarker = self.instToIndex(node) if returnIndex else node results.append((nodeMarker, edgeTypes)) return results def words(self): """ Returns the words in narrative order """ return [t.word for t in self.tokens()] def tokens(self): """ Returns the tokens in narrative order """ return [i.token for i in self.temporal] def labels(self): """ Returns the sequence of labels for the instances """ return [i.event.type for i in self.temporal] def removeAny(self, blackList): """ Removes any nodes/tokens/instances that match the words in the blacklist """ #if a token or its lemma match any of the words in the blacklist #mark it for removal toRemove = {inst.token for inst in self.temporal if inst.token.word.lower() in blackList or inst.token.lemma.lower() in blackList} self.removeNodes(toRemove) def removeNodes(self, tokens): """ Removes the token from the graph """ startLen = len(self) #mark all the instances/indexes to remove instances = {inst:i for inst,i in self.temporalMap.items() if inst.token in tokens} #determine the remaining nodes remaining = sorted(list(set(range(startLen)) - {i for i in instances.values()})) #add in all the bypasses for startIndex, endIndex in iterPairs(remaining): start = self.temporal[startIndex] end = self.temporal[endIndex] self.addEdge(start, end, WORD_EDGE) #remove the edges for inst in instances: self.graph.remove_node(inst) #if there are remaining nodes then reset the temporal mapping if remaining: startIndex = min(remaining) self.start = self.temporal[startIndex] #redo narrative order self.temporal = self.narrativeOrder() self.temporalMap = self.narrativeMapping() else: self.start = None self.temporal = [] self.temporalMap = {} def copy(self): """ Performs a shallow copy of the graph """ newGraph = LangGraph(self.isDirected, self.entEdges) #create new instances newInst = {i:me.Instance(copy(i.token), i.event) for i in self.temporal} #add in all the edges for start, end in self.graph.edges(): for eType in self.edgeTypes(start, end): newGraph.addEdge(newInst[start], newInst[end], eType) newGraph.setStart(newInst[self.start]) return newGraph def graphString(self): """ Returns the graph as a string """ return " ".join([t.word for t in self.tokens()]) def __len__(self): """ Returns the number of nodes (tokens) in the graph """ return len(self.graph) def __repr__(self): """ Returns a summary string of the graph """ return "LangGraph {} nodes, {} edges".format(len(self.graph.nodes()), len(self.graph.edges()))
utm_zone_number = pos[2] graph.add_node(item.id, lat=item.lat, lon=item.lon, pos=pos[:2]) #nodes += 1 items += 1 print('{0} items processed'.format(items), end='\r') print('{0} items processed'.format(items)) if shape_file: n = graph.number_of_nodes() i = 0 print('Apply shapefile') for node in graph.nodes(): p = Point(graph.node[node]['lon'], graph.node[node]['lat']) if not shape_file.contains(p): graph.remove_node(node) i += 1 print('{0}/{1} nodes processed'.format(i, n), end='\r') print('{0}/{1} nodes processed'.format(i, n)) print('Search for orphaned nodes') orphaned = set() n = graph.number_of_nodes() i = 0 for node in graph.nodes_iter(): if graph.degree(node) == 0: orphaned.add(node) i += 1 print('{0}/{1} nodes processed'.format(i, n), end='\r') print('{0}/{1} nodes processed'.format(i, n))
def remove_node(self,n): Graph.remove_node(self,n) self.fh.write("Remove node: %s\n"%n)
class Network(HasTraits): """ The implementation of the Connectome Networks """ implements(INetwork) # Network ID, from parsed GraphML the graphid networkid = '' # Network name networkname = Str # network name as seen in the TreeView name = Str # Is it an hierarchical network? hierarchical = CBool(False) # TODO: later, also Hypergraph?! # see: http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1000385 hypergraph = CBool(False) # Directionality of the Network, {True: 'directed', False: 'undirected'} directed = CBool(False) # metadata for the network metadata = Dict # NodeKeys from the parsed GraphML # These are Dict of Dict, all having strings nodekeys = {} # Edgekeys, from parsed GraphML edgekeys = {} # A NetworkX AttrGraph containing all the information graph = Any # Surface containers surfaces = List(ISurfaceContainer) # Surface containers loaded surfaces_loaded = List(ISurfaceContainer) # Volume data volumes = List(IVolume) # Track data tracks = List(ITrackfile) # is this network active, and thus a render manager displayed? active = Bool # the render manager of this network rendermanager = Instance(RenderManager) # DatasourceManager Instance of this network datasourcemanager = Instance(DatasourceManager) # private traits ########### # parent cfile this networks belongs to _parentcfile = Any # filezip of cfile _filezip = DelegatesTo('_parentcfile') # edge parameters for visualization _edge_para = Instance(EdgeParameters) # View traits_view = View( Item('networkname', style = 'readonly'), Item('hierarchical', style = 'simple'), Item('hypergraph', style = 'simple'), Item('directed', style = 'simple'), Item('active', style = 'simple'), title = 'A network', ) def __init__(self, name, src = None, directed = '0', pickled_graph = None, \ hierarchical ='0', hypergraph = '0', graph = None): """ Initializes the network and sets the traits. Parameters ---------- name : string the name of the network src : file handle or StringIO object the source text of the network to parse pickled_graph : NetworkX graph reference to a graph object, src should be None directed : bool Is the network directed? hierarchical : bool Is the network hierarchical? (default: '0') Not implemented yet. hypergraph : bool Is the network a hypergraph? (default: '0') Not implemented yet. """ # initialize the traits self.networkname = name self.directed = int(directed) self.hierarchical = int(hierarchical) self.hypergraph = int(hypergraph) if src is None and not pickled_graph is None: self.load_pickled_graphml(pickled_graph) else: if not src is None: # generates NetworkX Graph self.graph = self.parse_network_graphml(src) elif not graph is None: self.graph = graph else: if self.directed: from networkx import DiGraph self.graph = DiGraph() logger.info("Initialize with empty directed Graph") else: from networkx import Graph self.graph = Graph() logger.info("Initialize with empty undirected Graph") # initializes the weight key of the graph # with the first edgekey if len(self.edgekeys) > 0: edgk = self.edgekeys.keys() if not 'weight' in edgk: self.set_weight_key(edgk[0]) else: # try grabbing first edge from the graph if self.graph.number_of_edges() > 0: it = self.graph.edges_iter(data=True) edg = it.next() if len(edg[2]) > 0: # if it has a weigth key, just leave it edgk = edg[2].keys() if not 'weight' in edgk: self.set_weight_key(edgk[0]) else: pass # logger.error('Cannot set weight key for network : ' + self.networkname) def _name_default(self): return self.networkname def _active_default(self): return False def _active_changed(self , value): if value: n = self.name if ' [Active]' not in n: self.name = "%s [Active]" % n # XXX: do refactor with threaded loading of surfaces # and default spring force layout for graph rendering! # see also TraitsUI Demos: Multi thread demo # load the surface containers data # make a deep copy of the already loaded surface containers import copy self.surfaces = copy.deepcopy(self.surfaces_loaded) for surfcont in self.surfaces: surfcont.load_surface_container() if self.rendermanager is None: self._create_datasourcemanager() self._create_renderer() # if there are no surfaces, initialize # network rendering, but only if dn_positions are given if len(self.surfaces) == 0: logger.debug('No surfaces found. Try to render graph view with dn_position information.') self.rendermanager.datasourcemanager._compute_3DLayout(-1, -1) self.rendermanager.visualize_graph() else: logger.debug('SurfaceContainer found. Try to render 3D View using %s.' % self.surfaces[0].name) if len(self.surfaces[0].surfaces) == 0: logger.debug('Rendering not possible because SurfaceContainer contains no surfaces.') else: logger.debug('Using first surface for rendering.') self.surfaces[0].surfaces[0]._layout_3DView() if not self._parentcfile._workbenchwin is None: #from enthought.pyface.timer.api import do_later from enthought.pyface.api import GUI GUI.invoke_later(self._parentcfile._workbenchwin.status_bar_manager.set, message = '') else: self.name = self.name.replace(' [Active]', '') logger.debug('Close RenderManager scenes') self.rendermanager.close_scenes() logger.debug('All scenes closed.') # FIXME: what is happening in the following? # e.g. for instances. e.g. reset traits? # XXX: this is somehow not correct. do i need to use del # or remove/reset traits? self.rendermanager = None self.datasourcemanager = None self.surfaces = [] def _de_activate(self): """ Toggles the internal state of the activation """ if self.active: self.active = False else: self._parentcfile._workbenchwin.status_bar_manager.message = 'Activating network ...' self.active = True def _edge_parameters(self): """ Dialog to change edge attribute and thresholding """ if self._edge_para is None: self._edge_para = EdgeParameters(self, self.rendermanager.attract.point_scalars_name) self._edge_para.configure_traits() def _create_renderer(self): """ Creates the renderer instance if not yet available and opens the scenes in mayavi """ if self.active: if self.rendermanager is None: logger.debug('Create a RenderManager instance') self.rendermanager = RenderManager(network=self) else: logger.debug('RenderManager instance already running. This is an error.') def _create_datasourcemanager(self): """ Creates the datasource manager instance if not yet available """ if self.active: if self.datasourcemanager is None: logger.debug('Create a DatasourceManager instance') self.datasourcemanager = DatasourceManager(network=self) else: logger.debug('DatasourceManager instance already running. This is an error.') def _render_matrix(self): """ Invokes the connectivity matrix viewer """ # assume the network is activated (i.e. data source generated) # we need the edge parameter instance initialized if self._edge_para is None: self._edge_para = EdgeParameters(self, self.rendermanager.attract.point_scalars_name) logger.debug('Invoke Matrix Viewer...') self.rendermanager.invoke_matrix_viewer() def _trackvis_launch(self): """ Generates scene file and launch Trackvis on the selected nodes """ import tempfile logger.debug('Starting TrackVis ...') # extract selected subgraph selectionlist = self.get_selectiongraph_list() if len(selectionlist) == 0: # message from enthought.traits.ui.message import message message(message = 'No nodes selected for ROI creation!', title = 'Infomessage', buttons = [ 'OK' ], parent = None) tmpgraph = self.graph.subgraph(selectionlist) # extract trackfile temporarily if len(self.tracks) == 0: logger.info('No trackfile found to invoke Trackvis.') return else: # load the first trackfile trackfname = self.tracks[0].load_trackfile_to_file() # find the first valid segmentation volume in the self.volumes list for vol in self.volumes: if vol.segmentation: logger.debug('Found a segmentation volume file. Assume labels are corresponding.') volumefname = vol.load_volume_to_file() break # generate the scene file in the temporary folder tmpscenefile=tempfile.mkstemp(prefix='tmp', suffix='.scene') # generate trackfile generate_scene_file(scenefname=tmpscenefile[1], \ trackfname = trackfname, \ volumefname = volumefname, \ selectiongraph = tmpgraph) # execute trackvis in a thread pref = preference_manager.preferences action = ThreadedTrackvis(tvpath = pref.get('cviewer.plugins.ui.trackvispath'), \ fname = tmpscenefile[1], \ trkfname = trackfname,\ volfname = volumefname) action.start() def add_surface_container(self, surfacecontainer): """ Add a surface container to the loaded list Parameters ---------- surfacecontainer : `ISurfaceContainer` instance a surface container object """ surfacecontainer._networkref = self self.surfaces_loaded.append(surfacecontainer) def add_volume(self, volume): """ Adds a volume to the volumes list Parameters ---------- volume : `IVolume` instance a volume object """ self.volumes.append(volume) def add_trackfile(self, trackfile): """ Adds a trackfile to the tracks list Parameters ---------- trackfile : `ITrackfile` instance a trackfile of type ITrackfile """ self.tracks.append(trackfile) def unselect_all(self): """ Unselects every node in the current network """ if self.datasourcemanager is None: raise Exception('No DatasourceManager. You have to first activate the network and render it.') from numpy import array # get all the nodes graphnodes = self.datasourcemanager._srcobj.relabled_graph.nodes() # and unselect all nodes self.rendermanager._select_nodes(selection_node_array = array(graphnodes)) def select_all(self): """ Selects all nodes in the current network """ if self.datasourcemanager is None: raise Exception('No DatasourceManager. You have to first activate the network and render it.') from numpy import array # get all the nodes graphnodes = self.datasourcemanager._srcobj.relabled_graph.nodes() # and select all nodes self.rendermanager._select_nodes(selection_node_array = array(graphnodes), activate = True) def set_selectiongraph(self, sellist, activate = False): """ Sets the selected nodes in the network to active. Parameters ---------- sellist : array_like a list of nodeids conforming to the NetworkX node id activate : boolean set the selectionlist nodes to activated? """ from numpy import array, int16 graphnodes = self.graph.nodes(data=False) if self.rendermanager is None: raise Exception('No RenderManager. You have to first activate the network and render it.') if len(sellist) == 0: self.unselect_all() return from numpy import array, append tmparr = array([]) for node in sellist: # check if it is a valid graph node id if node in graphnodes: # get the node id as integer j = int(node.lstrip('n'))-1 # extend empty array with node id tmparr = append(tmparr, j) self.rendermanager._select_nodes(selection_node_array = array(tmparr, dtype = int16), activate = activate) def get_selectiongraph_list(self): """ Returns a list of the node ids that were selected in the rendered scene. """ if self.datasourcemanager is None: raise Exception('No DatasourceManager. You have to first activate the network and render it.') import numpy as np sel_list = [] if not self.active: return sel_list selnodesarray = self.datasourcemanager._srcobj.selected_nodes # array with indices where the nodes are selected (==1) idx = np.where(selnodesarray == 1)[0] for i in idx: sel_list.append('n' + str(i + 1)) return sel_list def set_weight_key(self, weight_key = None): """ Sets the weight key in the graph representation of the network. Parameters ---------- weight_key : Str Must be a possible existing edge key """ if not weight_key is None: for u,v,d in self.graph.edges(data=True): self.graph[u][v]['weight']=d[weight_key] return True else: return False def get_matrix(self, weight_key = None): """ Returns the connectivity matrix of the network with the nodes ordered according to their id in the GraphML file. Parameters ---------- weight_key : Str Possible key value of the edges Returns ------- matrix : `Numpy.array` instance The connectivity matrix """ nr_nodes = len(self.graph.nodes()) if not weight_key is None: #FIXME: sanity check if weight_key exists # thanks to Aric Hagberg for u,v,d in self.graph.edges(data=True): self.graph[u][v]['weight']=d[weight_key] nodes = [(lambda nmod:'n'+str(nmod))(node) for node in range(1,nr_nodes + 1)] from networkx import to_numpy_matrix return to_numpy_matrix(self.graph, nodelist = nodes) def toggle_surface(self): """ Toggle the surface for the selected network nodes """ if self.rendermanager is None: raise Exception('No RenderManager. You have to first activate the network and render it.') self.rendermanager._toggle_surface() def show_surface(self): """ Shows the surface for the selected network nodes """ if self.rendermanager is None: raise Exception('No RenderManager. You have to first activate the network and render it.') self.rendermanager._show_surface() def load_pickled_graphml(self, graph): """ Loads a pickled GraphML file Parameters ---------- graph : NetworkX Graph instance A graph instance """ # setting the graph self.graph = graph if self.graph.has_node('n0'): if self.graph.node['n0'].has_key('nodekeys'): # extracting the node keys from the first node self.nodekeys = self.graph.node['n0']['nodekeys'] # extracting the edge keys from the first edge (without explanation) if self.graph.node['n0'].has_key('edgekeys'): self.edgekeys = self.graph.node['n0']['edgekeys'] if self.graph.node['n0'].has_key('graphid'): self.networkid = self.graph.node['n0']['graphid'] # remove node self.graph.remove_node('n0') def _return_default_edgevalue(self, edgekeys, key): """ Looks up if there is a default value defined, otherwise return zero """ if edgekeys[key].has_key('default'): return float(edgekeys[key]['default']) else: return 0.0 def parse_network_graphml(self, path): """ Read network in GraphML format from a path. Parameters ---------- path : string path the the GraphML file Returns ------- graph : NetworkX `Graph` """ import networkx as nx from networkx.utils import _get_fh from lxml import etree # Return a file handle for given path. # Path can be a string or a file handle. # Attempt to uncompress/compress files ending in .gz and .bz2. fh=_get_fh(path,mode='r') tree = etree.parse(fh) # get the root node from parsed lxml root = tree.getroot() # Schema Validation # http://codespeak.net/lxml/validation.html#xmlschema # define the namespace prefixes nsprefix = "{%s}" % root.nsmap[None] nsxlink = "{%s}" % root.nsmap['xlink'] nodekeys = {} edgekeys = {} defaultDirected = [True] # Parse the KEYs for child in root.iterchildren(): if child.tag == (nsprefix+'key'): attribs = child.attrib ddkeys = {} for mchildren in child: if mchildren.tag == (nsprefix+'default'): ddkeys['default'] = mchildren.text elif mchildren.tag == (nsprefix+'desc'): ddkeys['desc'] = mchildren.text if child.attrib['for'] == 'node': # Parse all the node keys # Read in the description and the default (if existing) # dict of dicts for nodes: key1: the id; key2: rest: attr.name, attr.type, desc, default nodekeys[attribs['id']] = {'attr.name' : attribs['attr.name'], \ 'attr.type' : attribs['attr.type']} # add default/desc keys if existing nodekeys[attribs['id']] = ddkeys elif child.attrib['for'] == 'edge': # Parse all the edge keys # Read in the description and the default (if existing) # dict of dicts for edges: key1: the id; key2: rest: attr.name, attr.type, desc, default edgekeys[attribs['id']] = {'attr.name' : attribs['attr.name'], \ 'attr.type' : attribs['attr.type']} # add default/desc keys if existing edgekeys[attribs['id']] = ddkeys else: logger.error("The 'for' attribute of key-tag not known, must be either node or edge") elif child.tag == (nsprefix+'graph'): # start parsing the graph into networkx data structure # create graph depending on (either AttrGraph or AttrDiGraph) # directionality: undirected/directed # version of networkx: # contains self-loops # edges have dicts # data per graph/node/edge for attr, value in child.items(): if attr == 'edgedefault' and value == 'undirected': defaultDirected[0] = False elif attr == 'id': graphid = value if defaultDirected[0]: G = nx.DiGraph() else: G = nx.Graph() # add id, nodekeys and edkeys as traits self.networkid = graphid self.nodekeys = nodekeys self.edgekeys = edgekeys # iterate over all nodes and edges for children in child.iterchildren(): if children.tag == (nsprefix+'node'): # parse the node for attr, value in children.items(): if attr == 'id': # add the node with corresponding id G.add_node(value) # keep node id to store attributes nodeid = value elif attr == (nsxlink+'href'): # add xlink to node dictionary G.node[nodeid]['xlink'] = value else: # node attribute not known logger.warning('The following node attribute is not known and thus discarded:'+ attr + ':' + value) # parse node data, add to node dict for data in children.iterchildren(): # read the keylabel, i.e. the data attribute name keylabel = data.attrib['key'] # is the keylabel in the list of allowed keys if nodekeys.has_key(keylabel): if not data.text == '': # add data to the node's dict G.node[nodeid][keylabel] = data.text else: # no data available, check if default value exists if nodekeys[keylabel].has_key('default'): # add default data to the node's dict G.node[nodeid][keylabel] = nodekeys[keylabel]['default'] logger.debug('Added default value '+ keylabel + ':' + nodekeys[keylabel]['default']) else: logger.warning('Nor data nor default value defined for ' + keylabel) # TODO: Work with exceptions! else: logger.warning("Data entry with key " + keylabel + " not defined.") elif children.tag == (nsprefix+'edge'): # parse the edge # parse its attributes for attr, value in children.items(): if attr == 'id': # no usage of edge id # add the edge with corresponding id src = children.attrib['source'] tar = children.attrib['target'] G.add_edge(src, tar) # keep dest and tar id to store attributes srcid = src tarid = tar elif attr == (nsxlink+'href'): # add xlink to edge dictionary G.edge[srcid][tarid]['xlink'] = value # parse data, and add to the edge dict for data in children.iterchildren(): # read the keylabel, i.e. the data attribute name keylabel = data.attrib['key'] # is the keylabel in the list of allowed keys if self.edgekeys.has_key(keylabel): if not data.text == '': # add data to the edge's dict, assume float!! G.edge[srcid][tarid][keylabel] = float(data.text) else: # no data available, check if default value exists G.edge[srcid][tarid][keylabel] = self._return_default_edgevalue(self.edgekeys, keylabel) data_keys = G.edge[srcid][tarid].keys() # check if we missed some edge keys that are available in the header for k, v in self.edgekeys.items(): if not k in data_keys: G.edge[srcid][tarid][k] = self._return_default_edgevalue(self.edgekeys, k) # return the generated network graph return G
def remove_node(self, n): Graph.remove_node(self, n) self.fh.write(f"Remove node: {n}\n")