예제 #1
0
def get_graph_compressed(graph_data):
    """
    Getting the Compressed Graph. A Compressed Graph is a DAG, after removing
    unreachable graph nodes, and getting bfs tree.
    """
    # Creating the directed graphs, for graph1.
    dgraph = nx.DiGraph(graph_data)
    if not dgraph.has_node(0):  # adding root node, on one node case.
        dgraph.add_node(0)
    # First, remove non reachable nodes, from the root.
    # assuming node 0 is the function root node.
    bfsy = nx.bfs_tree(dgraph, 0).nodes()
    if 0 not in bfsy:
        bfsy.append(0)
    for i in dgraph.nodes():
        if i not in bfsy:
            dgraph.remove_node(i)

    # Second, _collapse some vertices together...
    dgraph = _collapse(dgraph)

    # create DAG's (computing scc) from digraph before.
    compressed_graph = nx.condensation(dgraph)

    return compressed_graph.edges()
예제 #2
0
def Dulmage_Mendelsohn(g, eqs):
    '''The input graph g is assumed to be a bipartite graph with no isolated 
    nodes. Returns the diagonal blocks as a list of (equations, variables).'''
    assert_all_in_graph(g, eqs)
    assert_no_isolates(g)
    assert eqs, 'At least one equation is expected'
    assert is_bipartite_node_set(g, eqs)
    # Maximum matching
    mate = nx.max_weight_matching(g, maxcardinality=True)
    matches = sorted((k, mate[k]) for k in mate if k in eqs)
    log('Matches:')
    for eq, var in matches:
        log(eq, var)
    # Direct the edges of g according to the matching
    bipart = to_digraph(g, matches)
    plot(bipart)
    # Find the strongly connected components (SCCs) of the equations
    eq_sccs = nx.condensation(projected_graph(bipart, eqs))
    plot(eq_sccs)
    # Q: With proper implementation, shouldn't the SCCs be already top. sorted?
    precedence_order = nx.topological_sort(eq_sccs)
    # Collect the diagonal blocks as a list of (equations, variables)
    diagonal_blocks = []
    seen = set()
    for scc in precedence_order:
        equations = eq_sccs.node[scc]['members']
        variables = {
            n
            for eq in equations for n in g.edge[eq] if n not in seen
        }
        seen.update(variables)
        diagonal_blocks.append((equations, list(variables)))
    return diagonal_blocks
예제 #3
0
def attracting_components(G):
    """Returns a list of attracting components in `G`.

    An attracting component in a directed graph `G` is a strongly connected
    component with the property that a random walker on the graph will never
    leave the component, once it enters the component.

    The nodes in attracting components can also be thought of as recurrent
    nodes.  If a random walker enters the attractor containing the node, then
    the node will be visited infinitely often.

    Parameters
    ----------
    G : DiGraph, MultiDiGraph
        The graph to be analyzed.

    Returns
    -------
    attractors : list
        The list of attracting components, sorted from largest attracting
        component to smallest attracting component.

    See Also
    --------
    number_attracting_components
    is_attracting_component 
    attracting_component_subgraphs

    """
    scc = nx.strongly_connected_components(G)
    cG = nx.condensation(G, scc)
    attractors = [scc[n] for n in cG if cG.out_degree(n) == 0]
    attractors.sort(key=len,reverse=True)
    return attractors
예제 #4
0
def condensation_plus(G):
	C = nx.condensation(G)
	maps = {}
	maps = C.graph['mapping']

	num_of_c = C.number_of_nodes();
	nbunch = {}
	for num in range(0,num_of_c):
		nbunch[num] = []

	#search through and divide G.nodes() into groups
	for num in range(0,num_of_c):
		for name in G.nodes():
			if maps[name]==num:
				nbunch[num].append(name)

	G_sub = {};

	for i in range(0, num_of_c):
		G_sub[i] = G.subgraph(nbunch[i])

	result = [];
	result.append(C);
	result.append(G_sub);

	return result
예제 #5
0
    def _create_spatial_index(self):
        G = nx.condensation(self.G)  # convert to DAG
        index = dict()
        # Add 1 hop reachability for a DAG
        for v in G.nodes():  # for each component
            for w in G.node[v]['members']:  # for each node in the component
                if 'spatial' in self.G.node[w]:  # is 'w' a spatial node?
                    index.upsert(v, {self.region(w)})  # if yes, add block # of 'w' to v's meta

        # Add multi hop reachability
        self._do_dfs(G, index)
        # Update reachability information to each node in the component
        for v in G.nodes():  # for each component
            for w in G.node[v]['members']:  # for each node in the component
                try:
                    self.spatial_index[w] = index[v]  # set component's index entry to each vertex in it
                except KeyError:
                    pass  # ignore if index entry is not found as they don't have any spatial connections

        # free up space
        G = None
        index = None
        gc.collect(0)

        # Create region based index
        c = count()
        for v in self.G.nodes():
            if 'spatial' in self.G.node[v]:
                x = self.G.node[v]['spatial']['lng']
                y = self.G.node[v]['spatial']['lat']
                self.region_index.insert(next(c), (x, y, x, y), v)
def strongly_connected_components():
    conn = sqlite3.connect("zhihu.db")     
    #following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 50000) and user_url in (select user_url from User where agree_num > 50000)', conn)        
    following_data = pd.read_sql('select user_url, followee_url from Following where followee_url in (select user_url from User where agree_num > 10000) and user_url in (select user_url from User where agree_num > 10000)', conn)        
    conn.close()
    
    G = nx.DiGraph()
    cnt = 0
    for d in following_data.iterrows():
        G.add_edge(d[1][0],d[1][1])
        cnt += 1
    print 'links number:', cnt

    scompgraphs = nx.strongly_connected_component_subgraphs(G)
    scomponents = sorted(nx.strongly_connected_components(G), key=len, reverse=True)
    print 'components nodes distribution:', [len(c) for c in scomponents]
    
    #plot graph of component, calculate saverage_shortest_path_length of components who has over 1 nodes
    index = 0
    print 'average_shortest_path_length of components who has over 1 nodes:'
    for tempg in scompgraphs:
        index += 1
        if len(tempg.nodes()) != 1:
            print nx.average_shortest_path_length(tempg)
            print 'diameter', nx.diameter(tempg)
            print 'radius', nx.radius(tempg)
        pylab.figure(index)
        nx.draw_networkx(tempg)
        pylab.show()

    # Components-as-nodes Graph
    cG = nx.condensation(G)
    pylab.figure('Components-as-nodes Graph')
    nx.draw_networkx(cG)
    pylab.show()    
예제 #7
0
def path_entropy(graph, backward=False, condensed=False):
    u"""Compute the average path entropy of a graph.

    There is a more efficient algorithm defined in the paper. It is only
    partially implemented so far. This is the naive aproach.

    Corominas-Murtra, B., Goñi, J., Solé, R. V, & Rodríguez-Caso, C. (2013).
    "On the origins of hierarchy in complex networks". PNAS, 110(33), 13316–21.
    http://doi.org/10.1073/pnas.1300832110
    """
    gc = graph if condensed else nx.condensation(graph)
    maximals = [n for n, d in gc.in_degree_iter() if d == 0]
    minimals = [n for n, d in gc.out_degree_iter() if d == 0]
    degrees_func = gc.in_degree if backward else gc.out_degree

    entropy = 0
    for source in maximals:
        for target in minimals:
            for path in nx.all_simple_paths(gc, source, target):
                d = 1
                degs = [degrees_func(n) for n in path]
                degs = degs if backward else degs[::-1]
                _degs = 1 / np.cumprod(degs[1:], dtype=float)
                entropy += (_degs * np.log(_degs)).sum()
    return -1 * entropy
예제 #8
0
    def _omega_graphviz_string(self,give_repre=None):
        d = self.left_omega_cayley(label=False)
        G = nx.condensation(nx.DiGraph(d))
        T = nx.topological_sort(G)[0] 
        sources = G.node[T]["members"]
        d = self.left_omega_cayley()
        J_min = self._get_J_topological_sort()
        J_min = J_min[len(J_min)-1]
        J_min = list(set(give_repre).intersection(J_min))[0]
        s = """
subgraph clusteromega{
style=filled;
color=black;
fillcolor=azure;\n"""
        O = self.omega_elements()
        for x in O:
            s +='  "'+str(x)+'"[label="'+str(x)+'",shape=rectangle,fillpcolor=white];\n'
        s += '}\n'
        for e in d:
            s += '   "'+str(e[0])+'"->"'+str(e[1])+'"[label="'+str(e[2])+'."];\n'
        if not give_repre:
            for e in self.idempotents():
                s += '   '+str(e)+'->"'+str(self.omega_power(e))+'"[color=darkgreen, weight=10];\n'
        else:
            for x in give_repre:
                I = set(self.idempotents()).intersection(self.J_class_of_element(x))            
                for e in I:
                    s += '   '+str(x)+":"+str(e)+'->"'+str(self.omega_power(e))+'"[color=darkgreen, weight=10];\n'
        for k in sources:
            s +=  '   '+str(J_min)+' -> "'+str(k)+'"[style=invis];\n'
        return s
예제 #9
0
 def test_null_graph(self):
     G = nx.DiGraph()
     assert list(nx.strongly_connected_components(G)) == []
     assert list(nx.kosaraju_strongly_connected_components(G)) == []
     assert list(nx.strongly_connected_components_recursive(G)) == []
     assert len(nx.condensation(G)) == 0
     pytest.raises(nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph())
예제 #10
0
 def test_contract_scc2(self):
     # Bug found and fixed in [1687].
     G = nx.DiGraph()
     G.add_edge(1,2)
     G.add_edge(2,1)
     cG = nx.condensation(G)
     assert_true((1,2) in cG)
예제 #11
0
 def find_route_in_order(dl, tram_line):
     """
     Basically it performs condensation on MultiDiGraph -> in result we obtain DAG
     Nodes of condensation graph C of G are in correct order
     :param dl: DataLoader object
     :param tram_line: LineString representig route of tram
     :return: list of nodes in order [start_of_route, ..., end_of_route]
     """
     # List of nodes that are include in route
     nodes = GraphConverter.line_to_nodes_precise(dl.graph, tram_line)
     sub = dl.graph.subgraph(nodes)
     # Perform condensation
     sub = nx.condensation(sub)
     route = list()
     # The nodes labels are integers corresponding to the index of the component
     # Each node as dictionary with 'members' property mapping the original nodes to the nodes in C
     for node in sub.nodes(data=True):
         mem = node[1]['members']
         if isinstance(mem, set):
             mem = list(mem)
             for el in mem:
                 route.append(el)
         else:
             route.append(mem)
     return route[::-1]
