Python networkx.descendants() Examples

The following are 19 code examples of networkx.descendants(). 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: deadlock_detector.py    From Ciw with MIT License 6 votes vote down vote up
def detect_deadlock(self):
        """
        Detects whether the system is in a deadlocked state,
        that is, is there a knot. Note that this code is taken
        and adapted from the NetworkX Developer Zone Ticket
        #663 knot.py (09/06/2015).
        """
        knots = []
        for c in nx.strongly_connected_components(self.statedigraph):
            subgraph = self.statedigraph.subgraph(c)
            nodes = set(subgraph.nodes())
            if len(nodes) == 1:
                n = nodes.pop()
                nodes.add(n)
                if set(self.statedigraph.successors(n)) == nodes:
                    knots.append(subgraph)
            else:
                for n in nodes:
                    successors = nx.descendants(self.statedigraph, n)
                    if successors <= nodes:
                        knots.append(subgraph)
                        break
        if len(knots) > 0:
            return True
        return False 
Example #2
Source File: function_flow.py    From Sark with MIT License 6 votes vote down vote up
def mark_not_reaching_nodes(ea, source_color=COLOR_SOURCE, other_color=COLOR_NOT_REACHING):
    graph = get_nx_graph(ea)
    graph = graph.reverse()
    block_ea = get_block_start(ea)
    reaching = nx.descendants(graph, block_ea)

    try:
        graph_nodes_iter = graph.nodes()
    except:
        graph_nodes_iter = graph.nodes_iter()

    for node_ea in graph_nodes_iter:
        if node_ea not in reaching:
            CodeBlock(node_ea).color = other_color

    CodeBlock(ea).color = source_color 
Example #3
Source File: test_highlevel.py    From tskit with MIT License 5 votes vote down vote up
def verify_nx_for_tutorial_algorithms(self, tree, g):
        # traversing upwards
        for u in tree.leaves():
            path = []
            v = u
            while v != tskit.NULL:
                path.append(v)
                v = tree.parent(v)

            self.assertSetEqual(set(path), {u} | nx.ancestors(g, u))
            self.assertEqual(
                path,
                [u] + [n1 for n1, n2, _ in nx.edge_dfs(g, u, orientation="reverse")],
            )

        # traversals with information
        def preorder_dist(tree, root):
            stack = [(root, 0)]
            while len(stack) > 0:
                u, distance = stack.pop()
                yield u, distance
                for v in tree.children(u):
                    stack.append((v, distance + 1))

        for root in tree.roots:
            self.assertDictEqual(
                {k: v for k, v in preorder_dist(tree, root)},
                nx.shortest_path_length(g, source=root),
            )

        for root in tree.roots:
            # new traversal: measuring time between root and MRCA
            for u, v in itertools.combinations(nx.descendants(g, root), 2):
                mrca = tree.mrca(u, v)
                tmrca = tree.time(mrca)
                self.assertAlmostEqual(
                    tree.time(root) - tmrca,
                    nx.shortest_path_length(
                        g, source=root, target=mrca, weight="branch_length"
                    ),
                ) 
Example #4
Source File: causal_graph.py    From dowhy with MIT License 5 votes vote down vote up
def get_instruments(self, treatment_nodes, outcome_nodes):
        treatment_nodes = parse_state(treatment_nodes)
        outcome_nodes = parse_state(outcome_nodes)
        parents_treatment = set()
        for node in treatment_nodes:
            parents_treatment = parents_treatment.union(self.get_parents(node))
        g_no_parents_treatment = self.do_surgery(treatment_nodes,
                                                 remove_incoming_edges=True)
        ancestors_outcome = set()
        for node in outcome_nodes:
            ancestors_outcome = ancestors_outcome.union(nx.ancestors(g_no_parents_treatment, node))

        # [TODO: double check these work with multivariate implementation:]
        # Exclusion
        candidate_instruments = parents_treatment.difference(ancestors_outcome)
        self.logger.debug("Candidate instruments after exclusion %s",
                          candidate_instruments)
        # As-if-random setup
        children_causes_outcome = [nx.descendants(g_no_parents_treatment, v)
                                   for v in ancestors_outcome]
        children_causes_outcome = set([item
                                       for sublist in children_causes_outcome
                                       for item in sublist])

        # As-if-random
        instruments = candidate_instruments.difference(children_causes_outcome)
        return list(instruments) 
