Пример #1
0
def test_disconnected_graph():
    # https://github.com/networkx/networkx/issues/1144
    G = nx.Graph()
    G.add_edges_from([(0, 1), (1, 2), (2, 0), (3, 4)])
    assert_false(nx.is_tree(G))

    G = nx.DiGraph()
    G.add_edges_from([(0, 1), (1, 2), (2, 0), (3, 4)])
    assert_false(nx.is_tree(G))
Пример #2
0
 def add_edge(self, u, v):
     print('[euler_tour_forest] add_edge(%r, %r)' % (u, v))
     if self.has_edge(u, v):
         return
     ru = self.find_root(u)
     rv = self.find_root(v)
     if ru is None:
         self.add_node(u)
         ru = u
     if rv is None:
         self.add_node(v)
         rv = v
     assert ru is not rv, (
         'u=%r, v=%r not disjoint, can only join disjoint edges' % (u, v))
     assert ru in self.trees, 'ru must be a root node'
     assert rv in self.trees, 'rv must be a root node'
     subtree1 = self.trees[ru]
     subtree2 = self.trees[rv]
     del self.trees[rv]
     new_tree = nx.compose(subtree1, subtree2)
     new_tree.add_edge(u, v)
     self.trees[ru] = new_tree
     print(list(new_tree.nodes()))
     assert nx.is_connected(new_tree)
     assert nx.is_tree(new_tree)
Пример #3
0
def euler_tour(G, node=None, seen=None, visited=None):
    """
    definition from
    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.192.8615&rep=rep1&type=pdf

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.experimental.euler_tour_tree_avl import *  # NOQA
        >>> edges = [
        >>>     ('R', 'A'), ('R', 'B'),
        >>>     ('B', 'C'), ('C', 'D'), ('C', 'E'),
        >>>     ('B', 'F'), ('B', 'G'),
        >>> ]
        >>> G = nx.Graph(edges)
        >>> node = list(G.nodes())[0]
        >>> et1 = euler_tour(G, node)
        >>> et2 = euler_tour_dfs(G, node)
    """
    if node is None:
        node = next(G.nodes())
    if visited is None:
        assert nx.is_tree(G)
        visited = []
    if seen is None:
        seen = set([])
    visited.append(node)
    for c in G.neighbors(node):
        if c in seen:
            continue
        seen.add(c)
        euler_tour(G, c, seen, visited)
        visited.append(node)
    return visited
Пример #4
0
def question4(T, node1, node2):
    BSTG=nx.from_numpy_matrix(np.matrix(T))
    if (nx.is_tree(BSTG) & check_sum(T)):
        path = nx.all_simple_paths(BSTG, node1,  node2)
        return min(list(path)[0])
    else:
        print ("This graph is not a binary search tree")
        return None 
Пример #5
0
def inspectlabels(milestone,sent):
    for h,d in sent.edges():
        if type(sent[h][d]['deprel']) == str:
            pass
        else:
            print(milestone,"ARLAMA",sent)
    if not nx.is_tree(sent):
        print("not tree")
Пример #6
0
 def span_makes_subtree(self, initidx, endidx):
     G = nx.DiGraph()
     span_nodes = list(range(initidx,endidx+1))
     span_words = [self.node[x]["form"] for x in span_nodes]
     G.add_nodes_from(span_nodes)
     for h,d in self.edges():
         if h in span_nodes and d in span_nodes:
             G.add_edge(h,d)
     return nx.is_tree(G)
Пример #7
0
 def test_default_flow_function_karate_club_graph(self):
     G = nx.karate_club_graph()
     nx.set_edge_attributes(G, 1, 'capacity')
     T = nx.gomory_hu_tree(G)
     assert_true(nx.is_tree(T))
     for u, v in combinations(G, 2):
         cut_value, edge = self.minimum_edge_weight(T, u, v)
         assert_equal(nx.minimum_cut_value(G, u, v),
                      cut_value)
Пример #8
0
 def test_karate_club_graph_cutset(self):
     G = nx.karate_club_graph()
     nx.set_edge_attributes(G, 1, 'capacity')
     T = nx.gomory_hu_tree(G)
     assert_true(nx.is_tree(T))
     u, v = 0, 33
     cut_value, edge = self.minimum_edge_weight(T, u, v)
     cutset = self.compute_cutset(G, T, edge)
     assert_equal(cut_value, len(cutset))
Пример #9
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Check that G is a tree
        if not nx.is_tree(self.G):
            raise ValueError(
                f"G is not a tree with edges {self.edges}. "
                "If a tree is not required, use the generic TaskGraph class."
            )
Пример #10
0
    def to_tree(cls, node: nx.DiGraph, ctx):
        """Check graph structure and build nested dictionary."""
        if not nx.is_tree(node):  # no cycles, single tree
            raise ValueError("Graph must represent a tree.")

        keep_uuid = getattr(node, "_wx_keep_uuid_name", False)

        root = build_tree(node, tuple(node.nodes)[0], keep_uuid=keep_uuid)
        return dict(root_node=root)
Пример #11
0
def _tree_layout(
    G: nx.classes.graph.Graph,
    root_vertex: Union[Hashable, None],
    scale: float,
) -> dict:
    result = {root_vertex: np.array([0, 0, 0])}

    if not nx.is_tree(G):
        raise ValueError("The tree layout must be used with trees")
    if root_vertex is None:
        raise ValueError("The tree layout requires the root_vertex parameter")

    def _recursive_position_for_row(
        G: nx.classes.graph.Graph,
        result: dict,
        two_rows_before: List[Hashable],
        last_row: List[Hashable],
        current_height: float,
    ):
        new_row = []
        for v in last_row:
            for x in G.neighbors(v):
                if x not in two_rows_before:
                    new_row.append(x)

        new_row_length = len(new_row)

        if new_row_length == 0:
            return

        if new_row_length == 1:
            result[new_row[0]] = np.array([0, current_height, 0])
        else:
            for i in range(new_row_length):
                result[new_row[i]] = np.array(
                    [-1 + 2 * i / (new_row_length - 1), current_height, 0]
                )

        _recursive_position_for_row(
            G,
            result,
            two_rows_before=last_row,
            last_row=new_row,
            current_height=current_height + 1,
        )

    _recursive_position_for_row(
        G, result, two_rows_before=[], last_row=[root_vertex], current_height=1
    )

    height = max(map(lambda v: result[v][1], result))

    return {
        v: np.array([pos[0], 1 - 2 * pos[1] / height, pos[2]]) * scale / 2
        for v, pos in result.items()
    }