예제 #12
0
def solve_2_sat(num_variables: int, or_pairs: List[Tuple[int, int]]) -> List[int]:
	"""takes or clauses (2-CNF), returns ids of true values, sorted by absolute id.
	negative ids indicate negations,
	e.g. 3, [(-1,2),(-2,3),(-3,-1)] -> [-1,2,3]"""
	g = nx.DiGraph()
	for n in range(1, num_variables + 1):
		g.add_node(n)
		g.add_node(-n)
	for a, b in or_pairs:
		assert 1 <= abs(a) <= num_variables and 1 <= abs(b) <= num_variables
		g.add_edge(-a, b)
		g.add_edge(-b, a)
	sccs = list(nx.strongly_connected_components(g))
	for s in sccs:
		for node in s:
			if (-node) in s:
				return None
	g_condensed = nx.condensation(g, scc=sccs)
	top_sorted_scc_ids = nx.topological_sort(g_condensed, reverse=True)
	truths = set()
	for scc_id in top_sorted_scc_ids:
		scc = sccs[scc_id]
		for node in scc:
			if (-node) not in truths:
				truths.add(node)
	assert len(truths) == num_variables
	res = list()
	for n in range(1, num_variables + 1):
		if n in truths:
			res.append(n)
		else:
			res.append(-n)
	return res
예제 #13
0
def attracting_components(G):
    """Generates a list of attracting components in `G`.

    An attracting component in a directed graph `G` is a strongly connected
    component with the property that a random walker on the graph will never
    leave the component, once it enters the component.

    The nodes in attracting components can also be thought of as recurrent
    nodes.  If a random walker enters the attractor containing the node, then
    the node will be visited infinitely often.

    Parameters
    ----------
    G : DiGraph, MultiDiGraph
        The graph to be analyzed.

    Returns
    -------
    attractors : generator of sets
        A generator of sets of nodes, one for each attracting component of G.

    See Also
    --------
    number_attracting_components
    is_attracting_component 
    attracting_component_subgraphs

    """
    scc = list(nx.strongly_connected_components(G))
    cG = nx.condensation(G, scc)
    for n in cG:
        if cG.out_degree(n) == 0:
            yield scc[n]
예제 #14
0
 def test_graph_has_isolated_components(self):
     self.setUp()
     scc_G = nx.condensation(self.G)
     scc_G_nodes = nx.number_of_nodes(scc_G)
     scc_G_comp = nx.number_strongly_connected_components(scc_G)
     self.assertEqual(scc_G_comp, scc_G_nodes,
                      'Connected Components are not isolated')
예제 #15
0
파일: tests.py 프로젝트: dglmoore/big-attrs
    def test_complex(self):
        net = nb.WTNetwork([
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, -1, 0, 0, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, -1, -1, 1, 1, 0, 0, 0, 0],
            [0, -1, 0, -1, 1, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, -1, 1, 0, 0],
            [0, 0, 0, 0, 1, 0, -1, 1, 0, 0],
            [0, 0, 0, 0, 0, 1, 0, 0, -1, -1],
            [0, 0, 0, 0, -1, 0, 0, 0, 1, 0],
        ])

        g = net.to_networkx_graph()
        self.assertEqual([[8, 9], [6, 7], [4, 5], [0, 1], [2, 3]],
                         list(map(list, nx.strongly_connected_components(g))))
        self.assertEqual([(2, 1), (2, 0), (3, 2), (4, 2)],
                         list(nx.condensation(g).edges))

        expect = ns.attractors(net)

        got = main.attractors(net)

        self.assertUnorderedEqual(expect, got)
예제 #16
0
def get_graph_compressed(graph_data):
    """
    Getting the Compressed Graph. A Compressed Graph is a DAG, after removing
    unreachable graph nodes, and getting bfs tree.
    """
    # Creating the directed graphs, for graph1.
    dgraph = nx.DiGraph(graph_data)
    if not dgraph.has_node(0):  # adding root node, on one node case.
        dgraph.add_node(0)
    # First, remove non reachable nodes, from the root.
    # assuming node 0 is the function root node.
    bfsy = nx.bfs_tree(dgraph, 0).nodes()
    if 0 not in bfsy:
        bfsy.append(0)
    for i in dgraph.nodes():
        if i not in bfsy:
            dgraph.remove_node(i)

    # Second, _collapse some vertices together...
    dgraph = _collapse(dgraph)

    # create DAG's (computing scc) from digraph before.
    compressed_graph = nx.condensation(dgraph)

    return compressed_graph.edges()
예제 #17
0
def attracting_components(G):
    """Generates a list of attracting components in `G`.

    An attracting component in a directed graph `G` is a strongly connected
    component with the property that a random walker on the graph will never
    leave the component, once it enters the component.

    The nodes in attracting components can also be thought of as recurrent
    nodes.  If a random walker enters the attractor containing the node, then
    the node will be visited infinitely often.

    Parameters
    ----------
    G : DiGraph, MultiDiGraph
        The graph to be analyzed.

    Returns
    -------
    attractors : generator of sets
        A generator of sets of nodes, one for each attracting component of G.

    See Also
    --------
    number_attracting_components
    is_attracting_component 
    attracting_component_subgraphs

    """
    scc = list(nx.strongly_connected_components(G))
    cG = nx.condensation(G, scc)
    for n in cG:
        if cG.out_degree(n) == 0:
            yield scc[n]
예제 #18
0
 def test_null_graph(self):
     G = nx.DiGraph()
     assert_equal(list(nx.strongly_connected_components(G)), [])
     assert_equal(list(nx.kosaraju_strongly_connected_components(G)), [])
     assert_equal(list(nx.strongly_connected_components_recursive(G)), [])
     assert_equal(len(nx.condensation(G)), 0)
     assert_raises(nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph())
예제 #19
0
def components(graph):
    print("Number of strongly connected components",
          nx.number_strongly_connected_components(graph))
    print("Number of weakly connected components",
          nx.number_weakly_connected_components(graph))

    condensation = nx.condensation(graph)
    nx.write_edgelist(condensation, "Datasets/condenced_graph.edgelist")
예제 #20
0
def orderability(G, condensed_nx_graph=None, num_thresholds=8, threshold_distribution=None):
    """Evaluates orderability, or number of nodes which were not condensed
     over total number of nodes in original uncondensed graph. Evaluated as in [1]_

    Parameters
    ----------
    G: NetworkX Graph
        A directed graph.
    condensed_nx_graph: optional
        Directed acyclic networkX graph if already evaluated to save computational time
    num_thresholds: int, optional
        only applicable as node_weighted_condense parameter if G is weighted
    threshold_distribution: float, optional
        only applicable as node_weighted_condense parameter if G is weighted

    Return
    -------
    float: orderability
        Hierarchy coordinate


    Examples
    ---------
    a = np.array([
        [0, 0.2, 0, 0, 0],
        [0, 0, 0, 0.7, 0],
        [0, 0.4, 0, 0, 0],
        [0, 0, 0.1, 0, 1.0],
        [0, 0, 0, 0, 0],
    ])

    G = nx.from_numpy_matrix(a, create_using=nx.DiGraph)
    print(hc.orderability(G))


    Notes
    ______
    TODO: Not sure what's proper re: optional num_thresholds and threshold_distribution parameter
    .. [1] "On the origins of hierarchy in complex networks."
     Corominas-Murtra, Bernat, Joaquín Goñi, Ricard V. Solé, and Carlos Rodríguez-Caso,
     Proceedings of the National Academy of Sciences 110, no. 33 (2013)
    """

    if not np.array_equal(np.unique(nx.to_numpy_array(G)), [0, 1]):  # unweighted (non-binary) check
        o = 0
        condensed_graphs, original_graphs = node_weighted_condense(nx.to_numpy_array(G),  # creates binary graphs
                                                                   num_thresholds=num_thresholds,
                                                                   threshold_distribution=threshold_distribution)

        for index in range(len(condensed_graphs)):
            o += orderability(original_graphs[index], condensed_graphs[index])
        return o / len(condensed_graphs)

    if condensed_nx_graph is None:
        condensed_nx_graph = weight_nodes_by_condensation(nx.condensation(G))
    non_cyclic_nodes = [node[0] for node in nx.get_node_attributes(condensed_nx_graph, 'weight').items() if node[1] == 1]
    total_acyclic_node_weight = sum([weight for weight in nx.get_node_attributes(condensed_nx_graph, 'weight').values()])
    return len(non_cyclic_nodes) / total_acyclic_node_weight
예제 #21
0
def attractors(net, size=None, encode=True):
    if not is_network(net):
        raise TypeError("net must be a network or a networkx DiGraph")
    elif is_fixed_sized(net) and size is not None:
        raise ValueError("fixed sized networks require size is None")
    elif not is_fixed_sized(net) and size is None:
        raise ValueError("variable sized networks require a size")

    if size is None:
        g = net.to_networkx_graph()
        encoder = net.state_space()._unsafe_encode
    else:
        g = net.to_networkx_graph(size)
        encoder = net.state_space(size)._unsafe_encode

    modules = list(nx.strongly_connected_components(g))

    dag = nx.condensation(g)
    dag_list = list(nx.topological_sort(dag))

    attractors = {}

    for module_number in dag_list:
        parents = greatest_predecessors(dag, module_number)
        if len(parents) == 0:
            nodes = modules[module_number]
            attractors[module_number] = {
                'eff_module': nodes,
                'attractors': attractors_brute_force(net, size, subgraph=nodes)
            }
        else:
            parent_modules = [attractors[p]['eff_module'] for p in parents]
            parent_attractors = [attractors[p]['attractors'] for p in parents]
            parent = direct_sum(parent_modules, parent_attractors)

            subgraph = modules[module_number]
            attractors[module_number] = {
                'eff_module':
                parent[0] | subgraph,
                'attractors':
                attractors_brute_force(net,
                                       size,
                                       subgraph=subgraph,
                                       parent=parent)
            }

    outputs = list(
        filter(lambda m: len(list(dag.successors(m))) == 0, dag_list))
    parent_modules = [attractors[o]['eff_module'] for o in outputs]
    parent_attractors = [attractors[o]['attractors'] for o in outputs]

    _, attractors = direct_sum(parent_modules, parent_attractors)

    if encode:
        return list(
            map(lambda attractor: list(map(encoder, attractor)), attractors))
    else:
        return attractors