Example #5
Source File: causal_graph.py    From dowhy with MIT License 5 votes vote down vote up
def get_descendants(self, node_name):
        return set(nx.descendants(self._graph, node_name)) 
Example #6
Source File: graph.py    From flo with MIT License 5 votes vote down vote up
def subgraph_needed_for(self, start_at, end_at):
        """Find the subgraph of all dependencies to run these tasks. Returns a
        new graph.
        """
        assert start_at or end_at, "one of {start_at,end_at} must be a task id"
        start, end = map(self.task_dict.get, [start_at, end_at])
        if None in [start, end]:
            graph = self.get_networkx_graph()
            if start:
                task_subset = nx.descendants(graph, start)
                task_subset.add(start)
            elif end:
                task_subset = nx.ancestors(graph, end)
                task_subset.add(end)
        elif start == end:
            task_subset = set([start])
        else:
            graph = self.get_networkx_graph()
            task_subset = set()
            for path in nx.all_simple_paths(graph, start, end):
                task_subset.update(path)

        # make sure the tasks are added to the subgraph in the same
        # order as the original configuration file
        tasks_kwargs_list = [task.yaml_data for task in self.task_list
                             if task in task_subset]
        subgraph = TaskGraph(self.config_path, tasks_kwargs_list)
        return subgraph 
Example #7
Source File: ontol.py    From ontobio with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def traverse_nodes(self, qids, up=True, down=False, **args):
        """
        Traverse (optionally) up and (optionally) down from an input set of nodes

        Arguments
        ---------
        qids : list[str]
            list of seed node IDs to start from
        up : bool
            if True, include ancestors
        down : bool
            if True, include descendants
        relations : list[str]
            list of relations used to filter

        Return
        ------
        list[str]
            nodes reachable from qids
        """
        g = self.get_filtered_graph(**args)
        nodes = set()
        for id in qids:
            # reflexive - always add self
            nodes.add(id)
            if down:
                nodes.update(nx.descendants(g, id))
            if up:
                nodes.update(nx.ancestors(g, id))
        return nodes 
Example #8
Source File: ontol.py    From ontobio with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def descendants(self, node, relations=None, reflexive=False):
        """
        Returns all descendants of specified node.

        The default implementation is to use networkx, but some
        implementations of the Ontology class may use a database or
        service backed implementation, for large graphs.


        Arguments
        ---------
        node : str
            identifier for node in ontology
        reflexive : bool
            if true, return query node in graph
        relations : list
             relation (object property) IDs used to filter

        Returns
        -------
        list[str]
            descendant node IDs
        """
        seen = set()
        nextnodes = [node]
        while len(nextnodes) > 0:
            nn = nextnodes.pop()
            if not nn in seen:
                seen.add(nn)
                nextnodes += self.children(nn, relations=relations)
        if not reflexive:
            seen -= {node}
        return list(seen) 
Example #9
Source File: rel_graph.py    From cloudify-dsl-parser with Apache License 2.0 5 votes vote down vote up
def _build_multi_instance_node_tree_rec(node_id,
                                        contained_tree,
                                        ctx,
                                        parent_relationship=None,
                                        parent_relationship_index=None,
                                        parent_node_instance_id=None,
                                        current_host_instance_id=None):
    node = contained_tree.node[node_id]['node']
    containers = _build_and_update_node_instances(
        ctx=ctx,
        node=node,
        parent_node_instance_id=parent_node_instance_id,
        parent_relationship=parent_relationship,
        current_host_instance_id=current_host_instance_id)
    for container in containers:
        node_instance = container.node_instance
        node_instance_id = node_instance['id']
        relationship_instance = container.relationship_instance
        new_current_host_instance_id = container.current_host_instance_id
        ctx.deployment_node_graph.add_node(node_instance_id,
                                           node=node_instance)
        if parent_node_instance_id is not None:
            ctx.deployment_node_graph.add_edge(
                node_instance_id, parent_node_instance_id,
                relationship=relationship_instance,
                index=parent_relationship_index)
        for child_node_id in contained_tree.neighbors_iter(node_id):
            descendants = nx.descendants(contained_tree, child_node_id)
            descendants.add(child_node_id)
            child_contained_tree = contained_tree.subgraph(descendants)
            _build_multi_instance_node_tree_rec(
                node_id=child_node_id,
                contained_tree=child_contained_tree,
                ctx=ctx,
                parent_relationship=ctx.plan_node_graph[
                    child_node_id][node_id]['relationship'],
                parent_relationship_index=ctx.plan_node_graph[
                    child_node_id][node_id]['index'],
                parent_node_instance_id=node_instance_id,
                current_host_instance_id=new_current_host_instance_id) 