Пример #12
0
def hierarchy_pos(G,
                  root=None,
                  width=1.,
                  vert_gap=0.2,
                  vert_loc=0,
                  xcenter=0.5):
    if not nx.is_tree(G):
        raise TypeError(
            'cannot use hierarchy_pos on a graph that is not a tree')

    if root is None:
        if isinstance(G, nx.DiGraph):
            root = next(iter(nx.topological_sort(
                G)))  #allows back compatibility with nx version 1.11
        else:
            root = random.choice(list(G.nodes))

    def _hierarchy_pos(G,
                       root,
                       width=1.,
                       vert_gap=0.2,
                       vert_loc=0,
                       xcenter=0.5,
                       pos=None,
                       parent=None):
        '''
        see hierarchy_pos docstring for most arguments

        pos: a dict saying where all nodes go if they have been assigned
        parent: parent of this branch. - only affects it if non-directed

        '''

        if pos is None:
            pos = {root: (xcenter, vert_loc)}
        else:
            pos[root] = (xcenter, vert_loc)
        children = list(G.neighbors(root))
        if not isinstance(G, nx.DiGraph) and parent is not None:
            children.remove(parent)
        if len(children) != 0:
            dx = width / len(children)
            nextx = xcenter - width / 2 - dx / 2
            for child in children:
                nextx += dx
                pos = _hierarchy_pos(G,
                                     child,
                                     width=dx,
                                     vert_gap=vert_gap,
                                     vert_loc=vert_loc - vert_gap,
                                     xcenter=nextx,
                                     pos=pos,
                                     parent=root)
        return pos

    return _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)
Пример #13
0
 def test_les_miserables_graph_cutset(self):
     G = nx.les_miserables_graph()
     nx.set_edge_attributes(G, 1, 'capacity')
     for flow_func in flow_funcs:
         T = nx.gomory_hu_tree(G, flow_func=flow_func)
         assert_true(nx.is_tree(T))
         for u, v in combinations(G, 2):
             cut_value, edge = self.minimum_edge_weight(T, u, v)
             assert_equal(nx.minimum_cut_value(G, u, v),
                          cut_value)
Пример #14
0
def tree_or_forest(graph):
    if nx.is_tree(graph):
        print(
            "The Minimum Spanning Tree Generated from this Network is a Tree")
    elif nx.is_forest(graph):
        print(
            "The Minimum Spanning Tree Generated from this Network is a Forest"
        )
    else:
        print("Neither a Tree nor Forest")
Пример #15
0
 def test_davis_southern_women_graph(self):
     G = nx.davis_southern_women_graph()
     nx.set_edge_attributes(G, 'capacity', 1)
     for flow_func in flow_funcs:
         T = nx.gomory_hu_tree(G, flow_func=flow_func)
         assert_true(nx.is_tree(T))
         for u, v in combinations(G, 2):
             cut_value, edge = self.minimum_edge_weight(T, u, v)
             assert_equal(nx.minimum_cut_value(G, u, v),
                          cut_value)
Пример #16
0
 def test_florentine_families_graph(self):
     G = nx.florentine_families_graph()
     nx.set_edge_attributes(G, 1, 'capacity')
     for flow_func in flow_funcs:
         T = nx.gomory_hu_tree(G, flow_func=flow_func)
         assert_true(nx.is_tree(T))
         for u, v in combinations(G, 2):
             cut_value, edge = self.minimum_edge_weight(T, u, v)
             assert_equal(nx.minimum_cut_value(G, u, v),
                          cut_value)
Пример #17
0
def orient_junction_tree(t: nx.Graph):
    """Make oriented Junction tree out of an unoriented Junction tree,
    preserving node and edge informations"""
    assert nx.is_tree(t), "Graph must have tree structure"
    oriented = nx.bfs_tree(t, list(t.nodes)[0])
    for n in oriented.nodes:
        oriented.node[n].update(t.node[n])
    for e in oriented.edges:
        oriented[e[0]][e[1]].update(t[e[0]][e[1]])
    return oriented 
Пример #18
0
 def _validate_graph(self, graph):
     """Private: Validate a graph is suitable for visualizer."""
     if not issubclass(type(graph), ScaffoldGraph):
         raise ValueError(f'{graph} must be a subclass of ScaffoldGraph')
     if self._requires_tree:
         if not nx.is_tree(graph) or nx.is_forest(graph):
             msg = '{} requires a tree/forest structured graph'
             msg.format(self.__class__.__name__)
             raise ValueError(msg)
     return graph
Пример #19
0
def test_random_DAG():
    import networkx as nx
    # import matplotlib.pyplot as plt
    # from networkx.drawing.nx_pydot import graphviz_layout
    con_pattern = lambda imax: min(int(exponential(5)), imax - 1)
    for i in range(5, 50):
        W = random_DAG(i)
        G = nx.convert_matrix.from_numpy_matrix(W, parallel_edges=False, create_using=nx.DiGraph)
        assert nx.is_directed_acyclic_graph(G), "G must be a DAG!"
        assert nx.is_tree(G), "G must be a tree!"
Пример #20
0
 def test_florentine_families_graph(self):
     G = nx.florentine_families_graph()
     nx.set_edge_attributes(G, 'capacity', 1)
     for flow_func in flow_funcs:
         T = nx.gomory_hu_tree(G, flow_func=flow_func)
         assert_true(nx.is_tree(T))
         for u, v in combinations(G, 2):
             cut_value, edge = self.minimum_edge_weight(T, u, v)
             assert_equal(nx.minimum_cut_value(G, u, v),
                          cut_value)
Пример #21
0
def main():
    args = read_arguments()
    filename = args.filename
    nodes = {}
    edges = {}
    actors = {}
    roots = []
    digraph = nx.DiGraph()
    doc_title = filename.replace('.ann', '')
    with open(filename, 'r') as file_:
        for line in file_:
            if line.startswith('T'):
                name, label, text = line.split('\t')[:3]
                nodes[name] = {'label': label.split(' ')[0], 'text': text}
                digraph.add_node(name, {
                    'label': label.split(' ')[0],
                    'text': text
                })
                if 'major-claim' in label:
                    roots.append(name)
            elif line.startswith('R'):
                name, label = line.split('\t')[:2]
                label, destination, origin = label.split(' ')
                origin = origin.replace('Arg2:', '')
                destination = destination.replace('Arg1:', '')
                edges[name] = {
                    'label': label,
                    'origin': origin,
                    'destination': destination
                }
                digraph.add_edge(origin, destination, {'label': label})
            elif line.startswith('A'):
                _, attribute_name, source, attribute_value = line.split()
                if attribute_name == 'ACTOR':
                    actors[source] = attribute_value
    nx.set_node_attributes(digraph, 'actor', actors)
    data = {'name': doc_title.replace('_', ' '), 'children': []}
    # Transform digraph into a forest using the major-claims as tree roots.
    for root in roots:
        descendants = nx.descendants(digraph, root)
        descendants.add(root)
        subgraph = digraph.subgraph(descendants)
        if not nx.is_tree(subgraph):
            print('Subgraph that is not a tree founded')
            continue
        data['children'].append(
            json_graph.tree_data(subgraph,
                                 root=root,
                                 attrs={
                                     'children': 'children',
                                     'id': 'name',
                                     'actor': 'actor'
                                 }))
    with open('{}.json'.format(doc_title), 'w') as jf:
        json.dump(data, jf)