def node_weighted_condense(A,
                           num_thresholds=8,
                           exp_threshold_distribution=None):
    """
    returns a series of node_weighted condensed graphs (DAGs) [*] and their original nx_graphs.
    [*] Hierarchy in Complex Networks: the possible and the actual: Supporting information. Corominas-Murtra et al. [2013]
    :param timestep: timestep for conversion
    :param num_thresholds: Number of thresholds and resultant sets of node-weighted Directed Acyclic Graphs
    :param exp_threshold_distribution: if true or float, distributes the thresholds exponentially, with an exponent equal to the float input.
    :return condensed graphs, a list of node_weighted condensed nx_graphs, one for every threshold and corresponding binary A
    An exponent of 0 results in a linear distribution, otherwise the exp distribution is sampled from e^(exp_float)*2e - e^(exp_float)*e
    """
    # Establishing Thresholds
    if exp_threshold_distribution is None:
        if np.isclose(np.max(A) - np.min(A), 0, 1e-2):
            print(f"Breadth of A: {np.max(A)-np.min(A)}")
        try:
            thresholds = list(
                np.round(
                    np.arange(np.min(A), np.max(A),
                              (np.max(A - np.min(A))) / num_thresholds), 4))
        except:
            thresholds = [np.max(A)] * num_thresholds
    else:
        thresholds = utility_funcs.exponentially_distribute(
            exponent=exp_threshold_distribution,
            dist_max=np.max(A),
            dist_min=np.min(A),
            num_exp_distributed_values=num_thresholds)
    # Converting to binary nx_graphs according to thresholds:
    nx_graphs = [
        nx.from_numpy_matrix(np.where(A > threshold, 1, 0),
                             create_using=nx.DiGraph)
        for threshold in thresholds
    ]
    # base_binary_graphs = [nx.to_numpy_array(nx_graphs[val]) for val in range(len(nx_graphs))]  # yes, it's silly to reconvert if this is actually needed.

    condensed_graphs = [
        nx.condensation(nx_graphs[index]) for index in range(len(nx_graphs))
    ]
    largest_condensed_graphs = []
    for condensed_graph in condensed_graphs:
        largest_condensed_graphs.append(
            nx.convert_node_labels_to_integers(
                max(weakly_connected_component_subgraphs(condensed_graph,
                                                         copy=True),
                    key=len)))
        # networkx.weakly_connected_component_subgraphs comes from networkx 1.10 documentation, and has sense been discontinued.
        # For ease of access and future networkx compatibility, it was copied directly to this file before the class declaration.
        members = nx.get_node_attributes(largest_condensed_graphs[-1],
                                         'members')
        node_weights = [len(w) for w in members.values()]
        for node_index in range(len(node_weights)):
            largest_condensed_graphs[-1].nodes[node_index][
                "weight"] = node_weights[node_index]

    return largest_condensed_graphs, nx_graphs
예제 #23
0
 def test_contract_scc_isolate(self):
     # Bug found and fixed in [1687].
     G = nx.DiGraph()
     G.add_edge(1,2)
     G.add_edge(2,1)
     scc = nx.strongly_connected_components(G)        
     cG = nx.condensation(G, scc)
     assert_equal(cG.nodes(),[0])
     assert_equal(cG.edges(),[])
예제 #24
0
def make_acyclic_scc(G):
    reduced = nx.condensation(G, scc=None)
    SCC_list= list(nx.strongly_connected_components(G))
    Super_nodes = {}
    
    for i in range(int(nx.number_strongly_connected_components(G))):
        Super_nodes[i] = list(SCC_list[i])
    
    return reduced, Super_nodes     
예제 #25
0
def compute_condensation_in_topological_order(dependency_graph: nx.DiGraph, sort_by = lambda x: x):
    if not dependency_graph.number_of_nodes():
        return

    condensed_graph = nx.condensation(dependency_graph)
    assert isinstance(condensed_graph, nx.DiGraph)

    for connected_component_index in nx.lexicographical_topological_sort(condensed_graph, key=sort_by):
        yield list(sorted(condensed_graph.node[connected_component_index]['members'], key=sort_by))
예제 #26
0
 def test_condensation_mapping_and_members(self):
     G, C = self.gc[1]
     cG = nx.condensation(G)
     mapping = cG.graph['mapping']
     assert_true(all(n in G for n in mapping))
     assert_true(all(0 == cN for n, cN in mapping.items() if n in C[0]))
     assert_true(all(1 == cN for n, cN in mapping.items() if n in C[1]))
     for n, d in cG.nodes(data=True):
         assert_equal(C[n], cG.node[n]['members'])
예제 #27
0
 def test_condensation_mapping_and_members(self):
     G, C = self.gc[1]
     cG = nx.condensation(G)
     mapping = cG.graph['mapping']
     assert_true(all(n in G for n in mapping))
     assert_true(all(0 == cN for n, cN in mapping.items() if n in C[0]))
     assert_true(all(1 == cN for n, cN in mapping.items() if n in C[1]))
     for n, d in cG.nodes(data=True):
         assert_equal(C[n], cG.node[n]['members'])
예제 #28
0
 def condensed_relevance_graph(self) -> nx.DiGraph:
     """
     Return the condensed_relevance graph whose nodes are the maximal sccs of the full relevance graph
     of the original MAID.
     - The condensed_relevance graph will always be acyclic. Therefore, we can return a topological ordering.
     """
     rg = self.relevance_graph()
     con_rel = nx.condensation(rg)
     return con_rel
예제 #29
0
 def test_contract_scc_isolate(self):
     # Bug found and fixed in [1687].
     G = nx.DiGraph()
     G.add_edge(1, 2)
     G.add_edge(2, 1)
     scc = list(nx.strongly_connected_components(G))
     cG = nx.condensation(G, scc)
     assert_equal(list(cG.nodes()), [0])
     assert_equal(list(cG.edges()), [])
예제 #30
0
 def __init__(self, macid: MACIDBase):
     super().__init__()
     rg = RelevanceGraph(macid)
     con_rel = nx.condensation(rg)
     self.add_nodes_from(con_rel.nodes)
     self.add_edges_from(con_rel.edges)
     # this generates a dictionary matching each decision node
     # in rg to the node of con_rel that it's in.
     self.graph["mapping"] = con_rel.graph["mapping"]
 def test_condensation_mapping_and_members(self):
     G, C = self.gc[1]
     C = sorted(C, key=len, reverse=True)
     cG = nx.condensation(G)
     mapping = cG.graph["mapping"]
     assert_true(all(n in G for n in mapping))
     assert_true(all(0 == cN for n, cN in mapping.items() if n in C[0]))
     assert_true(all(1 == cN for n, cN in mapping.items() if n in C[1]))
     for n, d in cG.nodes(data=True):
         assert_equal(set(C[n]), cG.node[n]["members"])
예제 #32
0
 def _get_J_topological_sort(self):        
     try :
         T = self._J_topological_sort
     except:
         G = self.cayley_graph(orientation="left_right")
         K = nx.condensation(G,nx.strongly_connected_components(G))
         T = nx.topological_sort(K)
         T = [K.node[i]["members"] for i in T]
         self._J_topological_sort = T
     return T
예제 #33
0
 def test_condensation_mapping_and_members(self):
     G, C = self.gc[1]
     C = sorted(C, key=len, reverse=True)
     cG = nx.condensation(G)
     mapping = cG.graph['mapping']
     assert all(n in G for n in mapping)
     assert all(0 == cN for n, cN in mapping.items() if n in C[0])
     assert all(1 == cN for n, cN in mapping.items() if n in C[1])
     for n, d in cG.nodes(data=True):
         assert set(C[n]) == cG.nodes[n]['members']
예제 #34
0
def is_semiconnected(G, topo_order=None):
    """Returns True if the graph is semiconnected, False otherwise.

    A graph is semiconnected if, and only if, for any pair of nodes, either one
    is reachable from the other, or they are mutually reachable.

    Parameters
    ----------
    G : NetworkX graph
        A directed graph.

    topo_order: list or tuple, optional
        A topological order for G (if None, the function will compute one)

    Returns
    -------
    semiconnected : bool
        True if the graph is semiconnected, False otherwise.

    Raises
    ------
    NetworkXNotImplemented
        If the input graph is undirected.

    NetworkXPointlessConcept
        If the graph is empty.

    Examples
    --------
    >>> G=nx.path_graph(4,create_using=nx.DiGraph())
    >>> print(nx.is_semiconnected(G))
    True
    >>> G=nx.DiGraph([(1, 2), (3, 2)])
    >>> print(nx.is_semiconnected(G))
    False

    See Also
    --------
    is_strongly_connected
    is_weakly_connected
    is_connected
    is_biconnected
    """
    if len(G) == 0:
        raise nx.NetworkXPointlessConcept(
            'Connectivity is undefined for the null graph.')

    if not nx.is_weakly_connected(G):
        return False

    G = nx.condensation(G)
    if topo_order is None:
        topo_order = nx.topological_sort(G)

    return all(G.has_edge(u, v) for u, v in pairwise(topo_order))
예제 #35
0
    def _rebuild_mito_relationship(self):
        # condensation requires directed graph
        mito = nx.condensation(nx.DiGraph(self.graph))

        attrs = dict()
        for mid, members in mito.nodes(data="members"):
            attrs.update({nid: {"mid": mid} for nid in members})
        nx.set_node_attributes(self.graph, attrs)

        logger.info(f"{len(mito)} (grouped) mitochondria")
        self.mito = nx.freeze(mito)
