def find_graph_given_data(graph: nx.Graph, data: pd.DataFrame, max_parents=2): ordering = list(graph.nodes) random.shuffle(ordering) best_score = None score, counts = bayesian_score(graph, data) for i_index, i in enumerate(ordering[1:-1]): if i_index % 10 == 0: print("intermediate graph:", str(graph.edges)) print("score", str(best_score)) print("finding parents for node", str(i_index), str(i)) best_score = score best_parent = None best_counts = None found_all_parents = False num_parents_found = 0 while not found_all_parents and (max_parents is None or num_parents_found < max_parents): print("finding parent #", str(num_parents_found + 1)) for j in ordering[0:i_index]: print("testing node", str(j), "as parent") if (j, i) not in graph.edges: graph.add_edge(j, i) # print("add edge (" + str(j) + ", " + str(i) + ")") temp_score, new_counts = bayesian_score_from_prev_graph(graph, i, data, score, counts) if temp_score > best_score: best_score, best_parent, best_counts = temp_score, j, new_counts graph.remove_edge(j, i) if best_score > score: score = best_score num_parents_found += 1 graph.add_edge(best_parent, i) counts = best_counts else: found_all_parents = True return graph, best_score
def degrade(graph: nx.Graph, k=0.95): to_delete = [] for edge in graph.edges: delete = np.random.random() > k if delete: to_delete.append(edge) for edge in to_delete: graph.remove_edge(edge[0], edge[1])
def generate_small_world_graph(self): max_edges = self.NODE_COUNT * (self.NODE_COUNT - 1) / 2 if self.EDGE_COUNT > max_edges: return complete_graph(self.NODE_COUNT) graph = Graph() graph.add_nodes_from(range(self.NODE_COUNT)) edges = performer.edge_indices.flatten() probabilities = performer.probabilities.flatten() for trial in range(len(edges) - 9): edge_index = numpy.random.choice(edges, p=probabilities) source, destination = self.edge_nodes(edge_index) graph.add_edge(source, destination, length=self.link_length(source, destination), weight=self.edge_weight(source, destination)) probabilities[edge_index] = 0 probabilities /= sum(probabilities) if max(graph.degree().values()) > self.DEGREE_MAX: graph.remove_edge(source, destination) if graph.number_of_edges() > self.EDGE_COUNT: victim = random.choice(graph.edges()) graph.remove_edge(victim[0], victim[1]) if self.constraints_satisfied(graph): print 'performer.generate_small_world_graph:', print self.BENCHMARK, self.NODE_COUNT, self.EDGE_COUNT, trial self.process_graph(graph) return graph
def __connect_spokes(graph: nx.Graph, men_spokes: List[int], women_spokes: List[int], is_invalid_graph: Callable, condom_weight: Optional[float] = None): men_spokes_copy = [i for i in men_spokes] women_spokes_copy = [i for i in women_spokes] random.shuffle(men_spokes_copy) while len(men_spokes_copy) > 0 and len(len(women_spokes_copy)) > 0: man_id = men_spokes_copy.pop(0) women = [i for i in women_spokes_copy] random.shuffle(women) while len(women) > 0: success = False woman_id = women.pop(0) if graph.has_edge(man_id, woman_id): continue if condom_weight is None: graph.add_edge(man_id, woman_id) else: graph.add_edge(man_id, woman_id, weight=condom_weight) if is_invalid_graph(graph): graph.remove_edge(man_id, woman_id) else: success = True break if success: women_spokes_copy.remove(woman_id)
def generate_small_world_graph(self): max_edges = self.NODE_COUNT*(self.NODE_COUNT-1)/2 if self.EDGE_COUNT > max_edges: return complete_graph(self.NODE_COUNT) graph = Graph() graph.add_nodes_from(range(self.NODE_COUNT)) edges = performer.edge_indices.flatten() probabilities = performer.probabilities.flatten() for trial in range(len(edges)-9): edge_index = numpy.random.choice(edges, p=probabilities) source, destination = self.edge_nodes(edge_index) graph.add_edge(source, destination, length = self.link_length(source, destination), weight = self.edge_weight(source, destination)) probabilities[edge_index] = 0 probabilities /= sum(probabilities) if max(graph.degree().values()) > self.DEGREE_MAX: graph.remove_edge(source, destination) if graph.number_of_edges() > self.EDGE_COUNT: victim = random.choice(graph.edges()) graph.remove_edge(victim[0], victim[1]) if self.constraints_satisfied(graph): print 'performer.generate_small_world_graph:', print self.BENCHMARK, self.NODE_COUNT, self.EDGE_COUNT, trial self.process_graph(graph) return graph
def _unstable_behavior(self, G: nx.Graph, agent: int, neighbors: Sequence[int]): # add a neighbor if lonely if len(neighbors) < self._lower_bound: if len(neighbors) == 0: connect_agents(G, agent, choice(tuple(G.nodes))) else: neighbor_to_strength = { (neighbor, calc_prop_common_neighbors(G, agent, neighbor)) for neighbor in neighbors } closest_neighbor = max(neighbor_to_strength, key=lambda x: x[1])[0] # TODO: neighbor_choices will likely include agents already adjacent to agent. # These should be filtered out. neighbor_choices = tuple(set(G[closest_neighbor]) - {agent}) to_add = choice(neighbor_choices if len(neighbor_choices) > 0 else tuple(G.nodes)) connect_agents(G, agent, to_add) # remove a neighbor if overwhelmed elif len(neighbors) > self._upper_bound: neighbor_to_strength = { (neighbor, calc_prop_common_neighbors(G, agent, neighbor)) for neighbor in neighbors } farthest_neighbor = min(neighbor_to_strength, key=lambda x: x[1])[0] G.remove_edge(agent, farthest_neighbor)
def remove_edges(graph: nx.Graph, edge_weights: list, percentile_cutoff: int, remove_isolated_nodes: bool = 1) \ -> nx.Graph: """ remove_edges removes edges from graph that have a weight below the weight cutoff :param graph: word embedding graph :param edge_weights: list or edge weights :param percentile_cutoff: cutoff weight percentile :param remove_isolated_nodes: if 1, remove islated nodes (default: 1) :return: graph without lower weighted edges """ # remove edges that do not have a high enough similarity score min_cutoff_value = np.percentile(edge_weights, percentile_cutoff) # min(heapq.nlargest(percentile_cutoff, edge_weights)) graph_edge_weights = nx.get_edge_attributes(graph, "weight") edges_to_kill = [] for edge in graph.edges(): edge_weight = graph_edge_weights[edge] if edge_weight < min_cutoff_value: edges_to_kill.append(edge) for edge in edges_to_kill: graph.remove_edge(edge[0], edge[1]) if remove_isolated_nodes: graph.remove_nodes_from(list(nx.isolates(graph))) return graph
def quad_switch(graph: nx.Graph, u1, v1, u2, v2) -> bool: if not graph.has_edge(u1, v1) or not graph.has_edge(u2, v2): return False if graph.has_edge(u1, u2) or graph.has_edge(v1, v2): return False num_connected = nx.number_connected_components(graph) graph.remove_edge(u1, v1) graph.remove_edge(u2, v2) graph.add_edge(u1, u2) graph.add_edge(v1, v2) if nx.number_connected_components(graph) != num_connected: graph.remove_edge(u1, u2) graph.remove_edge(v1, v2) graph.add_edge(u1, v1) graph.add_edge(u2, v2) return False return True
def add_ionic_interactions(G: nx.Graph, rgroup_df: pd.DataFrame = None): """ Find all ionic interactions. Criteria: ARG, LYS, HIS, ASP, and GLU residues are within 6A. """ if rgroup_df is None: rgroup_df = G.graph["rgroup_df"] ionic_df = filter_dataframe(rgroup_df, "residue_name", IONIC_RESIS, True) distmat = compute_distmat(ionic_df) interacting_atoms = get_interacting_atoms(6, distmat) add_interacting_resis(G, interacting_atoms, ionic_df, ["ionic"]) # Check that the interacting residues are of opposite charges for r1, r2 in get_edges_by_bond_type(G, "ionic"): condition1 = (G.nodes[r1]["residue_name"] in POS_AA and G.nodes[r2]["residue_name"] in NEG_AA) condition2 = (G.nodes[r2]["residue_name"] in POS_AA and G.nodes[r1]["residue_name"] in NEG_AA) is_ionic = condition1 or condition2 if not is_ionic: G.edges[r1, r2]["kind"].remove("ionic") if len(G.edges[r1, r2]["kind"]) == 0: G.remove_edge(r1, r2)
def remove_edges(G: nx.Graph, edges): e_set = set(G.edges()) for e in edges: if e in e_set: G.remove_edge(*e) elif (e[1], e[0]) in e_set: G.remove_edge(e[1], e[0])
def hide_edges(graph: nx.Graph, percentage: int) -> nx.Graph: graph = copy.deepcopy(graph) edge_usages = np.zeros(graph.number_of_nodes()) edges = [] for u, v, w in graph.edges(data='weight', default=1): edge_usages[u] += 1 edge_usages[v] += 1 edges.append((u, v, w)) edges = np.array(edges) to_hide = (percentage / 100.0) * graph.number_of_edges() while to_hide > 0: e = np.random.randint(len(edges)) u, v, w = edges[e] u, v = int(u), int(v) if not graph.has_edge(u, v): continue if edge_usages[u] > 0 and edge_usages[v] > 0: edge_usages[u] -= 1 edge_usages[v] -= 1 graph.remove_edge(u, v) to_hide -= 1 return graph
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 test_consistency_vrp(): """Tests consistency of input graph.""" G = Graph() with pytest.raises(TypeError): VehicleRoutingProblem(G) G = DiGraph() G.add_edge("Source", 1, cost=0) with pytest.raises(KeyError) and pytest.raises(NetworkXError): VehicleRoutingProblem(G) G.add_edge(1, "Sink") with pytest.raises(KeyError): VehicleRoutingProblem(G) G.edges[1, "Sink"]["cost"] = 1 G.add_edge("Sink", 2, cost=3) with pytest.raises(NetworkXError): VehicleRoutingProblem(G) with pytest.raises(NetworkXError): VehicleRoutingProblem(G) G.remove_edge("Sink", 2) with pytest.raises(TypeError): VehicleRoutingProblem(G, num_stops=3.5) with pytest.raises(TypeError): VehicleRoutingProblem(G, load_capacity=-10) with pytest.raises(TypeError): VehicleRoutingProblem(G, duration=0) G.remove_edge("Source", 1)
def remove_edges_randomly(graph: nx.Graph, *, frac=None, number=None, keep_connected=False): """ Removes edges randomly from the given graph. You must either give `frac` or `number` to specify how many edges should be removed. The parameter `keep_connected` can be used to ensure that all nodes remain connected. Some embedding algorithms (DAOR) lead to subsequent problems in later tasks otherwise. A set of all edges that were removed is returned. The graph is altered in place. """ number = number_random_edges(graph, frac=frac, number=number) connected = nx.is_weakly_connected if graph.is_directed() else nx.is_connected if keep_connected and not connected(graph): raise RuntimeError("The graph is already not connected before removing any edges.") removed_edges = set() infeasible_edges = set() while len(removed_edges) < number: to_remove = sample(graph.edges - infeasible_edges, number - len(removed_edges)) for edge in to_remove: edge_data = graph[edge[0]][edge[1]] graph.remove_edge(*edge) if keep_connected and not connected(graph): # The removed edge made the graph disconnected, add the edge # again and re-sample a new edge as replacement later. graph.add_edge(*edge, **edge_data) infeasible_edges.add(edge) else: removed_edges.add(edge) return removed_edges
def add_break(graph: Graph, segment_ids: [(str, str)]) -> str: """ Adds a node that breaks proper segment. Proper segment is a segment with the smallest angle with positive x-axis. `segment_ids` - list of tuples. Each tuple consists of two vertexes ids that represents a segment. This means that there has to be an edge between these vertexes. Returns id of newly created vertex. """ (v1, v2) = get_segment_with_smallest_angle(graph, segment_ids) layer = graph.nodes[v1]['layer'] v1_pos = graph.nodes[v1]['position'] v2_pos = graph.nodes[v2]['position'] v_x = (v1_pos[0] + v2_pos[0]) / 2 v_y = (v1_pos[1] + v2_pos[1]) / 2 v_pos = (v_x, v_y) v = gen_name() graph.add_node(v, layer=layer, position=v_pos, label='E') graph.remove_edge(v1, v2) graph.add_edge(v1, v) graph.add_edge(v2, v) return v
def mutateGraphWithEdge(G: nx.Graph, op: OpType, edge: ("src", "dst")) -> None: if op == "add": G.add_edge(edge[0], edge[1]) elif op == "remove": try: G.remove_edge(edge[0], edge[1]) except: pass
def maximal_independent_sets(mat): g = Graph(mat) for u in g.nodes(): if g.has_edge(u, u): g.remove_edge(u, u) cg = complement(g) isets = list(find_cliques(cg)) return isets
def two_type_step(G: nx.Graph) -> None: normal_lb = 2 # lower bound normal_ub = 10 # upper bound bridge_happy_number = 2 # how a normal agent behaves for agent in normal_agents: neighbors = tuple(nx.neighbors(G, agent)) # connect to a new neighbor if len(neighbors) < normal_lb: to_add = choice(tuple(G.nodes)) connect_agents(G, agent, to_add) elif len(neighbors) < normal_ub: neighbor_to_strength = { (neighbor, calc_prop_common_neighbors(G, agent, neighbor)) for neighbor in neighbors } closest_neighbor = max(neighbor_to_strength, key=lambda x: x[1])[0] new_neighbor_choices = set(nx.neighbors( G, closest_neighbor)) - {agent} if len(new_neighbor_choices) > 0: to_add = choice(tuple(new_neighbor_choices)) else: to_add = choice(tuple(G.nodes)) connect_agents(G, agent, to_add) # disconnect from a neighbor elif len(neighbors) > normal_ub: neighbor_to_strength = { (neighbor, calc_prop_common_neighbors(G, agent, neighbor)) for neighbor in neighbors } to_remove = min(neighbor_to_strength, key=lambda x: x[1])[0] G.remove_edge(agent, to_remove) # how a bridge agent behaves for agent in bridge_agents: neighbors = tuple(nx.neighbors(G, agent)) # search for more connections if len(neighbors) < bridge_happy_number: choices = [ a for a in G.nodes if (a not in bridge_agents) and (a not in neighbors) ] to_add = choice(choices) connect_agents(G, agent, to_add) # if the agent has enough connections, look for ones to prune else: # connections are invalid if they are to an agent that shares a common neighbor invalid_connections = [ a for a in neighbors if calc_prop_common_neighbors(G, agent, a) > 0 ] if len(invalid_connections) == 0: invalid_connections = neighbors to_remove = choice(invalid_connections) G.remove_edge(agent, to_remove)
def remove_loops(g: nx.Graph) -> nx.Graph: remove_edges = [] for edge in g.edges: u, v = edge if u == v: remove_edges.append(edge) for edge in remove_edges: g.remove_edge(*edge) return g
def update_environment_edge(rules: Rules, graph: Graph, final_actions: Actions) -> None: for edge in final_actions.values(): u, v = edge if not graph.has_edge(*edge): graph.add_edge(u, v) elif graph.has_edge(*edge): graph.remove_edge(u, v) return None
def _rm_dummy_edge(processor: Graph, edge: typing.Collection[object]) -> None: """Remove an edge from the given processor. `processor` is the processor to remove the edge from. `edge` is the edge to remove. """ warning("Units %s and %s have no capabilities in common, removing " "connecting edge...", *edge) processor.remove_edge(*edge)
def remove_intra_edges(graph: nx.Graph, group: Union[GraphSignalData, Mapping[str, GraphSignalData]]): if isinstance(group, collections.abc.Mapping): for actual_group in group.values(): remove_intra_edges(graph, actual_group) else: for v in group: for u in group: if graph.has_edge(v, u) or graph.has_edge(u, v): graph.remove_edge(v, u)
def _mov_out_link(graph: Graph, link: Tuple[object, object], new_node: object) -> None: """Move an outgoing link from an old node to a new one. `graph` is the graph containing the nodes. `link` is the outgoing link to move. `new_node` is the node to move the outgoing link to. """ graph.add_edge(new_node, link[1]) graph.remove_edge(*link)
def reduceMotiveGraph(g: nx.Graph, mode: int): if mode == 0: treshold = 1.9 elif mode == 1: treshold = 1.7 else: treshold = 1.5 for (u, v, d) in g.edges(data=True): if d['weight'] < treshold: g.remove_edge(u,v) 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 remove_edges(graph: nx.Graph, max_deg: int) -> nx.Graph: v_num = graph.number_of_nodes() to_remove = [x for x in range(v_num) if graph.degree[x] > max_deg] for src in to_remove: # iterate over vertices with degree > max_deg to_remove = np.maximum(0, graph.degree[src] - max_deg) neighbors = [x for x in graph.neighbors(src)] for dest in neighbors[:to_remove + 1]: graph.remove_edge(src, dest) return graph
def _drop_edges_not_of_type(graph: nx.Graph, rel: str) -> None: """ Take a graph and remove all edges that aren't of type/Class rel :param graph: :param rel: :return: """ for e in graph.edges(data=True): # e is a tuple (source, target, property dict) if e[2].get(NetworkXMixin.NETWORKX_LABEL, None) != rel: # delete this edge graph.remove_edge(e[0], e[1])
def recalculate_edges(self, nodes=[]): """ Recalculate edges for given nodes or for all self.nodes(). Edge between nodes n1 and n2 are added if both are ChannelType.in_comm_range of each other""" if (not nodes): nodes = self.nodes() for n1 in nodes: for n2 in self.nodes(): if (n1 != n2): if (self.channelType.in_comm_range(self, n1, n2)): Graph.add_edge(self, n1, n2) elif (Graph.has_edge(self, n1, n2)): Graph.remove_edge(self, n1, n2)
def recalculate_edges(self, nodes=[]): """ Recalculate edges for given nodes or for all self.nodes(). Edge between nodes n1 and n2 are added if both are ChannelType.in_comm_range of each other""" if(not nodes): nodes = self.nodes() for n1 in nodes: for n2 in self.nodes(): if (n1 != n2): if (self.channelType.in_comm_range(self, n1, n2)): Graph.add_edge(self, n1, n2) elif (Graph.has_edge(self, n1, n2)): Graph.remove_edge(self, n1, n2)
def remove_suggested_edges(graph: nx.Graph) -> None: """Drops non-canonical edges from the graph.""" logger.info("Dropping non-canonical edges") logger.info( f"Original graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges" ) drop = set() for edge in graph.edges: if graph.edges[edge].get("kind"): drop.add(edge) for edge in drop: graph.remove_edge(*edge) logger.info( f"Updated graph has {graph.number_of_nodes()} nodes and {graph.number_of_edges()} edges" )
def filter_null_edges(G: nx.Graph, attr_name='throughput', threshold=0) -> nx.Graph: """ Removes edges with attribute value below given threshold (default 0) :param G: graph :param attr_name: attribute name :param threshold: :return: Graph with filtered edges """ weights = nx.get_edge_attributes(G, attr_name) for e in G.edges(): if weights[e] <= threshold: G.remove_edge(*e) return G
def remove_insignificant_edges(graph: nx.Graph, threshold: float) -> nx.Graph: """Removes all edges from a given graph with a score below the threshold Arguments: graph: -- The graph to work on threshold: -- The threshold below which edges are removed Returns: A reference to the same graph that has been passed """ for u, v in graph.edges(): attrs = graph.get_edge_data(u, v) if attrs['combined_score'] < threshold: graph.remove_edge(u, v) return graph
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()))
def remove_edge(self, u, v): Graph.remove_edge(self,u,v) self.fh.write("Remove edge: %s-%s\n"%(u,v))