Пример #22
0
    def coverage_BFS_single_source(self, infectG, subInfectG, source_ture):
        # 进行所有点有向树构建,再进行层次遍历。针对每一层都进行传播点/全部的比例计算。
        node_every_ratio = []
        for node_every in list(subInfectG.nodes()):
            #进行BFS树构造,
            tree = nx.bfs_tree(infectG, source=node_every)
            #进行层次遍历。返回每一层顶点。
            BFS_nodes = commons.BFS_nodes(tree, node_every, infectG)
            ratio_all = 0
            for layer_node in BFS_nodes:
                infect_node_len = len(
                    [x for x in layer_node if infectG.node[x]['SI'] == 2])
                # print('infect_node_len',infect_node_len)
                infect_node_not = len(
                    [x for x in layer_node if infectG.node[x]['SI'] == 1])
                # print('infect_node_not', infect_node_not)
                infect_ratio = infect_node_len / len(layer_node)  #感染点的比例
                ratio_all += infect_ratio
            ratio_average = ratio_all / len(BFS_nodes)
            node_every_ratio.append([node_every, ratio_average])

        node_every_ratio_sort = sorted(node_every_ratio,
                                       key=lambda x: x[1],
                                       reverse=True)
        print(node_every_ratio_sort)

        print(
            'distacne',
            nx.shortest_path_length(infectG,
                                    source=node_every_ratio_sort[0][0],
                                    target=source_ture))
        #以第一个点进行BFS树构建,然后单源定位。

        # plot_main. plot_G_node_color(subInfectG,[1])(infectG, subInfectG, source_ture, [node_every_ratio_sort[0][0]])
        print('isTree,', nx.is_tree(subInfectG))
        subinfectG = nx.bfs_tree(subInfectG,
                                 source=node_every_ratio_sort[0][0])
        print('isTree,', nx.is_tree(subinfectG))
        count_number = 0
        undirectG = subinfectG.to_undirected()
        result_node = self.revsitionAlgorithm_singlueSource(undirectG)
        return result_node
Пример #23
0
    def _validate_hierachy(self, hierarchy) -> None:
        """
        Validate active hierarchy returned for the cause_set_id.

        Some of our cause hierarchies are not true trees.
        They can have more than one root node and each node may have more
        than one parent. For these reasons we can't use traditional methods
        for tree recognition and validation for all the hierarchies and 
        must create our own suite of validations to confirm the fitness of 
        the hierarchies used in the machinery run.

        This method creates a networkx digraph from the cause hierarchy
        dataframe and uses it to check for duplicates and validate tree
        structure for hierarchies other than the reporting aggregates
        hierarchy.

        The digraph may become more useful as validations are added or we can
        get rid of it entirely.
        """
        G = nx.DiGraph()
        errors = ""
        for index, row in hierarchy.iterrows():
            if row.cause_id == row.parent_id and row.level == 0:
                continue
            parent_df = (hierarchy.loc[hierarchy.cause_id == row.parent_id])
            if len(parent_df) > 1 or G.has_edge(row.parent_id, row.cause_id):
                errors += (f'Duplicates found for cause_id {row.cause_id}, '
                           f'parent_id {row.parent_id}.\n')
            elif parent_df.empty:
                errors += (
                    f'The hierarchy is missing information for parent_id '
                    f'{row.parent_id}.\n')
            else:
                parent_level = parent_df.level.iat[0]
                edge_weight = row.level - parent_level
                G.add_edge(u_of_edge=row.parent_id,
                           v_of_edge=row.cause_id,
                           weight=edge_weight)
                if edge_weight != 1:
                    errors += (
                        f'A child cause should be 1 level below its parent. '
                        f'parent_id {row.parent_id} has level {parent_level}. '
                        f'cause_id {row.cause_id} has level {row.level}.\n')
        if (self.set_id != constants.CauseSetId.REPORTING_AGGREGATES
                and not nx.is_tree(G)):
            errors += ('The hierarchy is not a tree. nx.is_tree() '
                       'returned False\n')

        if errors:
            msg = (f"There are issues with the hierarchy for cause_set_id "
                   f"{self.set_id}, cause_set_version_id "
                   f"{self.set_version_id}\n{errors}")
            logging.error(msg)
            raise RuntimeError(msg)
Пример #24
0
def is_valid_network(G, T):
    """
    Checks whether T is a valid network of G.
    Args:
        G: networkx.Graph
        T: networkx.Graph

    Returns:
        bool: whether T is a valid network
    """
    return nx.is_tree(T) and nx.is_dominating_set(G, T.nodes)
Пример #25
0
def tree_stats(graphs):
    '''
  Tree Stats will return a dict containing
  1. ratio of valid trees
  2. depth distribution
  '''

    total_graphs = len(graphs)
    total_trees = sum(1 for g in graphs if nx.is_tree(g))

    total_dags = sum(1 for g in graphs if nx.is_directed_acyclic_graph(g))
    longest_path = [
        nx.dag_longest_path_length(g) for g in graphs if nx.is_tree(g)
    ]

    return {
        'istree_ratio': total_trees / total_graphs,
        'dag_ratio': total_dags / total_graphs,
        'longest_path': longest_path
    }
Пример #26
0
def is_path(g):
    # we know it's connected
    leaves = 0
    for nd in g.nodes():
        if g.degree(nd) == 1:
            leaves += 1
        elif g.degree(nd) != 2:
            return False
        if leaves > 2:
            return False
    return nx.is_tree(g) and leaves == 2
    def fit(self, X, y=None, sample_weight=None):
        """Fit underlying classifiers.

        Parameters
        ----------
        X : (sparse) array-like, shape = [n_samples, n_features]
            Data.

        y : (sparse) array-like, shape = [n_samples, ], [n_samples, n_classes]
            Multi-class targets. An indicator matrix turns on multilabel
            classification.

        sample_weight : array-like, shape (n_samples,), optional (default=None)
            Weights applied to individual samples (1. for unweighted).

        Returns
        -------
        self

        """
        X, y = check_X_y(X, y, accept_sparse='csr')
        check_classification_targets(y)
        if sample_weight is not None:
            check_consistent_length(y, sample_weight)

        # Check that parameter assignment is consistent
        self._check_parameters()

        # Initialize NetworkX Graph from input class hierarchy
        self.class_hierarchy_ = self.class_hierarchy or make_flat_hierarchy(
            list(np.unique(y)), root=self.root)
        self.graph_ = DiGraph(self.class_hierarchy_)
        self.is_tree_ = is_tree(self.graph_)
        self.classes_ = list(node for node in self.graph_.nodes()
                             if node != self.root)
        self.logger.debug("fit() - self.classes_ = %s", self.classes_)

        # Recursively build training feature sets for each node in graph
        with self._progress(total=self.n_classes_ + 1,
                            desc="Building features") as progress:
            self._recursive_build_features(X,
                                           y,
                                           node_id=self.root,
                                           progress=progress)

        # Recursively train base classifiers
        with self._progress(total=self.n_classes_ + 1,
                            desc="Training base classifiers") as progress:
            self._recursive_train_local_classifiers(X,
                                                    y,
                                                    node_id=self.root,
                                                    progress=progress)

        return self