예제 #36
0
def recalculate_function_can_throw_info(module: ir3.Module):
    if not module.function_defns:
        return module

    function_dependency_graph = nx.DiGraph()

    function_defn_by_name = {
        function_defn.name: function_defn
        for function_defn in module.function_defns
    }

    for function_defn in module.function_defns:
        function_dependency_graph.add_node(function_defn.name)

        for global_function_name in get_referenced_global_function_names(
                function_defn):
            if global_function_name in function_defn_by_name.keys():
                function_dependency_graph.add_edge(function_defn.name,
                                                   global_function_name)

    condensed_graph = nx.condensation(function_dependency_graph)
    assert isinstance(condensed_graph, nx.DiGraph)

    function_dependency_graph_transitive_closure = nx.transitive_closure(
        function_dependency_graph)
    assert isinstance(function_dependency_graph_transitive_closure, nx.DiGraph)

    # Determine which connected components can throw.
    condensed_node_can_throw = defaultdict(lambda: False)
    for connected_component_index in nx.topological_sort(condensed_graph,
                                                         reverse=True):
        condensed_node = condensed_graph.node[connected_component_index]

        # If a function in this connected component can throw, the whole component can throw.
        for function_name in condensed_node['members']:
            if function_contains_raise_stmt(
                    function_defn_by_name[function_name]):
                condensed_node_can_throw[connected_component_index] = True

        # If a function in this connected component calls a function in a connected component that can throw, this
        # connected component can also throw.
        for called_condensed_node_index in condensed_graph.successors(
                connected_component_index):
            if condensed_node_can_throw[called_condensed_node_index]:
                condensed_node_can_throw[connected_component_index] = True

    function_can_throw = dict()
    for connected_component_index in condensed_graph:
        for function_name in condensed_graph.node[connected_component_index][
                'members']:
            function_can_throw[function_name] = condensed_node_can_throw[
                connected_component_index]

    return apply_function_can_throw_info(module, function_can_throw)
예제 #37
0
def MBB(grafo):
    MBB = nx.strongly_connected_components(grafo)
    MBB1 = []
    count = 0
    corresp = {}
    for blocks in MBB:
        corresp[count] = blocks
        MBB1.append(blocks)
        count = count + 1
    grafo.grafo = nx.condensation(grafo, scc=MBB1)
    return (grafo, corresp)
예제 #38
0
 def condensation(self):
     if DEBUG_FLAG:
         print "self.dep_graph.number_of_nodes()", self.dep_graph.number_of_nodes()
     c0 = nx.condensation(self.dep_graph)
     for cnode in c0.nodes():
         stratum_atoms = c0.node[cnode]['members']
         rules = []
         for atom in stratum_atoms:
             for rule in self.head2rules[atom]:
                 rules.append(rule)
         c0.node[cnode]['stratum'] = Stratum(stratum_atoms, rules)
     return c0
def condensation_nx( G, components) :
	"""
	G : DiGraph object. the nx.DiGraph attribute is extracted from this.

	components : 	Given components C_1 .. C_k which partition the nodes of G, the
	condensation graph cG has nodes <C_1> .. <C_k> and has edge
	(<C_i>,<C_j>) iff there was an edge in G from a node in C_i to a
	node in C_j.
	"""
	cG = DiGraph()
	cG.graph = nx.condensation( G.graph, components )
	return cG
예제 #40
0
    def __init__(self, markov_table, init_dist=None):
        """
        Constructs a Markov Chain from a transition matrix.
        The initial distribution can be provided or be set afterwards.
        """

        # Attributes
        self.running_state = None
        self.steps = 0
        self.visits = {state: 0 for state in markov_table}
        size = len(markov_table)

        # Set up state transition probs
        self._states = {
            state: self._partial_sums(dist)
            for state, dist in markov_table.items()
        }
        for state, dist in self._states.items():
            if not np.isclose(dist[-1][0], 1.0):
                msg = "State {} transitions do not add up to 1.0".format(state)
                raise ValueError(msg)
        self._probs_state = np.array([0] * size)

        # Adjacency Matrix
        data, rows, cols = [], [], []
        for row, dist in markov_table.items():
            col, pval = zip(*[(s, p) for s, p in dist.items() if p > 0])
            rows += [row] * len(col)
            cols += col
            data += pval
        # make sure they are in the right order
        enum = {state: i for i, state in enumerate(self._states)}
        rows = [enum[r] for r in rows]
        cols = [enum[c] for c in cols]
        self._adj = csr_matrix((data, (rows, cols)), shape=(size, size))

        # Communication Classes
        classes = {'Closed': [], 'Open': []}
        g = nx.MultiDiGraph(self._adj)
        scc = list(nx.strongly_connected_components(g))
        g = nx.condensation(g)  # SCCs collapse to single nodes
        for n in g:
            if g.out_degree(n) == 0:
                classes["Closed"].append(scc[n])
            else:
                classes["Open"].append(scc[n])
        self.communication_classes = classes

        # Set Initial State
        self._init_dist = None
        if init_dist is not None:
            self.init_dist = init_dist
def recalculate_template_instantiation_can_trigger_static_asserts_info(
        header: ir.Header):
    if not header.template_defns:
        return header

    template_defn_by_name = {
        template_defn.name: template_defn
        for template_defn in header.template_defns
    }
    template_defn_dependency_graph = compute_template_dependency_graph(
        header.template_defns, template_defn_by_name)

    condensed_graph = nx.condensation(template_defn_dependency_graph)
    assert isinstance(condensed_graph, nx.DiGraph)

    template_defn_dependency_graph_transitive_closure = nx.transitive_closure(
        template_defn_dependency_graph)
    assert isinstance(template_defn_dependency_graph_transitive_closure,
                      nx.DiGraph)

    # Determine which connected components can trigger static assert errors.
    condensed_node_can_trigger_static_asserts = defaultdict(lambda: False)
    for connected_component_index in reversed(
            list(nx.lexicographical_topological_sort(condensed_graph))):
        condensed_node = condensed_graph.node[connected_component_index]

        # If a template defn in this connected component can trigger a static assert, the whole component can.
        for template_defn_name in condensed_node['members']:
            if _template_defn_contains_static_assert_stmt(
                    template_defn_by_name[template_defn_name]):
                condensed_node_can_trigger_static_asserts[
                    connected_component_index] = True

        # If a template defn in this connected component references a template defn in a connected component that can
        # trigger static asserts, this connected component can also trigger them.
        for called_condensed_node_index in condensed_graph.successors(
                connected_component_index):
            if condensed_node_can_trigger_static_asserts[
                    called_condensed_node_index]:
                condensed_node_can_trigger_static_asserts[
                    connected_component_index] = True

    template_defn_can_trigger_static_asserts = dict()
    for connected_component_index in condensed_graph:
        for template_defn_name in condensed_graph.node[
                connected_component_index]['members']:
            template_defn_can_trigger_static_asserts[
                template_defn_name] = condensed_node_can_trigger_static_asserts[
                    connected_component_index]

    return _apply_template_instantiation_can_trigger_static_asserts_info(
        header, template_defn_can_trigger_static_asserts)
예제 #42
0
def is_semiconnected(G):
    """Return True if the graph is semiconnected, False otherwise.

    A graph is semiconnected if, and only if, for any pair of nodes, either one
    is reachable from the other, or they are mutually reachable.

    Parameters
    ----------
    G : NetworkX graph
        A directed graph.

    Returns
    -------
    semiconnected : bool
        True if the graph is semiconnected, False otherwise.

    Raises
    ------
    NetworkXNotImplemented :
        If the input graph is undirected.

    NetworkXPointlessConcept :
        If the graph is empty.

    Examples
    --------
    >>> G=nx.path_graph(4,create_using=nx.DiGraph())
    >>> print(nx.is_semiconnected(G))
    True
    >>> G=nx.DiGraph([(1, 2), (3, 2)])
    >>> print(nx.is_semiconnected(G))
    False

    See Also
    --------
    is_strongly_connected
    is_weakly_connected
    is_connected
    is_biconnected
    """
    if len(G) == 0:
        raise nx.NetworkXPointlessConcept(
            'Connectivity is undefined for the null graph.')

    if not nx.is_weakly_connected(G):
        return False

    G = nx.condensation(G)
    path = nx.topological_sort(G)
    return all(G.has_edge(u, v) for u, v in pairwise(path))
예제 #43
0
 def test_contract_scc_edge(self):
     G = nx.DiGraph()
     G.add_edge(1, 2)
     G.add_edge(2, 1)
     G.add_edge(2, 3)
     G.add_edge(3, 4)
     G.add_edge(4, 3)
     scc = list(nx.strongly_connected_components(G))
     cG = nx.condensation(G, scc)
     assert_equal(sorted(cG.nodes()), [0, 1])
     if 1 in scc[0]:
         edge = (0, 1)
     else:
         edge = (1, 0)
     assert_equal(list(cG.edges()), [edge])
