コード例 #1
0
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
コード例 #2
0
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])
コード例 #3
0
 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
コード例 #4
0
ファイル: experiment.py プロジェクト: yuguanx/CS224W_project
 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)
コード例 #5
0
 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
コード例 #6
0
 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)
コード例 #7
0
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
コード例 #8
0
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
コード例 #9
0
ファイル: distance.py プロジェクト: BatoolMM/graphein
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)
コード例 #10
0
ファイル: generators.py プロジェクト: asrvsn/gds
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])
コード例 #11
0
ファイル: edge_hiding.py プロジェクト: vvancak/gem
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
コード例 #12
0
    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
コード例 #13
0
ファイル: test_consistency.py プロジェクト: pchtsp/vrpy
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)
コード例 #14
0
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
コード例 #15
0
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
コード例 #16
0
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
コード例 #17
0
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
コード例 #18
0
    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)
コード例 #19
0
ファイル: transform.py プロジェクト: glaserL/vizlo
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
コード例 #20
0
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
コード例 #21
0
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)
コード例 #22
0
ファイル: utils.py プロジェクト: maniospas/pygrank
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)
コード例 #23
0
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)
コード例 #24
0
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
コード例 #25
0
ファイル: trees.py プロジェクト: TypeRHonda/Clone1
 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)
コード例 #26
0
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
コード例 #27
0
 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])
コード例 #28
0
ファイル: network.py プロジェクト: fusion-research/pymote2.0
 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)
コード例 #29
0
ファイル: network.py プロジェクト: engalex/pymote
 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)
コード例 #30
0
ファイル: graph_lib.py プロジェクト: skearnes/scripture-graph
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"
    )
コード例 #31
0
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
コード例 #32
0
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
コード例 #33
0
ファイル: docgraph.py プロジェクト: jworr/ml_tools
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()))
コード例 #34
-1
ファイル: printgraph.py プロジェクト: Jverma/networkx
 def remove_edge(self, u, v): 
     Graph.remove_edge(self,u,v)
     self.fh.write("Remove edge: %s-%s\n"%(u,v))