Пример #28
0
def main():
    import pprint
    droid = Droid("../assets/day15-input")
    g, m = spread(droid, ' ')

    oxygen_location = next(coords for coords, t in m.items() if t == 'O')
    path = nx.shortest_path(g, source=(0, 0), target=oxygen_location)
    print("part 1:", len(path) - 1)
    t = nx.bfs_tree(g, source=oxygen_location)
    assert nx.is_tree(t)
    print("part 2:", tree_height(t, oxygen_location) - 1)
Пример #29
0
    def compute_graph(self, skel, location_attr="loc", connectivity=26):
        sz = self.image.shape

        mask = self.image_labeled * 0
        if skel.shape[0] == 0:
            return None

        mask[skel[:, 0], skel[:, 1], skel[:, 2]] = 1
        locs_flattened = skel[:, 0] * sz[0] * sz[1] + skel[:,
                                                           1] * sz[0] + skel[:,
                                                                             2]
        sorted_idxs = np.argsort(locs_flattened)
        coords_sorted = skel[sorted_idxs, :]
        graph = grid_to_graph(
            self.image.shape[0],
            self.image.shape[1],
            self.image.shape[2],
            mask=mask,
            connectivity=connectivity,
        )
        g = GeometricGraph()
        nodes = [(
            node_id,
            {
                location_attr: coord,
                "intensity": self.image_int[coord[0], coord[1], coord[2]],
            },
        ) for node_id, coord in enumerate(coords_sorted)]

        g.add_nodes_from(nodes)

        edges = [(a, b) for a, b in zip(graph.row, graph.col) if a > b]
        g.add_edges_from(edges)

        if not nx.is_tree(g):
            g.remove_cycles()
            print("*Converted to Tree?**")
            print(nx.is_tree(g))
            print(len(g.nodes))

        return g
Пример #30
0
    def test_tree_with_integration_test(swarm_with_tree):
        try:
            swarm_with_tree.run()
        except:
            hashes = swarm_with_tree.tree.hash_to_ids
            epoch = swarm_with_tree.epoch
            raise ValueError("%s epoch: %s" % (hashes, epoch))
        assert networkx.is_tree(swarm_with_tree.tree.data)

        best_ix = swarm_with_tree.walkers.states.cum_rewards.argmax()
        best_id = swarm_with_tree.walkers.states.id_walkers[best_ix]
        path = swarm_with_tree.tree.get_branch(best_id, from_hash=True)
Пример #31
0
    def hierarchy_pos(self,
                      root=0,
                      width=1.0,
                      vert_gap=0.2,
                      vert_loc=0,
                      xcenter=0.5):
        """compute abstract node positions of the tree
        From Joel's answer at https://stackoverflow.com/a/29597209/2966723.  
        Licensed under Creative Commons Attribution-Share Alike 
        """
        G = self.nxgraph
        if not nx.is_tree(G):
            # raise TypeError("cannot use hierarchy_pos on a graph that is not a tree")
            self.pos2d = nx.kamada_kawai_layout(G)
            return

        def _hierarchy_pos(
            G,
            root,
            width=1.0,
            vert_gap=0.2,
            vert_loc=0,
            xcenter=0.5,
            pos=None,
            parent=None,
        ):
            if pos is None:
                pos = {root: (xcenter, vert_loc)}
            else:
                pos[root] = (xcenter, vert_loc)
            children = list(G.neighbors(root))
            if not isinstance(G, nx.DiGraph) and parent is not None:
                children.remove(parent)
            if len(children) != 0:
                dx = width / len(children)
                nextx = xcenter - width / 2 - dx / 2
                for child in children:
                    nextx += dx
                    pos = _hierarchy_pos(
                        G,
                        child,
                        width=dx,
                        vert_gap=vert_gap,
                        vert_loc=vert_loc - vert_gap,
                        xcenter=nextx,
                        pos=pos,
                        parent=root,
                    )
            return pos

        self.pos2d = _hierarchy_pos(G, root, width, vert_gap, vert_loc,
                                    xcenter)
Пример #32
0
    def hierarchy_pos(self):
        '''
        Modification of Joel's answer at https://stackoverflow.com/a/29597209/2966723.  
        Licensed under Creative Commons Attribution-Share Alike 

        If the graph is a tree this will return the positions to plot this in a 
        hierarchical layout.
        
        Returns a dictionary with the hierarchy positions for a vertical tree or a horizontal tree.
        '''

        if not nx.is_tree(self.G): #NODES NAMES MUST BE ALL DIFFERENT or else it won't create a tree
            raise TypeError('cannot use hierarchy_pos on a graph that is not a tree') 

        if self.root is None:
            if isinstance(self.G, nx.DiGraph):
                self.root = next(iter(nx.topological_sort(self.G)))  #allows back compatibility with nx version 1.11
            else:
                self.root = random.choice(list(self.G.nodes))

        def _hierarchy_pos(G, root, spread, gap, root_x, root_y, pos=None, parent=None):

            if pos is None:
                pos = {root:(root_x, root_y)}
            else:
                pos[root] = (root_x, root_y)
            children = list(G.neighbors(root))
            if not isinstance(G, nx.DiGraph) and parent is not None:
                children.remove(parent)  
            if len(children)!=0:
                sp = spread/len(children) #sp divides the spread by all children
                nextxV = root_x - spread/2 - sp/2
                nextxH = root_y + spread/2 + sp/2
                for child in children:
                    if self.orientation == 'v':
                        nextxV += sp #Next horizontal position for a Vertical graph
                        pos = _hierarchy_pos(G,child, spread=sp, gap=gap, 
                                            root_x=nextxV,root_y=root_y-gap,
                                            pos=pos, parent = root)
                    elif self.orientation == 'h':
                        nextxH -= sp #Next horizontal position for a Horizontal graph
                        pos = _hierarchy_pos(G,child, spread=sp, gap=gap, 
                                             root_y=nextxH,root_x=root_x+gap,
                                             pos=pos, parent = root)
                    else:
                        raise Exception("Not a valid command for variable orientation! \n\
                        A string is needed with the value 'v' for a vertical graph (top-down) or \n\
                        value 'h' for horizontal graph (left-right). Default is 'v'.")
            return pos

        return _hierarchy_pos(self.G, self.root, self.spread, self.gap, 
                              self.root_x, self.root_y, self.pos, self.parent)