예제 #44
0
def build_analog_integration_blks(component):
    # Build the original dependance graph:
    graph = VisitorFindDirectSymbolDependance.build_direct_dependancy_graph(component)

    # Also, add in the RT graphs, that aren't direct dependents of anything, so
    # that the aprpriate AnalogIntegrationBlocks are created. (This might
    # emit events, but nothing else for example)
    for rt_graph in component.rt_graphs:
        if not rt_graph in graph:
            graph.add_node(rt_graph, label=repr(rt_graph), color='grey')


    # Plot:
    do_plot = True and False
    if do_plot:
        plot_networkx_graph(graph, show=False)
        plt.show()

    # Get the strongly connected components, and the dependancies between the
    # nodes:
    scc = nx.strongly_connected_components(graph)
    cond = nx.condensation(graph, scc=scc)


    #for node, node_data in cond.nodes_iter(data=True):
    #    print node, node_data


    ordering = reversed( nx.topological_sort(cond) )
    blks = []
    for o in ordering:
        objs = set(scc[0])
        blk_deps = set()
        for obj in scc[o]:
            o_deps = set(graph.successors(obj)) - objs
            blk_deps |= o_deps

        print blk_deps
        blk_deps = blk_deps - set(scc[o])
        blk = AnalogIntegrationBlock( objs = scc[o], dependancies=blk_deps )
        blks.append(blk)



    return blks
 def test_contract_scc1(self):
     G = nx.DiGraph()
     G.add_edges_from([(1,2),(2,3),(2,11),(2,12),(3,4),(4,3),(4,5),
                       (5,6),(6,5),(6,7),(7,8),(7,9),(7,10),(8,9),
                       (9,7),(10,6),(11,2),(11,4),(11,6),(12,6),(12,11)])
     cG = nx.condensation(G)
     # nodes
     assert_true((1,) in cG)
     assert_true((2,11,12) in cG)
     assert_true((3,4) in cG)
     assert_true((5,6,7,8,9,10) in cG)
     assert_true((2,11,12) in cG[(1,)])
     # edges
     assert_true((3,4) in cG[(2,11,12)])
     assert_true((5,6,7,8,9,10) in cG[(2,11,12)])
     assert_true((5,6,7,8,9,10) in cG[(3,4)])
     # DAG
     assert_true(nx.is_directed_acyclic_graph(cG))
 def test_contract_scc1(self):
     G = nx.DiGraph()
     G.add_edges_from(
         [
             (1, 2),
             (2, 3),
             (2, 11),
             (2, 12),
             (3, 4),
             (4, 3),
             (4, 5),
             (5, 6),
             (6, 5),
             (6, 7),
             (7, 8),
             (7, 9),
             (7, 10),
             (8, 9),
             (9, 7),
             (10, 6),
             (11, 2),
             (11, 4),
             (11, 6),
             (12, 6),
             (12, 11),
         ]
     )
     scc = list(nx.strongly_connected_components(G))
     cG = nx.condensation(G, scc)
     # DAG
     assert_true(nx.is_directed_acyclic_graph(cG))
     # nodes
     assert_equal(sorted(cG.nodes()), [0, 1, 2, 3])
     # edges
     mapping = {}
     for i, component in enumerate(scc):
         for n in component:
             mapping[n] = i
     edge = (mapping[2], mapping[3])
     assert_true(cG.has_edge(*edge))
     edge = (mapping[2], mapping[5])
     assert_true(cG.has_edge(*edge))
     edge = (mapping[3], mapping[5])
     assert_true(cG.has_edge(*edge))
예제 #47
0
    def test_condensation_as_quotient(self):
        """This tests that the condensation of a graph can be viewed as the
        quotient graph under the "in the same connected component" equivalence
        relation.

        """
        # This example graph comes from the file `test_strongly_connected.py`.
        G = nx.DiGraph()
        G.add_edges_from([(1, 2), (2, 3), (2, 11), (2, 12), (3, 4), (4, 3),
                          (4, 5), (5, 6), (6, 5), (6, 7), (7, 8), (7, 9),
                          (7, 10), (8, 9), (9, 7), (10, 6), (11, 2), (11, 4),
                          (11, 6), (12, 6), (12, 11)])
        scc = list(nx.strongly_connected_components(G))
        C = nx.condensation(G, scc)
        component_of = C.graph['mapping']
        # Two nodes are equivalent if they are in the same connected component.
        same_component = lambda u, v: component_of[u] == component_of[v]
        Q = nx.quotient_graph(G, same_component)
        assert_true(nx.is_isomorphic(C, Q))
예제 #48
0
파일: GML.py 프로젝트: hklarner/TomClass
def from_NXgraph(Graph, fname, verbose):
    if not fname[-4:]=='.gml':
        fname+='.gml'
    print 'Creating',fname+'..'
    
    attr = GraphTheory.attributes_components(Graph, verbose)
    NX.set_node_attributes(Graph, 'node_type', attr)
    attr = GraphTheory.attributes_interactions(Graph, verbose)
    NX.set_edge_attributes(Graph, 'edge_type', attr)
    
    sccs = NX.strongly_connected_components(Graph)
    condensation = NX.condensation(Graph, sccs)
    layout = NX.spring_layout(condensation, iterations=100, scale=1000)
    attr = {}
    
    for i,scc in enumerate(sccs):
        for node in scc:
            attr[node] = {'x':layout[i][0],'y':layout[i][1]}

    NX.set_node_attributes(Graph, 'graphics', attr)
    NX.write_gml(Graph, fname)
예제 #49
0
파일: srfs.py 프로젝트: wasserfeder/lomap
def compute_potentials(pa):
    '''Computes the potential function for each state of the product automaton.
    The potential function represents the minimum distance to a self-reachable
    final state in the product automaton.
    '''
    assert 'v' not in pa.g
    # add virtual node which connects to all initial states in the product
    pa.g.add_node('v')
    pa.g.add_edges_from([('v', p) for p in pa.init])
    # create strongly connected components of the product automaton w/ 'v'
    scc = list(nx.strongly_connected_components(pa.g))
    dag = nx.condensation(pa.g, scc)
    # get strongly connected component which contains 'v'
    for k, sc in enumerate(scc[::-1]):
        if 'v' in sc:
            start = len(scc) - k - 1
            break
    assert 'v' in scc[start]
    assert map(lambda sc: 'v' in sc, scc).count(True) == 1
    # get self-reachable final states
    pa.srfs = self_reachable_final_states_dag(pa, dag, scc, start)
    # remove virtual node from product automaton
    pa.g.remove_node('v')
    assert 'v' not in pa.g
    if not pa.srfs:
        return False
    # add artificial node 'v' and edges from the set of self reachable
    # states (pa.srfs) to 'v'
    pa.g.add_node('v')
    for p in pa.srfs:
        pa.g.add_edge(p, 'v', **{'weight': 0})
    # compute the potentials for each state of the product automaton
    lengths = nx.shortest_path_length(pa.g, target='v', weight='weight')
    for p in pa.g:
        pa.g.node[p]['potential'] = lengths[p]
    # remove virtual state 'v'
    pa.g.remove_node('v')
    return True
예제 #50
0
def basic_condenseg_process(_graph, sccs, dag_edges):
    condenseg = networkx.condensation(_graph, sccs)

    for edge in dag_edges:
        sscc_index = _graph.node[edge[0]]["scc_index"]
        escc_index = _graph.node[edge[1]]["scc_index"]

        condenseg.edge[sscc_index][escc_index].setdefault("condensed_edges", [])
        condenseg.edge[sscc_index][escc_index]["condensed_edges"].append(edge)


    # add fake finals (or I should do it on the original graph ??????????????????)
    final_sccs = set()
    for final in _graph.graph["finals"]:
        final_sccs.add(_graph.node[final]["scc_index"])
    final_sccs = list(final_sccs)
    condenseg.graph["final_sccs"] = final_sccs

    for final_scc in final_sccs:
        condenseg.add_edge(final_scc, str(final_scc)+"_final")
        condenseg.edge[final_scc][str(final_scc)+"_final"]["condensed_edges"] = []

    return condenseg, final_sccs
예제 #51
0
def all_node_cuts(G, k=None, flow_func=None):
    r"""Returns all minimum k cutsets of an undirected graph G. 

    This implementation is based on Kanevsky's algorithm [1]_ for finding all
    minimum-size node cut-sets of an undirected graph G; ie the set (or sets) 
    of nodes of cardinality equal to the node connectivity of G. Thus if 
    removed, would break G into two or more connected components.

    Parameters
    ----------
    G : NetworkX graph
        Undirected graph

    k : Integer
        Node connectivity of the input graph. If k is None, then it is 
        computed. Default value: None.

    flow_func : function
        Function to perform the underlying flow computations. Default value
        edmonds_karp. This function performs better in sparse graphs with
        right tailed degree distributions. shortest_augmenting_path will
        perform better in denser graphs.


    Returns
    -------
    cuts : a generator of node cutsets
        Each node cutset has cardinality equal to the node connectivity of
        the input graph.

    Examples
    --------
    >>> # A two-dimensional grid graph has 4 cutsets of cardinality 2
    >>> G = nx.grid_2d_graph(5, 5)
    >>> cutsets = list(nx.all_node_cuts(G))
    >>> len(cutsets)
    4
    >>> all(2 == len(cutset) for cutset in cutsets)
    True
    >>> nx.node_connectivity(G)
    2

    Notes
    -----
    This implementation is based on the sequential algorithm for finding all
    minimum-size separating vertex sets in a graph [1]_. The main idea is to
    compute minimum cuts using local maximum flow computations among a set 
    of nodes of highest degree and all other non-adjacent nodes in the Graph.
    Once we find a minimum cut, we add an edge between the high degree
    node and the target node of the local maximum flow computation to make 
    sure that we will not find that minimum cut again.

    See also
    --------
    node_connectivity
    edmonds_karp
    shortest_augmenting_path

    References
    ----------
    .. [1]  Kanevsky, A. (1993). Finding all minimum-size separating vertex 
            sets in a graph. Networks 23(6), 533--541.
            http://onlinelibrary.wiley.com/doi/10.1002/net.3230230604/abstract

    """
    if not nx.is_connected(G):
        raise nx.NetworkXError('Input graph is disconnected.')

    # Address some corner cases first.
    # For cycle graphs
    if G.order() == G.size():
        if all(2 == d for n, d in G.degree()):
            seen = set()
            for u in G:
                for v in nx.non_neighbors(G, u):
                    if (u, v) not in seen and (v, u) not in seen:
                        yield {v, u}
                        seen.add((v, u))
            return
    # For complete Graphs
    if nx.density(G) == 1:
        for cut_set in combinations(G, len(G) - 1):
            yield set(cut_set)
        return
    # Initialize data structures.
    # Keep track of the cuts already computed so we do not repeat them.
    seen = []
    # Even-Tarjan reduction is what we call auxiliary digraph
    # for node connectivity.
    H = build_auxiliary_node_connectivity(G)
    mapping = H.graph['mapping']
    R = build_residual_network(H, 'capacity')
    kwargs = dict(capacity='capacity', residual=R)
    # Define default flow function
    if flow_func is None:
        flow_func = default_flow_func
    if flow_func is shortest_augmenting_path:
        kwargs['two_phase'] = True
    # Begin the actual algorithm
    # step 1: Find node connectivity k of G
    if k is None:
        k = nx.node_connectivity(G, flow_func=flow_func)
    # step 2:
    # Find k nodes with top degree, call it X:
    X = {n for n, d in sorted(G.degree(), key=itemgetter(1), reverse=True)[:k]}
    # Check if X is a k-node-cutset
    if _is_separating_set(G, X):
        seen.append(X)
        yield X

    for x in X:
        # step 3: Compute local connectivity flow of x with all other
        # non adjacent nodes in G
        non_adjacent = set(G) - X - set(G[x])
        for v in non_adjacent:
            # step 4: compute maximum flow in an Even-Tarjan reduction H of G
            # and step:5 build the associated residual network R
            R = flow_func(H, '%sB' % mapping[x], '%sA' % mapping[v], **kwargs)
            flow_value = R.graph['flow_value']

            if flow_value == k:
                # Remove saturated edges form the residual network
                saturated_edges = [(u, w, d) for (u, w, d) in
                                   R.edges(data=True)
                                   if d['capacity'] == d['flow']]
                R.remove_edges_from(saturated_edges)
                # step 6: shrink the strongly connected components of
                # residual flow network R and call it L
                L = nx.condensation(R)
                cmap = L.graph['mapping']
                # step 7: Compute antichains of L; they map to closed sets in H
                # Any edge in H that links a closed set is part of a cutset
                for antichain in nx.antichains(L):
                    # Nodes in an antichain of the condensation graph of
                    # the residual network map to a closed set of nodes that
                    # define a node partition of the auxiliary digraph H.
                    S = {n for n, scc in cmap.items() if scc in antichain}
                    # Find the cutset that links the node partition (S,~S) in H
                    cutset = set()
                    for u in S:
                        cutset.update((u, w) for w in H[u] if w not in S)
                    # The edges in H that form the cutset are internal edges
                    # (ie edges that represent a node of the original graph G)
                    node_cut = {H.nodes[n]['id'] for edge in cutset for n in edge}

                    if len(node_cut) == k:
                        if node_cut not in seen:
                            yield node_cut
                            seen.append(node_cut)
                        # Add an edge (x, v) to make sure that we do not
                        # find this cutset again. This is equivalent
                        # of adding the edge in the input graph
                        # G.add_edge(x, v) and then regenerate H and R:
                        # Add edges to the auxiliary digraph.
                        H.add_edge('%sB' % mapping[x], '%sA' % mapping[v],
                                   capacity=1)
                        H.add_edge('%sB' % mapping[v], '%sA' % mapping[x],
                                   capacity=1)
                        # Add edges to the residual network.
                        R.add_edge('%sB' % mapping[x], '%sA' % mapping[v],
                                   capacity=1)
                        R.add_edge('%sA' % mapping[v], '%sB' % mapping[x],
                                   capacity=1)
                        break
                # Add again the saturated edges to reuse the residual network
                R.add_edges_from(saturated_edges)