Example #10
Source File: test_highlevel.py    From tskit with MIT License 5 votes vote down vote up
def verify_nx_algorithm_equivalence(self, tree, g):
        for root in tree.roots:
            self.assertTrue(nx.is_directed_acyclic_graph(g))

            # test descendants
            self.assertSetEqual(
                {u for u in tree.nodes() if tree.is_descendant(u, root)},
                set(nx.descendants(g, root)) | {root},
            )

            # test MRCA
            if tree.num_nodes < 20:
                for u, v in itertools.combinations(tree.nodes(), 2):
                    mrca = nx.lowest_common_ancestor(g, u, v)
                    if mrca is None:
                        mrca = -1
                    self.assertEqual(tree.mrca(u, v), mrca)

            # test node traversal modes
            self.assertEqual(
                list(tree.nodes(root=root, order="breadthfirst")),
                [root] + [v for u, v in nx.bfs_edges(g, root)],
            )
            self.assertEqual(
                list(tree.nodes(root=root, order="preorder")),
                list(nx.dfs_preorder_nodes(g, root)),
            ) 
Example #11
Source File: function_flow.py    From Sark with MIT License 5 votes vote down vote up
def mark_reachable_nodes(ea, source_color=COLOR_SOURCE, other_color=COLOR_REACHABLE):
    graph = get_nx_graph(ea)
    block_ea = get_block_start(ea)
    for descendant in nx.descendants(graph, block_ea):
        CodeBlock(descendant).color = other_color

    CodeBlock(ea).color = source_color 
Example #12
Source File: function_flow.py    From Sark with MIT License 5 votes vote down vote up
def mark_unreachable_nodes(ea, source_color=COLOR_SOURCE, other_color=COLOR_UNREACHABLE):
    graph = get_nx_graph(ea)
    block_ea = get_block_start(ea)
    descendants = nx.descendants(graph, block_ea)
    for block in FlowChart(ea):
        if block.start_ea not in descendants:
            block.color = other_color

    CodeBlock(ea).color = source_color 
Example #13
Source File: function_flow.py    From Sark with MIT License 5 votes vote down vote up
def mark_reaching_nodes(ea, source_color=COLOR_SOURCE, other_color=COLOR_REACHING):
    graph = get_nx_graph(ea)
    graph = graph.reverse()
    block_ea = get_block_start(ea)
    for descendant in nx.descendants(graph, block_ea):
        CodeBlock(descendant).color = other_color

    CodeBlock(ea).color = source_color 
Example #14
Source File: lca.py    From Sark with MIT License 5 votes vote down vote up
def OnClick(self, node_id):
        self.color_nodes()
        self._current_node_id = node_id
        node_ea = self[node_id]

        self._remove_target_handler.unregister()
        self._disable_source_handler.unregister()
        self._enable_source_handler.unregister()

        if node_ea in self._targets:
            self._remove_target_handler.register()
            self._attach_to_popup(self._remove_target_handler.get_name())

            for ea in nx.ancestors(self._lca_graph, node_ea):
                if ea not in self._targets and ea not in self._sources:
                    self._set_node_bg_color(self._node_ids[ea], COLOR_PATH)

        if node_ea in self._sources:
            if node_ea in self._disabled_sources:
                self._enable_source_handler.register()
                self._attach_to_popup(self._enable_source_handler.get_name())
            else:
                self._disable_source_handler.register()
                self._attach_to_popup(self._disable_source_handler.get_name())

                for ea in nx.descendants(self._lca_graph, node_ea):
                    if ea not in self._targets and ea not in self._sources:
                        self._set_node_bg_color(self._node_ids[ea], COLOR_PATH)

        return False 
Example #15
Source File: utg.py    From droidbot with MIT License 5 votes vote down vote up
def get_reachable_states(self, current_state):
        reachable_states = []
        for target_state_str in nx.descendants(self.G, current_state.state_str):
            target_state = self.G.nodes[target_state_str]["state"]
            reachable_states.append(target_state)
        return reachable_states 
Example #16
Source File: parser.py    From cloudify-dsl-parser with Apache License 2.0 5 votes vote down vote up
def descendants(self, element):
        return nx.descendants(self._element_tree, element) 