Пример #33
0
def verify_decomp(g, decomp, width, length):
    sys.stderr.write("\nChecking decomposition\n")
    sys.stderr.flush()
    if not nx.is_tree(decomp):
        raise Exception("Decomposition is not tree")
    if set(decomp.nodes(data=True)[0][1]['component']) != set(g.nodes()):
        s = str(set(g.nodes()) - set(decomp.nodes(data=True)[0][1]['component']))
        raise Exception("All nodes are not covered" + s)
    for curr in decomp.nodes():
        tor = len(decomp[curr])
        vertices = set()
        children = len(decomp[curr])
        component = set(decomp.nodes(data=True)[curr][1]['component'])
        for node in decomp[curr]:
            # print decomp.nodes(data=True)[node][1]
            # exit(0)
            nodecomp = set(decomp.nodes(data=True)[node][1]['component'])
            if not nodecomp <= component:
                s = "Parent node missing vertices " + str(nodecomp) + str(component)
                raise Exception(s)
            vertices = vertices.union(nodecomp)
            for node1 in decomp[curr]:
                if node1 == node:
                    continue
                node1comp = set(decomp.nodes(data=True)[node1][1]['component'])
                if node1comp & nodecomp:
                    s = 'Appearing in multiple branches ' + str(node1comp) + str(nodecomp)
                    raise Exception(s)

        if decomp.nodes(data=True)[curr][1]['level'] < length-1:
            if len(set(component) - vertices) + len(decomp[curr]) + 1 > width:
                raise Exception("Higher torso size for bag %i than width %i" % (curr, width))
        elif len(set(component) - vertices) + len(decomp[curr]) > width:
            raise Exception("Higher torso size for bag %i than width %i" % (curr, width))
        incident_edges = list()
        for e in g.edges(list(vertices)):
            if not (e[0] in component and e[1] in component):
                incident_edges.append(e)
                # try:
                #     incident_edges.remove(e)
                #     sys.stderr.write("\ndeleted edge %s\n"%str(e))
                # except:
                #     try:
                #         incident_edges.remove((e[1],e[0]))
                #         sys.stderr.write("\ndeleted edge %s\n" % str(e[1],e[0]))
                #     except:
                #         sys.stderr.write("\nskipped edge %s\n"%str(e))
                #         pass
        if len(incident_edges) > width:
            raise Exception("Higher adhesion than width")
    sys.stderr.write("Correct decomposition\n")
    sys.stderr.flush()
Пример #34
0
    def _checkTree(self, checkTree, graph):
        """
        Raises an AssertionError if the DFS tree is not actually a tree. As
        we add all nodes from the original graph in the tree during initialization,
        this test fails when the tree is not an acyclic connected graph.
        """
        if not checkTree:
            return

        for n in self._tree:
            assert self._tree.nodes[n]['visited']
        
        assert nx.is_tree(self._tree)
Пример #35
0
def is_tree(request):
    """Function for determination is graph tree or no

    This function is getting a graph and response:
    "1" -- it is a tree,
    "0" -- it is not a tree.
    """
    raw_data = request.GET.dict()
    graph_data = json.loads(raw_data["graph"])
    matrix = np.matrix(cn.to_matrix(graph_data))
    graph = create_graph(matrix, graph_data)
    data = {"result": int(nx.is_tree(graph))}
    return JsonResponse(data)
Пример #36
0
    def make_tree(self, ast: nx.DiGraph, root=None):
        if root is None:
            assert nx.is_tree(ast)
            for node in ast.nodes:
                if not list(ast.predecessors(node)):
                    root = node
                    break

        assert root is not None

        return self._make_tree(
            root, ast
        )
Пример #37
0
def pairwise_dists(G):
    '''
    Given adjacency matrix A,
    Return:
        D: np array with same shape as A,
           s.t. D[i, j] is shortest distance from i to j
    '''
    if nx.is_tree(G):
        yield from pairwise_tree_distance(G)
    else:
        for s, tdt in nx.all_pairs_dijkstra_path_length(G).items():
            for t, dt in tdt.items():
                yield (s, t), dt
Пример #38
0
    def stamp_and_approve(self):
        '''Mandatory method to validate and seal the execution tree such that
        it can be enacted by an agent

        Raises
        ------
        ValueError
            If the execution units do not form a tree

        '''
        if not nx.is_tree(self.tree):
            raise ValueError('The plan graph is not structured like a tree')
        self.tree_root_id = self._get_root_index(self.tree)
Пример #39
0
    def tree(self):
        rslt = {}
        rslt['is_tree'] = nx.is_tree(self.graph)
        rslt['is_forest'] = nx.is_forest(self.graph)

        if self.directed == 'directed':
            rslt['is_arborescence'] = nx.is_arborescence(self.graph)
            rslt['is_branching'] = nx.is_branching(self.graph)

        fname_tree = self.DIR + '/tree.json'
        with open(fname_tree, "w") as f:
            json.dump(rslt, f, cls=SetEncoder, indent=2)
        print(fname_tree)
Пример #40
0
def hierarchy_pos(G,
                  root=None,
                  width=.5,
                  vert_gap=0.2,
                  vert_loc=0,
                  xcenter=0.5):
    '''
    From Joel's answer at https://stackoverflow.com/a/29597209/2966723.  
    '''
    if not nx.is_tree(G):
        raise TypeError(
            'cannot use hierarchy_pos on a graph that is not a tree')

    if root is None:
        if isinstance(G, nx.DiGraph):
            root = next(iter(nx.topological_sort(
                G)))  #allows back compatibility with nx version 1.11
        else:
            root = random.choice(list(G.nodes))

    def _hierarchy_pos(G,
                       root,
                       width=1.,
                       vert_gap=0.2,
                       vert_loc=0,
                       xcenter=0.5,
                       pos=None,
                       parent=None):
        if pos is None:
            pos = {root: (xcenter, vert_loc)}
        else:
            pos[root] = (xcenter, vert_loc)
        children = list(G.neighbors(root))
        if not isinstance(G, nx.DiGraph) and parent is not None:
            children.remove(parent)
        if len(children) != 0:
            dx = width / len(children)
            nextx = xcenter - width / 2 - dx / 2
            for child in children:
                nextx += dx
                pos = _hierarchy_pos(G,
                                     child,
                                     width=dx,
                                     vert_gap=vert_gap,
                                     vert_loc=vert_loc - vert_gap,
                                     xcenter=nextx,
                                     pos=pos,
                                     parent=root)
        return pos

    return _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)
Пример #41
0
 def default(self, obj):
     if isinstance(obj, np.ndarray):
         return obj.tolist()
     elif isinstance(obj, np.generic):
         return obj.item()
     elif isinstance(obj, nx.Graph) or isinstance(obj, nx.DiGraph):
         if nx.is_tree(obj):
             # NOTE: the root must be the first node added. otherwise it won't work
             return json_graph.tree_data(obj, obj.nodes_iter().next())
         else:
             return json_graph.node_link_data(obj)
     elif isinstance(obj, pd.DataFrame):
         return obj.to_dict(orient='records')
     return json.JSONEncoder.default(self, obj)