예제 #52
0
def nx_transitive_reduction(G, mode=1):
    """
    References:
        https://en.wikipedia.org/wiki/Transitive_reduction#Computing_the_reduction_using_the_closure
        http://dept-info.labri.fr/~thibault/tmp/0201008.pdf
        http://stackoverflow.com/questions/17078696/im-trying-to-perform-the-transitive-reduction-of-directed-graph-in-python

    CommandLine:
        python -m utool.util_graph nx_transitive_reduction --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_graph import *  # NOQA
        >>> import utool as ut
        >>> import networkx as nx
        >>> G = nx.DiGraph([('a', 'b'), ('a', 'c'), ('a', 'e'),
        >>>                 ('a', 'd'), ('b', 'd'), ('c', 'e'),
        >>>                 ('d', 'e'), ('c', 'e'), ('c', 'd')])
        >>> G = testdata_graph()[1]
        >>> G_tr = nx_transitive_reduction(G, mode=1)
        >>> G_tr2 = nx_transitive_reduction(G, mode=1)
        >>> ut.quit_if_noshow()
        >>> import plottool as pt
        >>> G_ = nx.dag.transitive_closure(G)
        >>> pt.show_nx(G    , pnum=(1, 5, 1), fnum=1)
        >>> pt.show_nx(G_tr , pnum=(1, 5, 2), fnum=1)
        >>> pt.show_nx(G_tr2 , pnum=(1, 5, 3), fnum=1)
        >>> pt.show_nx(G_   , pnum=(1, 5, 4), fnum=1)
        >>> pt.show_nx(nx.dag.transitive_closure(G_tr), pnum=(1, 5, 5), fnum=1)
        >>> ut.show_if_requested()
    """

    import utool as ut
    import networkx as nx
    has_cycles = not nx.is_directed_acyclic_graph(G)
    if has_cycles:
        # FIXME: this does not work for cycle graphs.
        # Need to do algorithm on SCCs
        G_orig = G
        G = nx.condensation(G_orig)

    nodes = list(G.nodes())
    node2_idx = ut.make_index_lookup(nodes)

    # For each node u, perform DFS consider its set of (non-self) children C.
    # For each descendant v, of a node in C, remove any edge from u to v.

    if mode == 1:
        G_tr = G.copy()

        for parent in G_tr.nodes():
            # Remove self loops
            if G_tr.has_edge(parent, parent):
                G_tr.remove_edge(parent, parent)
            # For each child of the parent
            for child in list(G_tr.successors(parent)):
                # Preorder nodes includes its argument (no added complexity)
                for gchild in list(G_tr.successors(child)):
                    # Remove all edges from parent to non-child descendants
                    for descendant in nx.dfs_preorder_nodes(G_tr, gchild):
                        if G_tr.has_edge(parent, descendant):
                            G_tr.remove_edge(parent, descendant)

        if has_cycles:
            # Uncondense graph
            uncondensed_G_tr = G.__class__()
            mapping = G.graph['mapping']
            uncondensed_G_tr.add_nodes_from(mapping.keys())
            inv_mapping = ut.invert_dict(mapping, unique_vals=False)
            for u, v in G_tr.edges():
                u_ = inv_mapping[u][0]
                v_ = inv_mapping[v][0]
                uncondensed_G_tr.add_edge(u_, v_)

            for key, path in inv_mapping.items():
                if len(path) > 1:
                    directed_cycle = list(ut.itertwo(path, wrap=True))
                    uncondensed_G_tr.add_edges_from(directed_cycle)
            G_tr = uncondensed_G_tr

    else:

        def make_adj_matrix(G):
            edges = list(G.edges())
            edge2_idx = ut.partial(ut.dict_take, node2_idx)
            uv_list = ut.lmap(edge2_idx, edges)
            A = np.zeros((len(nodes), len(nodes)))
            A[tuple(np.array(uv_list).T)] = 1
            return A

        G_ = nx.dag.transitive_closure(G)

        A = make_adj_matrix(G)
        B = make_adj_matrix(G_)

        #AB = A * B
        #AB = A.T.dot(B)
        AB = A.dot(B)
        #AB = A.dot(B.T)

        A_and_notAB = np.logical_and(A, np.logical_not(AB))
        tr_uvs = np.where(A_and_notAB)

        #nodes = G.nodes()
        edges = list(zip(*ut.unflat_take(nodes, tr_uvs)))

        G_tr = G.__class__()
        G_tr.add_nodes_from(nodes)
        G_tr.add_edges_from(edges)

        if has_cycles:
            # Uncondense graph
            uncondensed_G_tr = G.__class__()
            mapping = G.graph['mapping']
            uncondensed_G_tr.add_nodes_from(mapping.keys())
            inv_mapping = ut.invert_dict(mapping, unique_vals=False)
            for u, v in G_tr.edges():
                u_ = inv_mapping[u][0]
                v_ = inv_mapping[v][0]
                uncondensed_G_tr.add_edge(u_, v_)

            for key, path in inv_mapping.items():
                if len(path) > 1:
                    directed_cycle = list(ut.itertwo(path, wrap=True))
                    uncondensed_G_tr.add_edges_from(directed_cycle)
            G_tr = uncondensed_G_tr
    return G_tr
예제 #53
0
def _generate_graph_list(Graph, s):
    """
    Generates the graph list from a given graph.
    """
    # Graph = nx.DiGraph()
    # 1.10 bug fix, remove any other root node can be...
    bfsy = nx.bfs_tree(Graph, s).nodes()
    if s not in bfsy:
        bfsy.append(s)
    for i in Graph.nodes():
        if i not in bfsy:
            Graph.remove_node(i)

    G = nx.condensation(Graph)

    l = nx.topological_sort(G)
    s = l[0]
    t = l[-1]

    # clear
    # assuming node 0 is the function root node.
    bfsy = nx.bfs_tree(G, s).nodes()
    if s not in bfsy:
        bfsy.append(s)
    for i in G.nodes():
        if i not in bfsy:
            G.remove_node(i)

    D = nx.copy.deepcopy(G)
    for edge in G.edges():
        D.remove_edge(edge[0], edge[1])
        D.add_edge(edge[1], edge[0])

    # assuming node 0 is the function root node.
    print D.nodes(), D.edges(), t
    bfsy = nx.bfs_tree(D, t).nodes()
    if t not in bfsy:
        bfsy.append(t)
    for i in G.nodes():
        if i not in bfsy:
            G.remove_node(i)

    G = expand(G, s, t)
    l = nx.topological_sort(G)

    topological_dict = {}
    for i in xrange(len(l)):
        topological_dict[l[i]] = i

    for edge in G.edges():
        G.edge[edge[0]][edge[1]]["capacity"] = 1

    zero_edges = get_all_zero_edges(G, s, t, topological_dict)

    zero_len = len(zero_edges)
    pair_array = []
    graph_array = []
    if zero_len > 0:
        pair_array.append((s, zero_edges[0][0]))
        for i in xrange(zero_len - 1):
            pair_array.append((zero_edges[i][1], zero_edges[i + 1][0]))
        pair_array.append((zero_edges[-1][1], t))

        for pair in pair_array:
            auxiliary = nx.copy.deepcopy(G)
            min_num_node = topological_dict[pair[0]]
            max_num_node = topological_dict[pair[1]]

            for node in auxiliary.nodes():
                if topological_dict[node] > max_num_node or topological_dict[node] < min_num_node:
                    auxiliary.remove_node(node)

            graph_array.append(_collapse(auxiliary))

    else:
        graph_array.append(_collapse(G))

    return graph_array
