Python networkx.minimum_spanning_tree() Examples

The following are 30 code examples of networkx.minimum_spanning_tree(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module networkx , or try the search function .
Example #1
Source File: inference.py    From science_rcn with MIT License 10 votes vote down vote up
def get_tree_schedule(frcs, graph):
    """
    Find the most constrained tree in the graph and returns which messages to compute
    it.  This is the minimum spanning tree of the perturb_radius edge attribute.

    See forward_pass for parameters.

    Returns
    -------
    tree_schedules : numpy.ndarray of numpy.int
        Describes how to compute the max marginal for the most constrained tree.
        Nx3 2D array of (source pool_idx, target pool_idx, perturb radius), where
        each row represents a single outgoing factor message computation.
    """
    min_tree = nx.minimum_spanning_tree(graph, 'perturb_radius')
    return np.array([(target, source, graph.edge[source][target]['perturb_radius'])
                     for source, target in nx.dfs_edges(min_tree)])[::-1] 
Example #2
Source File: graph_utils.py    From metal with Apache License 2.0 6 votes vote down vote up
def get_clique_tree(nodes, edges):
    """Given a set of int nodes i and edges (i,j), returns an nx.Graph object G
    which is a clique tree, where:
        - G.node[i]['members'] contains the set of original nodes in the ith
            maximal clique
        - G[i][j]['members'] contains the set of original nodes in the seperator
            set between maximal cliques i and j

    Note: This method is currently only implemented for chordal graphs; TODO:
    add a step to triangulate non-chordal graphs.
    """
    # Form the original graph G1
    G1 = nx.Graph()
    G1.add_nodes_from(nodes)
    G1.add_edges_from(edges)

    # Check if graph is chordal
    # TODO: Add step to triangulate graph if not
    if not nx.is_chordal(G1):
        raise NotImplementedError("Graph triangulation not implemented.")

    # Create maximal clique graph G2
    # Each node is a maximal clique C_i
    # Let w = |C_i \cap C_j|; C_i, C_j have an edge with weight w if w > 0
    G2 = nx.Graph()
    for i, c in enumerate(nx.chordal_graph_cliques(G1)):
        G2.add_node(i, members=c)
    for i in G2.nodes:
        for j in G2.nodes:
            S = G2.node[i]["members"].intersection(G2.node[j]["members"])
            w = len(S)
            if w > 0:
                G2.add_edge(i, j, weight=w, members=S)

    # Return a minimum spanning tree of G2
    return nx.minimum_spanning_tree(G2) 
Example #3
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_unknown_algorithm():
    nx.minimum_spanning_tree(nx.Graph(), algorithm='random') 
Example #4
Source File: mst.py    From PyRate with Apache License 2.0 5 votes vote down vote up
def _minimum_spanning_edges_from_mst(edges):
    """
    Convenience function to determine MST edges
    """
    g_nx = _build_graph_networkx(edges)
    T = nx.minimum_spanning_tree(g_nx)  # step ifglist_mst in make_mstmat.m
    edges = T.edges()
    return edges, g_nx 
Example #5
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_minimum_tree(self):
        T = nx.minimum_spanning_tree(self.G, algorithm=self.algo)
        actual = sorted(T.edges(data=True))
        assert_edges_equal(actual, self.minimum_spanning_edgelist) 
Example #6
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_disconnected(self):
        G = nx.Graph([(0, 1, dict(weight=1)), (2, 3, dict(weight=2))])
        T = nx.minimum_spanning_tree(G, algorithm=self.algo)
        assert_nodes_equal(list(T), list(range(4)))
        assert_edges_equal(list(T.edges()), [(0, 1), (2, 3)]) 
Example #7
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_empty_graph(self):
        G = nx.empty_graph(3)
        T = nx.minimum_spanning_tree(G, algorithm=self.algo)
        assert_nodes_equal(sorted(T), list(range(3)))
        assert_equal(T.number_of_edges(), 0) 
Example #8
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_weight_attribute(self):
        G = nx.Graph()
        G.add_edge(0, 1, weight=1, distance=7)
        G.add_edge(0, 2, weight=30, distance=1)
        G.add_edge(1, 2, weight=1, distance=1)
        G.add_node(3)
        T = nx.minimum_spanning_tree(G, algorithm=self.algo, weight='distance')
        assert_nodes_equal(sorted(T), list(range(4)))
        assert_edges_equal(sorted(T.edges()), [(0, 2), (1, 2)])
        T = nx.maximum_spanning_tree(G, algorithm=self.algo, weight='distance')
        assert_nodes_equal(sorted(T), list(range(4)))
        assert_edges_equal(sorted(T.edges()), [(0, 1), (0, 2)]) 
Example #9
Source File: test_mst.py    From Carnets with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def test_multigraph_keys_tree(self):
        G = nx.MultiGraph()
        G.add_edge(0, 1, key='a', weight=2)
        G.add_edge(0, 1, key='b', weight=1)
        T = nx.minimum_spanning_tree(G)
        assert_edges_equal([(0, 1, 1)], list(T.edges(data='weight'))) 
Example #10
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_unknown_algorithm():
    nx.minimum_spanning_tree(nx.Graph(), algorithm='random') 
Example #11
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_minimum_tree(self):
        T = nx.minimum_spanning_tree(self.G, algorithm=self.algo)
        actual = sorted(T.edges(data=True))
        assert_edges_equal(actual, self.minimum_spanning_edgelist) 
Example #12
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_disconnected(self):
        G = nx.Graph([(0, 1, dict(weight=1)), (2, 3, dict(weight=2))])
        T = nx.minimum_spanning_tree(G, algorithm=self.algo)
        assert_nodes_equal(list(T), list(range(4)))
        assert_edges_equal(list(T.edges()), [(0, 1), (2, 3)]) 
Example #13
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_empty_graph(self):
        G = nx.empty_graph(3)
        T = nx.minimum_spanning_tree(G, algorithm=self.algo)
        assert_nodes_equal(sorted(T), list(range(3)))
        assert_equal(T.number_of_edges(), 0) 
Example #14
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_weight_attribute(self):
        G = nx.Graph()
        G.add_edge(0, 1, weight=1, distance=7)
        G.add_edge(0, 2, weight=30, distance=1)
        G.add_edge(1, 2, weight=1, distance=1)
        G.add_node(3)
        T = nx.minimum_spanning_tree(G, algorithm=self.algo, weight='distance')
        assert_nodes_equal(sorted(T), list(range(4)))
        assert_edges_equal(sorted(T.edges()), [(0, 2), (1, 2)])
        T = nx.maximum_spanning_tree(G, algorithm=self.algo, weight='distance')
        assert_nodes_equal(sorted(T), list(range(4)))
        assert_edges_equal(sorted(T.edges()), [(0, 1), (0, 2)]) 
Example #15
Source File: test_mst.py    From aws-kube-codesuite with Apache License 2.0 5 votes vote down vote up
def test_multigraph_keys_tree(self):
        G = nx.MultiGraph()
        G.add_edge(0, 1, key='a', weight=2)
        G.add_edge(0, 1, key='b', weight=1)
        T = nx.minimum_spanning_tree(G)
        assert_edges_equal([(0, 1, 1)], list(T.edges(data='weight'))) 
Example #16
Source File: graphs.py    From PyCV-time with MIT License 5 votes vote down vote up
def buildGraph(simList, plot=False):
	g = distanceGraph(simList)
	trim(g, 0.15)

	#mst = nx.minimum_spanning_tree(g.to_undirected())
	#el = [(i, o, w) for (i, o, w) in g.edges_iter(data=True)  
	#                    if (i, o) in mst.edges() 
	#        			or (o, i) in mst.edges()]
	#g = nx.DiGraph()
	#g.add_edges_from(el)
	if plot:
		nx.draw_networkx(g, with_labels = True)
		plt.show()
	return json.dumps(json_graph.node_link_data(g)) 
Example #17
Source File: mst.py    From PyRate with Apache License 2.0 5 votes vote down vote up
def mst_from_ifgs(ifgs):
    """
    Returns a Minimum Spanning Tree (MST) network from the given interferograms
    using Kruskal's algorithm. The MST is calculated using a weighting based
    on the number of NaN cells in the phase band.

    :param list ifgs: List of interferogram objects (Ifg class)

    :return: edges: The number of network connections
    :rtype: int
    :return: is_tree: A boolean that is True if network is a tree
    :rtype: bool
    :return: ntrees: The number of disconnected trees
    :rtype: int
    :return: mst_ifgs: Minimum Spanning Tree network of interferograms
    :rtype: list
    """

    edges_with_weights_for_networkx = [(i.master, i.slave, i.nan_fraction)
                                       for i in ifgs]
    g_nx = _build_graph_networkx(edges_with_weights_for_networkx)
    mst = nx.minimum_spanning_tree(g_nx)
    # mst_edges, is tree?, number of trees
    edges = mst.edges()
    ifg_sub = [ifg_date_index_lookup(ifgs, d) for d in edges]
    mst_ifgs = [i for k, i in enumerate(ifgs) if k in ifg_sub]
    return mst.edges(), nx.is_tree(mst), \
        nx.number_connected_components(mst), mst_ifgs 
Example #18
Source File: robustPipelineSizing.py    From FINE with MIT License 5 votes vote down vote up
def createSteinerTree(graph, distances, inner_nodes):
    """
    Computes a steiner tree with minimal sum of pipeline lengths;
    updates distances such that only arcs of the spanning tree are contained with corresponding length

    :param graph: an undirected networkx graph: Its edges have the attribute length which is the pipeline length in [m]
    :type graph: networkx graph object

    :param distances: pipeline distances in the length unit specified in the esM object
    :type distances: pandas series

    :return spanning tree with sum of lengths of pipelines is minimal
    :rtype: graph object of networkx
    """
    from networkx.algorithms import approximation
    
    # type and value check
    isNetworkxGraph(graph)
    isPandasSeriesPositiveNumber(distances)

    # compute spanning tree with minimal sum of pipeline lengths
    S = approximation.steiner_tree(graph, terminal_nodes=inner_nodes, weight='length')
    # TODO check why function fails when MST function is not called here
    S = nx.minimum_spanning_tree(S, weight='length')
    # delete edges that are in graph but not in the tree from the distance matrix
    edgesToDelete = []
    for edge in distances.index:
        # check if edge or its reversed edge are contained in the tree
        # you have to check both directions because we have an undirected graph
        if edge not in S.edges and (edge[1], edge[0]) not in S.edges:
            edgesToDelete.append(edge)
    distances = distances.drop(edgesToDelete)

    return S, distances 
Example #19
Source File: test_mst.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def test_mst_attributes(self):
        G=nx.Graph()
        G.add_edge(1,2,weight=1,color='red',distance=7)
        G.add_edge(2,3,weight=1,color='green',distance=2)
        G.add_edge(1,3,weight=10,color='blue',distance=1)
        G.add_node(13,color='purple')
        G.graph['foo']='bar'
        T=nx.minimum_spanning_tree(G)
        assert_equal(T.graph,G.graph)
        assert_equal(T.node[13],G.node[13])
        assert_equal(T.edge[1][2],G.edge[1][2]) 
Example #20
Source File: nx_edge_augmentation.py    From ibeis with Apache License 2.0 5 votes vote down vote up
def weighted_one_edge_augmentation(G, avail, weight=None, partial=False):
    """Finds the minimum weight set of edges to connect G if one exists.

    This is a variant of the weighted MST problem.

    Example
    -------
    >>> G = nx.Graph([(1, 2), (2, 3), (4, 5)])
    >>> G.add_nodes_from([6, 7, 8])
    >>> # any edge not in avail has an implicit weight of infinity
    >>> avail = [(1, 3), (1, 5), (4, 7), (4, 8), (6, 1), (8, 1), (8, 2)]
    >>> sorted(weighted_one_edge_augmentation(G, avail))
    [(1, 5), (4, 7), (6, 1), (8, 1)]
    >>> # find another solution by giving large weights to edges in the
    >>> # previous solution (note some of the old edges must be used)
    >>> avail = [(1, 3), (1, 5, 99), (4, 7, 9), (6, 1, 99), (8, 1, 99), (8, 2)]
    >>> sorted(weighted_one_edge_augmentation(G, avail))
    [(1, 5), (4, 7), (6, 1), (8, 2)]
    """
    avail_uv, avail_w = _unpack_available_edges(avail, weight=weight, G=G)
    # Collapse CCs in the original graph into nodes in a metagraph
    # Then find an MST of the metagraph instead of the original graph
    C = collapse(G, nx.connected_components(G))
    mapping = C.graph['mapping']
    # Assign each available edge to an edge in the metagraph
    candidate_mapping = _lightest_meta_edges(mapping, avail_uv, avail_w)
    # nx.set_edge_attributes(C, name='weight', values=0)
    C.add_edges_from(
        (mu, mv, {'weight': w, 'generator': uv})
        for (mu, mv), uv, w in candidate_mapping
    )
    # Find MST of the meta graph
    meta_mst = nx.minimum_spanning_tree(C)
    if not partial and not nx.is_connected(meta_mst):
        raise nx.NetworkXUnfeasible(
            'Not possible to connect G with available edges')
    # Yield the edge that generated the meta-edge
    for mu, mv, d in meta_mst.edges(data=True):
        if 'generator' in d:
            edge = d['generator']
            yield edge 
Example #21
Source File: viz_graph.py    From ibeis with Apache License 2.0 5 votes vote down vote up
def ensure_names_are_connected(graph, aids_list):
    aug_graph = graph.copy().to_undirected()
    orig_edges = aug_graph.edges()
    unflat_edges = [list(itertools.product(aids, aids)) for aids in aids_list]
    aid_pairs = [tup for tup in ut.iflatten(unflat_edges) if tup[0] != tup[1]]
    new_edges = ut.setdiff_ordered(aid_pairs, aug_graph.edges())

    preweighted_edges = nx.get_edge_attributes(aug_graph, 'weight')
    if preweighted_edges:
        orig_edges = ut.setdiff(orig_edges, list(preweighted_edges.keys()))

    aug_graph.add_edges_from(new_edges)
    # Ensure the largest possible set of original edges is in the MST
    nx.set_edge_attributes(aug_graph, name='weight', values=dict([(edge, 1.0) for edge in new_edges]))
    nx.set_edge_attributes(aug_graph, name='weight', values=dict([(edge, 0.1) for edge in orig_edges]))
    for cc_sub_graph in nx.connected_component_subgraphs(aug_graph):
        mst_sub_graph = nx.minimum_spanning_tree(cc_sub_graph)
        for edge in mst_sub_graph.edges():
            redge = edge[::-1]
            if not (graph.has_edge(*edge) or graph.has_edge(*redge)):
                graph.add_edge(*redge, attr_dict={}) 
Example #22
Source File: viz_graph.py    From ibeis with Apache License 2.0 5 votes vote down vote up
def augment_graph_mst(ibs, graph):
    import plottool_ibeis as pt
    #spantree_aids1_ = []
    #spantree_aids2_ = []
    # Add edges between all names
    aid_list = list(graph.nodes())
    aug_digraph = graph.copy()
    # Change all weights in initial graph to be small (likely to be part of mst)
    nx.set_edge_attributes(aug_digraph, name='weight', values=.0001)
    aids1, aids2 = get_name_rowid_edges_from_aids(ibs, aid_list)
    if False:
        # Weight edges in the MST based on tenative distances
        # Get tentative node positions
        initial_pos = pt.get_nx_layout(graph.to_undirected(), 'graphviz')['node_pos']
        #initial_pos = pt.get_nx_layout(graph.to_undirected(), 'agraph')['node_pos']
        edge_pts1 = ut.dict_take(initial_pos, aids1)
        edge_pts2 = ut.dict_take(initial_pos, aids2)
        edge_pts1 = vt.atleast_nd(np.array(edge_pts1, dtype=np.int32), 2)
        edge_pts2 = vt.atleast_nd(np.array(edge_pts2, dtype=np.int32), 2)
        edge_weights = vt.L2(edge_pts1, edge_pts2)
    else:
        edge_weights = [1.0] * len(aids1)
    # Create implicit fully connected (by name) graph
    aug_edges = [(a1, a2, {'weight': w})
                  for a1, a2, w in zip(aids1, aids2, edge_weights)]
    aug_digraph.add_edges_from(aug_edges)

    # Determine which edges need to be added to
    # make original graph connected by name
    aug_graph = aug_digraph.to_undirected()
    for cc_sub_graph in nx.connected_component_subgraphs(aug_graph):
        mst_sub_graph = nx.minimum_spanning_tree(cc_sub_graph)
        mst_edges = mst_sub_graph.edges()
        for edge in mst_edges:
            redge = edge[::-1]
            #attr_dict = {'color': pt.DARK_ORANGE[0:3]}
            attr_dict = {'color': pt.BLACK[0:3]}
            if not (graph.has_edge(*edge) or graph.has_edge(*redge)):
                graph.add_edge(*redge, attr_dict=attr_dict) 
Example #23
Source File: pf.py    From PyPSA with GNU General Public License v3.0 5 votes vote down vote up
def find_tree(sub_network, weight='x_pu'):
    """Get the spanning tree of the graph, choose the node with the
    highest degree as a central "tree slack" and then see for each
    branch which paths from the slack to each node go through the
    branch.

    """

    branches_bus0 = sub_network.branches()["bus0"]
    branches_i = branches_bus0.index
    buses_i = sub_network.buses_i()

    graph = sub_network.graph(weight=weight, inf_weight=1.)
    sub_network.tree = nx.minimum_spanning_tree(graph)

    #find bus with highest degree to use as slack
    tree_slack_bus, slack_degree = max(degree(sub_network.tree), key=itemgetter(1))
    logger.debug("Tree slack bus is %s with degree %d.", tree_slack_bus, slack_degree)

    #determine which buses are supplied in tree through branch from slack

    #matrix to store tree structure
    sub_network.T = dok_matrix((len(branches_i),len(buses_i)))

    for j,bus in enumerate(buses_i):
        path = nx.shortest_path(sub_network.tree,bus,tree_slack_bus)
        for i in range(len(path)-1):
            branch = next(iterkeys(graph[path[i]][path[i+1]]))
            branch_i = branches_i.get_loc(branch)
            sign = +1 if branches_bus0.iat[branch_i] == path[i] else -1
            sub_network.T[branch_i,j] = sign 
Example #24
Source File: spanning_tree.py    From complex_network with GNU General Public License v2.0 5 votes vote down vote up
def main():
	# build up a graph
	filename = '../../florentine_families_graph.gpickle'
	G = nx.read_gpickle(filename)

	# Spanning tree
	mst = nx.minimum_spanning_tree(G) 
	out_file = 'florentine_families_graph_minimum_spanning_tree.png'
	PlotGraph.plot_graph(G, filename=out_file, colored_edges=mst.edges())

	edges = nx.minimum_spanning_edges(G, weight='weight', data=True)
	list_edges = list(edges)
	print(list_edges) 
Example #25
Source File: test_mst.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def test_mst(self):
        T=nx.minimum_spanning_tree(self.G)
        assert_equal(T.edges(data=True),self.tree_edgelist) 
Example #26
Source File: test_mst.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def test_mst_disconnected(self):
        G=nx.Graph()
        G.add_path([1,2])
        G.add_path([10,20])
        T=nx.minimum_spanning_tree(G)
        assert_equal(sorted(map(sorted,T.edges())),[[1, 2], [10, 20]])
        assert_equal(sorted(T.nodes()),[1, 2, 10, 20]) 
Example #27
Source File: test_mst.py    From qgisSpaceSyntaxToolkit with GNU General Public License v3.0 5 votes vote down vote up
def test_mst_isolate(self):
        G=nx.Graph()
        G.add_nodes_from([1,2])
        T=nx.minimum_spanning_tree(G)
        assert_equal(sorted(T.nodes()),[1, 2])
        assert_equal(sorted(T.edges()),[]) 
Example #28
Source File: mst.py    From aws-kube-codesuite with Apache License 2.0 4 votes vote down vote up
def minimum_spanning_tree(G, weight='weight', algorithm='kruskal',
                          ignore_nan=False):
    """Returns a minimum spanning tree or forest on an undirected graph `G`.

    Parameters
    ----------
    G : undirected graph
        An undirected graph. If `G` is connected, then the algorithm finds a
        spanning tree. Otherwise, a spanning forest is found.

    weight : str
       Data key to use for edge weights.

    algorithm : string
       The algorithm to use when finding a minimum spanning tree. Valid
       choices are 'kruskal', 'prim', or 'boruvka'. The default is
       'kruskal'.

    ignore_nan : bool (default: False)
        If a NaN is found as an edge weight normally an exception is raised.
        If `ignore_nan is True` then that edge is ignored instead.

    Returns
    -------
    G : NetworkX Graph
       A minimum spanning tree or forest.

    Examples
    --------
    >>> G = nx.cycle_graph(4)
    >>> G.add_edge(0, 3, weight=2)
    >>> T = nx.minimum_spanning_tree(G)
    >>> sorted(T.edges(data=True))
    [(0, 1, {}), (1, 2, {}), (2, 3, {})]


    Notes
    -----
    For Borůvka's algorithm, each edge must have a weight attribute, and
    each edge weight must be distinct.

    For the other algorithms, if the graph edges do not have a weight
    attribute a default weight of 1 will be used.

    There may be more than one tree with the same minimum or maximum weight.
    See :mod:`networkx.tree.recognition` for more detailed definitions.

    Isolated nodes with self-loops are in the tree as edgeless isolated nodes.

    """
    edges = minimum_spanning_edges(G, algorithm, weight, keys=True,
                                   data=True, ignore_nan=ignore_nan)
    T = G.fresh_copy()  # Same graph class as G
    T.graph.update(G.graph)
    T.add_nodes_from(G.nodes.items())
    T.add_edges_from(edges)
    return T 
Example #29
Source File: cycle_cocyle.py    From tobacco_3.0 with GNU General Public License v3.0 4 votes vote down vote up
def cycle_cocyle(TG):

	MST = nx.minimum_spanning_tree(TG)
	scaffold = nx.MultiGraph()

	used_keys = []
	for e in MST.edges(data=True):
		edict = e[2]
		lbl = edict['label']
		ind = edict['index']
		ke = (ind,lbl[0],lbl[1],lbl[2])
		scaffold.add_edge(e[0],e[1],key=ke)
		used_keys.append(ke)

	cycle_basis = []
	cycle_basis_append = cycle_basis.append
	nxfc = nx.find_cycle

	for e0 in TG.edges(data=True):

		edict = e0[2]
		lbl = edict['label']
		ind = edict['index']
		ke = (ind,lbl[0],lbl[1],lbl[2])
		scaffold.add_edge(e0[0],e0[1],key=ke)

		if ke not in used_keys:

			cycles = list(nxfc(scaffold))
			cy_list = [(i[0], i[1], i[2]) for i in cycles]

			if cy_list not in cycle_basis:
				cycle_basis_append(cy_list)

			scaffold.remove_edge(e0[0],e0[1],key=ke)

	node_out_edges = []
	node_out_edges_append = node_out_edges.append
	node_list = list(TG.nodes())
	
	for n in range(len(TG.nodes()) - 1):

		node = node_list[n]
		noe = [node]

		for e in TG.edges(data=True):
			if node == e[0] or node == e[1]:
				edict = e[2]
				lbl = edict['label']
				ke = (edict['index'],lbl[0],lbl[1],lbl[2])
				positive_direction = edict['pd']
				noe.append(positive_direction + ke)

		node_out_edges_append(noe)

	return cycle_basis, node_out_edges 
Example #30
Source File: Sentence.py    From kindred with MIT License 4 votes vote down vote up
def extractMinSubgraphContainingNodes(self, minSet):
		"""
		Find the minimum subgraph of the dependency graph that contains the provided set of nodes. Useful for finding dependency-path like structures
		
		:param minSet: List of token indices
		:type minSet: List of ints
		:return: All the nodes and edges in the minimal subgraph
		:rtype: Tuple of nodes,edges where nodes is a list of token indices, and edges are the associated dependency edges between those tokens
		"""

		assert isinstance(minSet, list)
		for i in minSet:
			assert isinstance(i, int)
			assert i >= 0
			assert i < len(self.tokens)
		G1 = nx.Graph()
		for a,b,depType in self.dependencies:
			G1.add_edge(a,b,dependencyType=depType)

		G2 = nx.Graph()
		paths = {}

		minSet = sorted(list(set(minSet)))
		setCount1 = len(minSet)
		minSet = [ a for a in minSet if G1.has_node(a) ]
		setCount2 = len(minSet)
		if setCount1 != setCount2:
			sys.stderr.write("WARNING. %d node(s) not found in dependency graph!\n" % (setCount1-setCount2))
		for a,b in itertools.combinations(minSet,2):
			try:
				path = nx.shortest_path(G1,a,b)
				paths[(a,b)] = path
				G2.add_edge(a,b,weight=len(path))
			except nx.exception.NetworkXNoPath:
				sys.stderr.write("WARNING. No path found between nodes %d and %d!\n" % (a,b))
			
		# TODO: This may through an error if G2 ends up having multiple components. Catch it gracefully.
		minTree = nx.minimum_spanning_tree(G2)
		nodes = set()
		allEdges = set()
		for a,b in minTree.edges():
			path = paths[(min(a,b),max(a,b))]
			for i in range(len(path)-1):
				a,b = path[i],path[i+1]
				dependencyType = G1.get_edge_data(a,b)['dependencyType']
				edge = (min(a,b),max(a,b),dependencyType)
				allEdges.add(edge)
			nodes.update(path)

		return nodes,allEdges