Пример #42
0
def _graphml2nx(fname):
	g=nx.DiGraph()
	def _attrdict(node):
		attrs=node.attributes()
		return {key:attrs[key].value for key in attrs if key not in attr_blacklist}
	parser=GraphMLParser()
	imported_graph=parser.parse(fname)
	edges=[(edge.node1.id, edge.node2.id) for edge in imported_graph.edges()]
	nodes=[(node.id, _attrdict(node)) for node in imported_graph.nodes()]
	g.add_edges_from(edges)
	g.add_nodes_from(nodes)
	assert(nx.is_tree(g))
	assert(nx.is_directed(g))
	return g
Пример #43
0
 def default(self, obj):
     if isinstance(obj, np.ndarray):
         return obj.tolist()
     elif isinstance(obj, np.generic):
         return obj.item()
     elif isinstance(obj, nx.Graph) or isinstance(obj, nx.DiGraph):
         if nx.is_tree(obj) and 'root' in obj.graph:
             # NOTE: there must be a root graph attribute, or the root must be the first node added.
             # otherwise it won't work
             return json_graph.tree_data(obj, obj.graph['root'])
         else:
             return json_graph.node_link_data(obj)
     elif isinstance(obj, pd.DataFrame):
         return obj.to_dict(orient='records')
     return json.JSONEncoder.default(self, obj)
Пример #44
0
 def test_wikipedia_example(self):
     # Example from https://en.wikipedia.org/wiki/Gomory%E2%80%93Hu_tree
     G = nx.Graph()
     G.add_weighted_edges_from((
         (0, 1, 1), (0, 2, 7), (1, 2, 1),
         (1, 3, 3), (1, 4, 2), (2, 4, 4),
         (3, 4, 1), (3, 5, 6), (4, 5, 2),
     ))
     for flow_func in flow_funcs:
         T = nx.gomory_hu_tree(G, capacity='weight', flow_func=flow_func)
         assert_true(nx.is_tree(T))
         for u, v in combinations(G, 2):
             cut_value, edge = self.minimum_edge_weight(T, u, v)
             assert_equal(nx.minimum_cut_value(G, u, v, capacity='weight'),
                          cut_value)
Пример #45
0
def check_spanning_tree(tree):
    '''Check that a graph is a spanning tree.
    Parameters
    ----------
    tree : networkx graph
    '''
    nodes = np.array(tree.nodes())
    n_nodes = len(nodes)
    edges = np.array(tree.edges())
    n_edges = len(edges)
    # check number of edges
    if not n_nodes - 1 == n_edges:
        raise ValueError('Incorrect number of edes in graph.')
    # check that graph is a tree
    if not nx.is_tree(tree):
        raise TypeError('Must input a tree.')    
Пример #46
0
def modif_free_mwe_labels(sent,most_common_label_filler):
    for h,d in sent.edges():
        if sent[h][d]["deprel"] in freemwes:
            head_over_mwe = sent.head_of(h)
            overall_mwe_function = sent[head_over_mwe][h]['deprel']
            if type(overall_mwe_function) == str:
                if "_" in overall_mwe_function or overall_mwe_function.startswith("mwe"):
                    pass
                else:
                    sent[h][d]["deprel"] = sent[h][d]["deprel"]+"_rmwe_"+most_common_label_filler[overall_mwe_function]
            else:
                #pass
                print("MUCHO WRONG",h,d,overall_mwe_function)
                print(sent, sent.edges(),nx.is_tree(sent))

    return sent
Пример #47
0
def to_dict_tree(digraph, root):
    import networkx as nx
    """
    Convert a networkx.DiGraph to a tree.
    (king, (governor,(editor,)), (state,(collapse,),(head,)(lord,)))
    """
    assert nx.is_tree(digraph)
    str2node = {root: []}
    for parent, child in nx.traversal.dfs_edges(digraph, root):
        score = digraph.edge[parent][child]['score']
        childnode = {child: [], 'score': score}
        children = str2node[parent]
        children.append(childnode)
        str2node[child] = childnode[child]

    return {root: str2node[root]}
Пример #48
0
def optimal_placement(tree, budget):
    """
    Place `budget` sensors on a tree in an optimal way.

    Parameters
    ----------
    tree : networkx.Graph
        A tree (undirected) on which to place the sensors.
    budget : int
        The sensor budget, i.e. the number of nodes that can be chosen as
        sensors

    Returns
    -------
    (perr, obs) : tuple
        `perr` is the error probability, and `obs` a tuple containing the
        sensors.
    """ 
    
    #one single sensor is useless
    assert budget >= 2

    assert nx.is_tree(tree)

    leaves = utilities.find_leaves(tree)
    if budget >= len(leaves):
        return (0, tuple(leaves))

    #define a non-leaf root arbitrarily
    root = random.choice(filter(lambda x: x not in leaves, tree.nodes()))
    directed = nx.dfs_tree(tree, source=root) #dir DFS tree from source

    #compute the subtree sizes
    for x in directed:
        directed.node[x]['size'] = utilities.size_subtree(directed, x)
    utilities.size_subtree.cache_clear()
    
    #add the budget and the root to the tree as an attribute
    directed.graph['root'] = root
    directed.graph['budget'] = budget
    
    #place the sensors using the DP algorithm
    err, obs = _opt(directed, root, budget)
    _optc.cache_clear()
    _opt.cache_clear()
    
    return (float(err) / len(tree), obs)
Пример #49
0
def is_forest(G):
    """Return True if the input graph is a forest

    Parameters
    ----------
    G : NetworkX Graph
       An undirected graph.

    Returns
    -------
    True if the input graph is a forest

    Notes
    -----
    For undirected graphs only.
    """
    for graph in nx.connected_component_subgraphs(G):
        if not nx.is_tree(graph):
            return False
    return True
Пример #50
0
 def test_is_tree(self):
     assert_true(nx.is_tree(self.T2))
     assert_true(nx.is_tree(self.T3))
     assert_true(nx.is_tree(self.T5))
Пример #51
0
def find_root(G):
    """Returns root node ID for the Graph."""
    if not nx.is_tree(G):
        return None
    return nx.topological_sort(G)[0]