예제 #54
0
def build_event_blks(component, analog_blks):

    # Find out what the rt_graphs are dependant on: events & triggers:
    # =================================================================
    # 1. Make a map dependancies 'rt_graph -> state_variable/assignments'
    rt_graph_deps_triggers = defaultdict(set)
    dep_finder = VisitorFindDirectSymbolDependance()
    for tr in component._transitions_triggers:
        #print 'TRANSITION:', repr(tr)
        trigger_deps = dep_finder.visit(tr.trigger)
        for tdep in trigger_deps:
            if tdep.symbol != 't':
                rt_graph_deps_triggers[tr.rt_graph].add(tdep)

    # 2. Make a map dependancies 'rt_graph -> event_ports'
    rt_graph_deps_events = defaultdict(set)
    for tr in component._transitions_events:
        #print 'TRANSITION:', repr(tr)
        rt_graph_deps_events[tr.rt_graph].add(tr.port)

    # Find out what transitions particular state-variables
    # are dependant on because of assignments:
    # =========================================
    statevar_on_rt_deps= defaultdict(set)
    for tr in component.transitions:
        for action in tr.actions:
            if isinstance(action, ast.OnEventStateAssignment):
                statevar_on_rt_deps[action.lhs].add(tr.rt_graph)


    # OK, now lets build a new dependancy graph to work out transition/event
    # dependancies:
    # A. Start with the analog graph:
    graph = VisitorFindDirectSymbolDependance.build_direct_dependancy_graph(component)
    # B. Add the RT-graph nodes:
    for rt_graph in component._rt_graphs:
        graph.add_node(rt_graph, label=repr(rt_graph), color='orange')
    # C. Add the dependance of rt_graphs on trigger-conditions:
    for rt_graph, deps in rt_graph_deps_triggers.items():
        for dep in deps:
            graph.add_edge(rt_graph,dep,)
    # D. Add the dependance of state_varaibles on assignments in rt_graphs:
    for sv, deps in statevar_on_rt_deps.items():
        for dep in deps:
            graph.add_edge(sv,dep,)
    # E. Event Dependancies:
    #  -- (Use the src event ports as the 'objects' in the graph:
    for inp in component.input_event_port_lut:
        graph.add_node(inp, label=repr(inp), color='brown')
    for out in component.output_event_port_lut:
        graph.add_node(out, label=repr(out), color='chocolate')

    #Output events are dependant on their rt_graphs:
    for tr in component.transitions:
        for a in tr.actions:
            if isinstance(a, ast.EmitEvent ):
                graph.add_edge(a.port, tr.rt_graph)

    #  -- RT graph dependance on input events:
    for tr in component._transitions_events:
        # The RT graph depends on the incoming events:
        graph.add_edge(tr.rt_graph, tr.port )

    # -- Input ports can depend on output ports:
    for conn in component._event_port_connections:
        graph.add_edge(conn.dst_port, conn.src_port)









    statevar_on_rt_deps= defaultdict(set)

    do_plot=False
    if do_plot:
        plot_networkx_graph(graph, show=False)


    scc = nx.strongly_connected_components(graph)
    cond = nx.condensation(graph, scc=scc)

    #plot_networkx_graph(cond)
    plt.figure()
    nx.draw_graphviz(cond, font_size=10, iteration=200, )


    # Build a dictionary mapping each state_variable to analog block that its in:
    obj_to_analog_block = {}
    for blk in analog_blks:
        for obj in blk.objects:
            assert not obj in obj_to_analog_block
            obj_to_analog_block[obj] = blk

    ordering = reversed( nx.topological_sort(cond) )


    all_uncovered_blks = set()
    ev_blks = []
    print 'Event Block ordering:'
    print '====================='
    for o in ordering:
        print
        print ' ---- %d ---- ' % o
        print scc[o]
        #for obj in scc[o]:
        #    print ' -- ', obj,

        analog_blks = list(set( [obj_to_analog_block.get(obj,None) for obj in scc[o] ] ) )
        analog_blks = [blk for blk in analog_blks if blk is not None]
        print 'Analog Blocks:', len(analog_blks)

        # OK, whose not covered by the AnalogBlocks?
        covered_objs = set( list(chain(*[blk.objects for blk in analog_blks])) )
        uncovered_objs = set(scc[o]) - covered_objs
        uncovered_objs = set( [co for co in uncovered_objs if not isinstance(co, (ast.InEventPort,ast.OutEventPort))])
        if uncovered_objs:
            print 'UNcovered Objects:', uncovered_objs
            all_uncovered_blks |= uncovered_objs
            #assert False


        if analog_blks:
            ev = EventIntegrationBlock(analog_blks=analog_blks)
            ev_blks.append(ev)

    if all_uncovered_blks:
        print all_uncovered_blks
        assert False

    return ev_blks
예제 #55
0
    else:
        edge_list=strongly_connected_component_subgraphs_edges[i]
        edge_color=colors_of_edges[i]

        edge_alpha=edges_color_alpha[i]
        edge_width=edge_width_l[i]

        nx.draw(G,pos,nodelist=node_list,with_labels=True,node_size=500,edgelist=edge_list,edge_color=edge_color,width=edge_width,alpha=node_alpha,edgealpha=edge_alpha)
        nx.draw_networkx_nodes(G,pos,nodelist=nx.isolates(G),with_labels=True,node_size=500,node_color='w')
        # nx.draw_networkx_nodes(G,pos,nodelist=l0,with_labels=True,node_size=500,node_color='w')
        # nx.draw_networkx_nodes(G,pos,nodelist=N1,with_labels=True,node_size=500,node_color='r',alpha=0.3)
        nx.draw(G,pos,nodelist=N1,with_labels=True,node_size=500,node_color='r',alpha=0.3) #edge_color='k',
        # nx.draw(G,pos,nodelist=N1,edgelist=N1.edges(),with_labels=True,node_size=500,node_color='r',alpha=0.3)
# plt.savefig('foo2.png')

S=nx.condensation(G)
condensation_graph_relabeled=nx.relabel_nodes(S,graphs_labels,copy=True)
posS=nx.spring_layout(condensation_graph_relabeled,k=0.15,iterations=10)
# posS=layout(condensation_graph_relabeled)

# lvl=[]
# print condensation_graph_relabeled.nodes(),'ssssssss'
# for i in range(len(condensation_graph_relabeled.nodes())):
#     lvl.append(len(eval(condensation_graph_relabeled.nodes()[i])))
    # lvl.append(len(condensation_graph_relabeled.nodes()[i]))

# lvl2=[]
# for i in graphs_lists:
#     lvl2.append(len(graphs_lists[i]))

# print 'condensation_graph_relabeled nodes'
예제 #56
0
def defineMetabGroups(processedDataDir, level, taxonFile):

    # Obtain the groupList
    taxonClass = pd.DataFrame.from_csv(taxonFile, sep=',')
    taxonClass = taxonClass.dropna()
    
    # Extract the unique tribes found in the dataset
    if level=='Genome':
        groupList = list(taxonClass.index.values)
    else:   
        groupList = pd.unique(taxonClass[level].values)
        groupList.sort(axis=0)
        groupList = [ group for group in groupList if not group.startswith('Unknown') ]
        groupList = sorted(groupList, key=str.lower)
        
    for curDir in groupList:
        # Read in the clade-level network and compute its condensation
        myDiGraph = nx.read_adjlist('../'+processedDataDir+'/'+curDir+'/'+curDir+'RedAdjList.txt',
                                        create_using=nx.DiGraph())                            
    
        # Compute the list of SCCs for the digraph as well as its condensation
        myCondensation = nx.condensation(myDiGraph)    
       
       # Invert the mapping dictionary to map SCC nodes to their original compoundsm
        mapDict = dict()
        for key in myCondensation.graph.items()[0][1].keys():
            value = str(myCondensation.graph.items()[0][1][key])
            # If the value exists as a key in mapDict, append the new value
            if value in mapDict.keys():
                mapDict[value].append(str(key))
                # Otherwise create it
            else:
                mapDict[value] = [str(key)]
    
        # Compute the seed compounds                    
        seedSetList = []
        sccSeedSetList = []
        GCC = ''
        for node in myCondensation.nodes():
            inDeg = myCondensation.in_degree(node)
            # Check the in-degree. If 0, it's a seed.
            if inDeg == 0:
                seedSetList.append(mapDict[str(node)])
                sccSeedSetList.append(node)
            # The GCC has the highest in-degree. If the node has a higher in-degree,
            # is is the new GCC
            if len(GCC) == 0:
                GCC = str(node)
            if inDeg > myCondensation.in_degree(int(GCC)):
                GCC = str(node)
        # Flatten the list
        seedSetList = [seed for seedList in seedSetList for seed in seedList]
        
        # Identify the seed compounds which point to the GCC
        # Work with seeds in the SCC graph, then convert to compounds
        sccToGccList = []
        seedToGccList = []
        
        for node in sccSeedSetList:
            if int(GCC) in nx.all_neighbors(myCondensation, node):
                sccToGccList.append(node)
        for node in sccToGccList:
            seedToGccList.append(mapDict[str(node)])
        seedToGccList = [seed for seedList in seedToGccList for seed in seedList]
        
        # And those that don't
        remainingSeedList = [seed for seed in seedSetList if seed not in seedToGccList]
        
        # Write these lists to file
        with open('../'+processedDataDir+'/'+curDir+'/'+curDir+'seedsToGCC.txt', "w") as outFile:
            for seed in seedToGccList:
                outFile.write(seed+'\n')
        with open('../'+processedDataDir+'/'+curDir+'/'+curDir+'seedsToNotGCC.txt', "w") as outFile:
            for seed in remainingSeedList:
                outFile.write(seed+'\n')
    
        # Compute the sink compounds                    
        sinkSetList = []
        sccSinkSetList = []
        for node in myCondensation.nodes():
            outDeg = myCondensation.out_degree(node)
            # Check the in-degree. If 0, it's a seed.
            if outDeg == 0:
                sinkSetList.append(mapDict[str(node)])
                sccSinkSetList.append(node)
            # The GCC has the highest in-degree. If the node has a higher in-degree,
            # is is the new GCC
        # Flatten the list
        sinkSetList = [sink for sinkList in sinkSetList for sink in sinkList]
        
        # Identify the seed compounds which point to the GCC
        # Work with seeds in the SCC graph, then convert to compounds
        sccToGccList = []
        sinkToGccList = []
        
        for node in sccSinkSetList:
            if int(GCC) in nx.all_neighbors(myCondensation, node):
                sccToGccList.append(node)
        for node in sccToGccList:
            sinkToGccList.append(mapDict[str(node)])
        sinkToGccList = [sink for sinkList in sinkToGccList for sink in sinkList]
        
        # And those that don't
        remainingSinkList = [sink for sink in sinkSetList if sink not in sinkToGccList]
        
        # Write these lists to file
        with open('../'+processedDataDir+'/'+curDir+'/'+curDir+'sinkFromGCC.txt', "w") as outFile:
            for sink in sinkToGccList:
                outFile.write(sink+'\n')
        with open('../'+processedDataDir+'/'+curDir+'/'+curDir+'sinkFromNotGCC.txt', "w") as outFile:
            for sink in remainingSinkList:
                outFile.write(sink+'\n')
    
        # Identify the remaining metabolites and write to file
        remainingMetabList = [str(metab) for metab in myDiGraph.nodes()]
        remainingMetabList = [metab for metab in remainingMetabList if metab not in seedToGccList]
        remainingMetabList = [metab for metab in remainingMetabList if metab not in remainingSeedList]
        remainingMetabList = [metab for metab in remainingMetabList if metab not in sinkToGccList]
        remainingMetabList = [metab for metab in remainingMetabList if metab not in remainingSinkList]
        
        with open('../'+processedDataDir+'/'+curDir+'/'+curDir+'remainingMetabs.txt', "w") as outFile:
            for metab in remainingMetabList:
                outFile.write(metab+'\n')
    return