Example #17
Source File: simulation.py    From Mathematics-of-Epidemics-on-Networks with MIT License 4 votes vote down vote up
def _out_component_(G, source):
    '''
    rather than following the pseudocode in figure 6.15 of 
        Kiss, Miller & Simon,
    this uses a built-in Networkx command.  

    finds the set of nodes (including source) which are reachable from 
    nodes in source.

    :Arguments: 

    **G**  networkx Graph
        The network the disease will transmit through.
    **source** either a node or an iterable of nodes (set, list, tuple)
        The nodes from which the infections start.  We assume no node
        will ever have a name that is an iterable of other node names.
        It will run, but may not use source user expects.


    :Returns: 
                  
    **reachable_nodes** set
        the set of nodes reachable from source (including source).

    :Warning: 
    if the graph G has nodes like 1, 2, 3, and (1,2,3), then a
    source of (1,2,3) is potentially ambiguous.  This algorithm will interpret
    the source as the single node (1,2,3)


    '''
    if G.has_node(source): 
        source_nodes = {source}
    else:
        source_nodes = set(source)
        
    reachable_nodes = set().union(source_nodes)

    for node in source_nodes:
        reachable_nodes = reachable_nodes.union(
                                        set(nx.descendants(G, node)))

    
    return reachable_nodes 
Example #18
Source File: urdf.py    From scikit-robot with MIT License 4 votes vote down vote up
def _validate_graph(self):
        """Raise an exception if the link-joint structure is invalid.

        Checks for the following:

        - The graph is connected in the undirected sense.
        - The graph is acyclic in the directed sense.
        - The graph has only one base link.

        Returns
        -------
        base_link : :class:`.Link`
            The base link of the URDF.
        end_links : list of :class:`.Link`
            The end links of the URDF.
        """

        # Check that the link graph is weakly connected
        if not nx.is_weakly_connected(self._G):
            link_clusters = []
            for cc in nx.weakly_connected_components(self._G):
                cluster = []
                for n in cc:
                    cluster.append(n.name)
                link_clusters.append(cluster)
            message = ('Links are not all connected. '
                       'Connected components are:')
            for lc in link_clusters:
                message += '\n\t'
                for n in lc:
                    message += ' {}'.format(n)
            raise ValueError(message)

        # Check that link graph is acyclic
        if not nx.is_directed_acyclic_graph(self._G):
            raise ValueError('There are cycles in the link graph')

        # Ensure that there is exactly one base link, which has no parent
        base_link = None
        end_links = []
        for n in self._G:
            if len(nx.descendants(self._G, n)) == 0:
                if base_link is None:
                    base_link = n
                else:
                    raise ValueError('Links {} and {} are both base links!'
                                     .format(n.name, base_link.name))
            if len(nx.ancestors(self._G, n)) == 0:
                end_links.append(n)
        return base_link, end_links 
Example #19
Source File: urdf.py    From urdfpy with MIT License 4 votes vote down vote up
def _validate_graph(self):
        """Raise an exception if the link-joint structure is invalid.

        Checks for the following:

        - The graph is connected in the undirected sense.
        - The graph is acyclic in the directed sense.
        - The graph has only one base link.

        Returns
        -------
        base_link : :class:`.Link`
            The base link of the URDF.
        end_links : list of :class:`.Link`
            The end links of the URDF.
        """

        # Check that the link graph is weakly connected
        if not nx.is_weakly_connected(self._G):
            link_clusters = []
            for cc in nx.weakly_connected_components(self._G):
                cluster = []
                for n in cc:
                    cluster.append(n.name)
                link_clusters.append(cluster)
            message = ('Links are not all connected. '
                       'Connected components are:')
            for lc in link_clusters:
                message += '\n\t'
                for n in lc:
                    message += ' {}'.format(n)
            raise ValueError(message)

        # Check that link graph is acyclic
        if not nx.is_directed_acyclic_graph(self._G):
            raise ValueError('There are cycles in the link graph')

        # Ensure that there is exactly one base link, which has no parent
        base_link = None
        end_links = []
        for n in self._G:
            if len(nx.descendants(self._G, n)) == 0:
                if base_link is None:
                    base_link = n
                else:
                    raise ValueError('Links {} and {} are both base links!'
                                     .format(n.name, base_link.name))
            if len(nx.ancestors(self._G, n)) == 0:
                end_links.append(n)
        return base_link, end_links