Пример #52
0
    def _keep_fused_form(self,posPreferenceDicts):
        # For a span A,B  and external tokens C, such as  A > B > C, we have to
        # Make A the head of the span
        # Attach C-level tokens to A
        #Remove B-level tokens, which are the subtokens of the fused form della: de la

        if self.graph["multi_tokens"] == {}:
            return

        spanheads = []
        spanhead_fused_token_dict = {}
        # This double iteration is overkill, one could skip the spanhead identification
        # but in this way we avoid modifying the tree as we read it
        for fusedform_idx in sorted(self.graph["multi_tokens"]):
            fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"]
            fuseform_span = list(range(fusedform_start,fusedform_end+1))
            spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts)
            #if not spanhead:
            #    spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts)
            spanheads.append(spanhead)
            spanhead_fused_token_dict[spanhead] = fusedform_idx

        bottom_up_order = [x for x in nx.topological_sort(self) if x in spanheads]
        for spanhead in bottom_up_order:
            fusedform_idx = spanhead_fused_token_dict[spanhead]
            fusedform = self.graph["multi_tokens"][fusedform_idx]["form"]
            fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"]
            fuseform_span = list(range(fusedform_start,fusedform_end+1))

            if spanhead:
                #Step 1: Replace form of head span (A)  with fusedtoken form  -- in this way we keep the lemma and features if any
                self.node[spanhead]["form"] = fusedform
                # 2-  Reattach C-level (external dependents) to A
                #print(fuseform_span,spanhead)

                internal_dependents = set(fuseform_span) - set([spanhead])
                external_dependents = [nx.bfs_successors(self,x) for x in internal_dependents]
                for depdict in external_dependents:
                    for localhead in depdict:
                        for ext_dep in depdict[localhead]:
                            deprel = self[localhead][ext_dep]["deprel"]
                            self.remove_edge(localhead,ext_dep)
                            self.add_edge(spanhead,ext_dep,deprel=deprel)

                #3- Remove B-level tokens
                for int_dep in internal_dependents:
                    self.remove_edge(self.head_of(int_dep),int_dep)
                    self.remove_node(int_dep)

        #4 reconstruct tree at the very end
        new_index_dict = {}
        for new_node_index, old_node_idex in enumerate(sorted(self.nodes())):
            new_index_dict[old_node_idex] = new_node_index

        T = DependencyTree() # Transfer DiGraph, to replace self

        for n in sorted(self.nodes()):
            T.add_node(new_index_dict[n],self.node[n])

        for h, d in self.edges():
            T.add_edge(new_index_dict[h],new_index_dict[d],deprel=self[h][d]["deprel"])
        #4A Quick removal of edges and nodes
        self.__init__()

        #4B Rewriting the Deptree in Self
        # TODO There must a more elegant way to rewrite self -- self= T for instance?
        for n in sorted(T.nodes()):
            self.add_node(n,T.node[n])

        for h,d in T.edges():
            self.add_edge(h,d,T[h][d])

        # 5. remove all fused forms form the multi_tokens field
        self.graph["multi_tokens"] = {}

        if not nx.is_tree(self):
            print("Not a tree after fused-form heuristics:",self.get_sentence_as_string())
Пример #53
0
 def from_dict(self, data):
   # Check that the dict has the expected keys
   if not criros.utils.has_keys(data, ['nodes','properties','root','title']):
     self.logger.logdebug('Dict does not have the expected keys')
     return False
   # Create a graph and check that it's a tree
   graph = nx.DiGraph()
   nodes = dict()
   blacklist = []
   # Process the nodes
   for identifier, spec in data['nodes'].items():
     # Get the children of the current node
     if spec.has_key('child'):
       self.children[identifier].append(spec['child'])
     elif spec.has_key('children'):
       self.children[identifier] = spec['children']
     # Check spec has the expected fields
     if not criros.utils.has_keys(spec, ['id','name','properties','title']):
       self.logger.logdebug( 'Node [{0}] does not have the expected keys'.format(identifier) )
       blacklist += self.children[identifier]
       continue
     # Check soundness
     if identifier != spec['id']:
       self.logger.logdebug( 'Identifier miss-match {0} != {1}'.format(identifier, spec['id']) )
       blacklist += self.children[identifier]
       continue
     # Skip blacklisted nodes
     if identifier in blacklist:
       self.logger.logdebug( 'Skiping blacklisted node {0}:{1}'.format(spec['title'], identifier) )
       blacklist += self.children[identifier]
       continue
     # Get node class and initialize it
     nodeclass = get_class_from_str(spec['name'])
     if nodeclass is None:
       self.logger.logdebug( 'Node {0}:{1} has unknown node class: {2}'.format(spec['title'], identifier, spec['name']) )
       blacklist += self.children[identifier]
       continue
     if behave.core.Action not in inspect.getmro(nodeclass):
       self.logger.logdebug( 'Node {0}:{1} has invalid node class: {2}'.format(spec['title'], identifier, spec['name']) )
       self.logger.logdebug( 'It must inherit from any of these: (Action, Composite, Decorator)' )
       blacklist += self.children[identifier]
       continue
     nodes[identifier] = nodeclass(identifier, title=spec['title'], properties=spec['properties'])
     # Populate the graph
     for child in self.children[identifier]:
       graph.add_edge(identifier, child)
   if len(graph) == 0:
     self.logger.logdebug( 'Failed parsing dict. Empty graph' )
     return False
   if not nx.is_tree(graph):
     self.logger.logdebug( 'Failed parsing dict. Graph must be a tree' )
     return False
   for identifier in nodes.keys():
     # Add the children for the nodes that were created
     for child_id in self.children[identifier]:
       if child_id in nodes.keys():
         # Depending on the type of class we add children or specify the child
         if    behave.core.Composite in inspect.getmro( type(nodes[identifier]) ):
           nodes[identifier].add_child( nodes[child_id] )
         elif  behave.core.Decorator in inspect.getmro( type(nodes[identifier]) ):
           nodes[identifier].set_child( nodes[child_id] )
         else:
           self.logger.logdebug( 'Node {0}:{1} has invalid node class: {2}'.format(spec['title'], identifier, spec['name']) )
           self.logger.logdebug( 'To have children it must inherit from any of these: (Composite, Decorator)' )
     # Store details in self.graph as well
     graph.node[identifier] = data['nodes'][identifier]['properties']
     graph.node[identifier]['children'] = self.children[identifier]
     graph.node[identifier]['class'] = nodes[identifier].name
     graph.node[identifier]['category'] = nodes[identifier].category
     graph.node[identifier]['title'] = nodes[identifier].title
     graph.node[identifier]['label'] = nodes[identifier].label
     graph.node[identifier]['shape'] = nodes[identifier].shape
   # Set-up the class
   if data.has_key('id'):
     self.identifier = data['id']
   self.root = data['root']
   self.graph = graph
   self.nodes = nodes
   self.initialized = True
   return True
Пример #54
0
def test_dag_nontree():
    G = nx.DiGraph()
    G.add_edges_from([(0,1), (0,2), (1,2)])
    assert_false(nx.is_tree(G))
    assert_true(nx.is_directed_acyclic_graph(G))
Пример #55
0
 def test_is_not_tree(self):
     assert_false(nx.is_tree(self.N4))
     assert_false(nx.is_tree(self.N5))
     assert_false(nx.is_tree(self.N6))
# Create G and H
G = nx.Graph()
H = nx.Graph()

G.add_nodes_from([1,2,3,4,5,6,7])
G.add_edge(1,2)
G.add_edge(1,3)
G.add_edge(2,4)
G.add_edge(2,5)
G.add_edge(3,6)
G.add_edge(3,7)

H.add_nodes_from([8,9,10])
H.add_edge(8,9)
H.add_edge(8,10)

print nx.is_tree(G)
print nx.is_tree(H)
print subtree_isomorphism(G, H)