예제 #57
0
def visualize():
    """
    Lay out, style and write to disk the macrogenesis graphs.
    :return: list of pairs ``(link_text, relative_path)`` to the generated html pages
    """
    output_dir = faust.config.get("macrogenesis", "output-dir")
    # copy resources
    try:
        shutil.copytree('macrogenesis/resources/js', os.path.join(output_dir, 'js'))
    except OSError as e:
        logging.warn(e)


    #collect hyperlinks to selected graphs for the TOC as [(link_text_1, relative_link_to_file_1), ...]
    links = []

    # draw raw input data
    graph_imported = graph.import_graph()
    logging.info("Generating raw data graph.")
    #UUU write_agraph_layout(agraph_from(graph_imported), output_dir, '00_raw_data')

    # highlight a single node and its neighbors
    # highlighted_node = 'faust://document/wa/2_I_H.17'
    for highlighted_node in graph_imported:
        highlighted_bunch = list(networkx.all_neighbors(graph_imported, highlighted_node))
        highlighted_bunch.append(highlighted_node)
        graph_highlighted_subgraph = graph_imported.subgraph(nbunch=highlighted_bunch).copy()
        graph_highlighted_subgraph.node[highlighted_node][KEY_HIGHLIGHT]= VALUE_TRUE
        graph.insert_minimal_edges_from_absolute_datings(graph_highlighted_subgraph)

        #agraph_highlighted_subgraph.node_attr[highlighted_node]['color'] = 'red'
        _write_agraph_layout(_agraph_from(graph_highlighted_subgraph), output_dir,
                             _highlighted_base_filename(highlighted_node))
        # try again with edge labels, sometimes this genereats segfaults in dot, then there is the already
        # generated graph without edge labels already there
        try:
            _write_agraph_layout(_agraph_from(graph_highlighted_subgraph, edge_labels=True), output_dir,
                                 _highlighted_base_filename(highlighted_node))
        except Exception:
            logging.error("Dot failed generating a graph")


    # add relationships implicit in absolute datings
    logging.info("Generating graph with implicit absolute date relationships.")
    graph_absolute_edges = graph_imported
    graph.insert_minimal_edges_from_absolute_datings(graph_absolute_edges)
    del graph_imported
    base_filename_absolute_edges = '10_absolute_edges'
    _write_agraph_layout(_agraph_from(graph_absolute_edges), output_dir, base_filename_absolute_edges)
    links.append(('Raw datings (relative and absolute)', '%s.html' % base_filename_absolute_edges))
    # again with edge labels
    # TODO this breaks graphviz
    # agraph_absolute_edges_edge_labels = agraph_from(graph_absolute_edges, edge_labels=True)
    # write_agraph_layout(agraph_absolute_edges_edge_labels, output_dir, '15_absolute_edges_edge_labels')

    logging.info("Generating condensation.")
    strongly_connected_components = list(networkx.strongly_connected_components(graph_absolute_edges))

    #condensation
    graph_condensation = networkx.condensation(graph_absolute_edges, scc=strongly_connected_components)
    for node in graph_condensation:
        label = ', '.join([_label_from_uri(uri) for uri in graph_condensation.node[node]['members']])
        label_width = int(2 * math.sqrt(len(label)))
        graph_condensation.node[node]['label'] = textwrap.fill(label, label_width, break_long_words=False).replace('\n','\\n')
        component_filename_pattern = '16_strongly_connected_component_%i'
        # make a hyperlink to subgraph of the component
        if len(graph_condensation.node[node]['members']) > 1:
            _set_node_url(graph_condensation.node[node], component_filename_pattern % node)
        else:
            # TODO just link to normal neighborhood subgraph for single nodes
            pass

    base_filename_condensation = '15_condensation'
    _write_agraph_layout(_agraph_from(graph_condensation), output_dir, base_filename_condensation)
    links.append(('Condensation', '%s.html' % base_filename_condensation))

    for (component_index, component) in enumerate(strongly_connected_components):
        # don't generate subgraphs consisting of a single node
        if len(component) > 1:
            graph_component = graph_absolute_edges.subgraph(nbunch=component).copy()
            #macrogenesis.insert_minimal_edges_from_absolute_datings(graph_component)
            # , edge_labels=True)
            _write_agraph_layout(_agraph_from(graph_component), output_dir,
                                 component_filename_pattern % (component_index))

    # transitive closure, don't draw
    logging.info("Generating transitive closure graph.")
    transitive_closure = networkx.transitive_closure(graph_absolute_edges)
    logging.info("{0} nodes, {1} edges in transtive closure.".format(transitive_closure.number_of_nodes(),
                                                                     transitive_closure.number_of_edges()))
    agraph_transitive_closure = _agraph_from(transitive_closure)

    # draw transitive reduction
    logging.info("Generating transitive reduction graph.")
    agraph_transitive_reduction = agraph_transitive_closure.tred(copy=True)
    logging.info("{0} nodes, {1} edges in transtive reduction.".format(agraph_transitive_reduction.number_of_nodes(),
                                                                      agraph_transitive_reduction.number_of_edges()))
    base_filename_transitive_reduction = '30_transitive_reduction'
    _write_agraph_layout(agraph_transitive_reduction, output_dir, base_filename_transitive_reduction)
    links.append(('Transitive reduction', '%s.html' % base_filename_transitive_reduction))
    return links
예제 #58
0
def computeSeedSets(dirList, processedDataDir, seedDir):

    # Create lists to store seed sets
    # seedSetList is a list of lists. Each outer list contains all the seed sets
    # for that graph.
    seedSetList = []

    # Iterate over the list of genome directories. For each reduced digraph,
    # identify its condensation (SCCs). For each node of the SCC, check if it
    # is a seed set by computing its in-degree. If yes, append the SCC (as a list
    # of nodes) to the list of seed sets. Then compute some summary statistics.
    count = 0
    print 'Computing seed sets'

    for curDir in dirList:

        # Read in adjacency list and convert to digraph object
        myDiGraph = nx.read_adjlist(processedDataDir+'/'+curDir+'/'+curDir+'RedAdjList.txt',
                                create_using=nx.DiGraph())

        # Compute the list of SCCs for the digraph as well as its condensation
        myCondensation = nx.condensation(myDiGraph)
        nx.write_adjlist(myCondensation, processedDataDir+'/'+curDir+'/'+curDir+'SCCAdjList.txt')

        # For some reason, the condensation cannot be written to GraphML. Instead, re-read the
        # adjacency list and write that to GraphML.
        myTempGraph = nx.read_adjlist(processedDataDir+'/'+curDir+'/'+curDir+'SCCAdjList.txt',
                                create_using=nx.DiGraph())
        nx.write_graphml(myTempGraph, processedDataDir+'/'+curDir+'/'+curDir+'SCCGraph.xml')


        # Invert the mapping dictionary to map SCC nodes to their original compoundsm
        mapDict = dict()
        for key in myCondensation.graph.items()[0][1].keys():
            value = str(myCondensation.graph.items()[0][1][key])
            # If the value exists as a key in mapDict, append the new value
            if value in mapDict.keys():
                mapDict[value].append(str(key))
                # Otherwise create it
            else:
                mapDict[value] = [str(key)]

        dictFile=open(processedDataDir+'/'+curDir+'/'+curDir+'SCCDict.txt', "w")
        for key in mapDict.keys():
            dictFile.write(str(key)+',')
            dictFile.write(",".join(str(value) for value in mapDict[key]))
            dictFile.write('\n')
        dictFile.close()

        # "List of lists" of seed metabolites. Each element is a list of nodes belonging
        # to an SCC which is also a seed set.
        mySeeds = []

        # For each node (SCC) of the condensation, examine each its in-degree. If the
        # in-degree is zero (only outgoing edges), the SCC is a seed set. Append the
        # SCC (as a list of nodes) to the list of seed sets.
        for node in myCondensation.nodes():
            inDeg = myCondensation.in_degree(node)
            if inDeg == 0:
                mySeeds.append(mapDict[str(node)])
        seedSetList.append(mySeeds)

        # Update the list of seed metabolites: replace the Model SEED metabolite
        # identifier with its common name. Note: The file metabMap.csv was created
        # manually from the seed database, and should be updated to reflect the
        # particulars of your data set. As above, record the seed metabolite for each
        # graph.

        # First read metabMap.csv in as a dictionary
        with open(dataPath+'/metabMap.csv', mode='rU') as inFile:
            reader = csv.reader(inFile)
            namesDict = dict((rows[0],rows[1]) for rows in reader)

        # Compute weights for each seed metabolite and write to file. Each row of the
        # output file contains a metabolite and its weight (1 / size of the seed set).

        if not os.path.exists(seedDir+'/'+curDir):
            os.makedirs(seedDir+'/'+curDir)
        seedFile = open(seedDir+'/'+curDir+'/'+curDir+'SeedCompounds.txt', 'w')
        for seed in mySeeds:
            myWeight = 1 / float(len(seed))
            for metab in seed:
                seedFile.write('%s\t%s\t%f\n' % (metab, namesDict[re.sub('_[a-d]', '', metab)], myWeight) )
        seedFile.close()

        count = count + 1

    return seedSetList