G = nx.Graph()
G.add_nodes_from([1,2,3,4,5])
G.add_edge(1,2)
G.add_edge(2,3)
G.add_edge(3,4)
G.add_edge(4,5)

print nx.is_tree(G)
print nx.is_tree(H)
print subtree_isomorphism(G, H)
Пример #57
0
def to_nested_tuple(T, root, canonical_form=False):
    """Returns a nested tuple representation of the given tree.

    The nested tuple representation of a tree is defined
    recursively. The tree with one node and no edges is represented by
    the empty tuple, ``()``. A tree with ``k`` subtrees is represented
    by a tuple of length ``k`` in which each element is the nested tuple
    representation of a subtree.

    Parameters
    ----------
    T : NetworkX graph
        An undirected graph object representing a tree.

    root : node
        The node in ``T`` to interpret as the root of the tree.

    canonical_form : bool
        If ``True``, each tuple is sorted so that the function returns
        a canonical form for rooted trees. This means "lighter" subtrees
        will appear as nested tuples before "heavier" subtrees. In this
        way, each isomorphic rooted tree has the same nested tuple
        representation.

    Returns
    -------
    tuple
        A nested tuple representation of the tree.

    Notes
    -----
    This function is *not* the inverse of :func:`from_nested_tuple`; the
    only guarantee is that the rooted trees are isomorphic.

    See also
    --------
    from_nested_tuple
    to_prufer_sequence

    Examples
    --------
    The tree need not be a balanced binary tree::

        >>> T = nx.Graph()
        >>> T.add_edges_from([(0, 1), (0, 2), (0, 3)])
        >>> T.add_edges_from([(1, 4), (1, 5)])
        >>> T.add_edges_from([(3, 6), (3, 7)])
        >>> root = 0
        >>> nx.to_nested_tuple(T, root)
        (((), ()), (), ((), ()))

    Continuing the above example, if ``canonical_form`` is ``True``, the
    nested tuples will be sorted::

        >>> nx.to_nested_tuple(T, root, canonical_form=True)
        ((), ((), ()), ((), ()))

    Even the path graph can be interpreted as a tree::

        >>> T = nx.path_graph(4)
        >>> root = 0
        >>> nx.to_nested_tuple(T, root)
        ((((),),),)

    """

    def _make_tuple(T, root, _parent):
        """Recursively compute the nested tuple representation of the
        given rooted tree.

        ``_parent`` is the parent node of ``root`` in the supertree in
        which ``T`` is a subtree, or ``None`` if ``root`` is the root of
        the supertree. This argument is used to determine which
        neighbors of ``root`` are children and which is the parent.

        """
        # Get the neighbors of `root` that are not the parent node. We
        # are guaranteed that `root` is always in `T` by construction.
        children = set(T[root]) - {_parent}
        if len(children) == 0:
            return ()
        nested = (_make_tuple(T, v, root) for v in children)
        if canonical_form:
            nested = sorted(nested)
        return tuple(nested)

    # Do some sanity checks on the input.
    if not nx.is_tree(T):
        raise nx.NotATree('provided graph is not a tree')
    if root not in T:
        raise nx.NodeNotFound('Graph {} contains no node {}'.format(T, root))

    return _make_tuple(T, root, None)
Пример #58
0
def to_prufer_sequence(T):
    r"""Returns the Prüfer sequence of the given tree.

    A *Prüfer sequence* is a list of *n* - 2 numbers between 0 and
    *n* - 1, inclusive. The tree corresponding to a given Prüfer
    sequence can be recovered by repeatedly joining a node in the
    sequence with a node with the smallest potential degree according to
    the sequence.

    Parameters
    ----------
    T : NetworkX graph
        An undirected graph object representing a tree.

    Returns
    -------
    list
        The Prüfer sequence of the given tree.

    Raises
    ------
    NetworkXPointlessConcept
        If the number of nodes in `T` is less than two.

    NotATree
        If `T` is not a tree.

    KeyError
        If the set of nodes in `T` is not {0, …, *n* - 1}.

    Notes
    -----
    There is a bijection from labeled trees to Prüfer sequences. This
    function is the inverse of the :func:`from_prufer_sequence`
    function.

    Sometimes Prüfer sequences use nodes labeled from 1 to *n* instead
    of from 0 to *n* - 1. This function requires nodes to be labeled in
    the latter form. You can use :func:`~networkx.relabel_nodes` to
    relabel the nodes of your tree to the appropriate format.

    This implementation is from [1]_ and has a running time of
    $O(n \log n)$.

    See also
    --------
    to_nested_tuple
    from_prufer_sequence

    References
    ----------
    .. [1] Wang, Xiaodong, Lei Wang, and Yingjie Wu.
           "An optimal algorithm for Prufer codes."
           *Journal of Software Engineering and Applications* 2.02 (2009): 111.
           <http://dx.doi.org/10.4236/jsea.2009.22016>

    Examples
    --------
    There is a bijection between Prüfer sequences and labeled trees, so
    this function is the inverse of the :func:`from_prufer_sequence`
    function:

    >>> edges = [(0, 3), (1, 3), (2, 3), (3, 4), (4, 5)]
    >>> tree = nx.Graph(edges)
    >>> sequence = nx.to_prufer_sequence(tree)
    >>> sequence
    [3, 3, 3, 4]
    >>> tree2 = nx.from_prufer_sequence(sequence)
    >>> list(tree2.edges()) == edges
    True

    """
    # Perform some sanity checks on the input.
    n = len(T)
    if n < 2:
        msg = 'Prüfer sequence undefined for trees with fewer than two nodes'
        raise nx.NetworkXPointlessConcept(msg)
    if not nx.is_tree(T):
        raise nx.NotATree('provided graph is not a tree')
    if set(T) != set(range(n)):
        raise KeyError('tree must have node labels {0, ..., n - 1}')

    degree = dict(T.degree())

    def parents(u):
        return next(v for v in T[u] if degree[v] > 1)

    index = u = min(k for k in range(n) if degree[k] == 1)
    result = []
    for i in range(n - 2):
        v = parents(u)
        result.append(v)
        degree[v] -= 1
        if v < index and degree[v] == 1:
            u = v
        else:
            index = u = min(k for k in range(index + 1, n) if degree[k] == 1)
    return result
Пример #59
0
import networkx as nx
import matplotlib.pyplot as plt

T=nx.DiGraph()


N=11
T.add_nodes_from(range(6))

T.add_edges_from(zip( range(0,N,2), range(1,N,2)))
T.add_edges_from(zip( range(0,N-1,2), range(2,N,2)))

print T.edges()




assert nx.is_tree(T)

nx.draw(T)
#nx.draw_spectral(T)
plt.show()
Пример #60
0
def test_multicycle():
    G = nx.MultiDiGraph()
    G.add_edges_from([(0,1), (0,1)])
    assert_false(nx.is_tree(G))
    assert_true(nx.is_directed_acyclic_graph(G))