Example #1
0
def _print_forest(graph):
    """
    Nice ascii representation of a forest

    Ignore:
        graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph)
        _print_forest(graph)

        graph = CategoryTree.demo('coco').graph
        _print_forest(graph)
    """
    assert nx.is_forest(graph)
    encoding = to_directed_nested_tuples(graph)

    def _recurse(encoding, indent=''):
        for idx, item in enumerate(encoding):
            node, data, children = item
            if idx == len(encoding) - 1:
                this_prefix = indent + '└── '
                next_prefix = indent + '    '
            else:
                this_prefix = indent + '├── '
                next_prefix = indent + '│   '
            label = graph.nodes[node].get('label', node)
            print(this_prefix + str(label))
            _recurse(children, indent=next_prefix)

    _recurse(encoding)
Example #2
0
    def __init__(self, graph=None):
        """
        Args:
            graph (nx.DiGraph):
                either the graph representing a category hierarchy
        """
        if graph is None:
            graph = nx.DiGraph()
        else:
            if len(graph) > 0:
                if not nx.is_directed_acyclic_graph(graph):
                    raise ValueError('The category graph must a DAG')
                if not nx.is_forest(graph):
                    raise ValueError('The category graph must be a forest')
            if not isinstance(graph, nx.Graph):
                raise TypeError(
                    'Input to CategoryTree must be a networkx graph not {}'.
                    format(type(graph)))
        self.graph = graph  # :type: nx.Graph
        # Note: nodes are class names
        self.id_to_node = None
        self.node_to_id = None
        self.node_to_idx = None
        self.idx_to_node = None
        self.idx_groups = None

        self._build_index()
Example #3
0
    def add_edge(self, u, v, *args, **kwargs):
        changed = False
        if u == v:
            if self.flags['strict']:
                raise ValueError('Edge must be between two unique nodes!')
            return changed
        elif self._undirected.has_edge(u, v):
            self.remove_edges_from([[u, v], [v, u]])
        elif len(self.nodes()) > 0:
            try:
                path = nx.shortest_path(self._undirected, u, v)
                if self.flags['strict']:
                    raise ValueError(
                        'Multiple edge path exists between nodes!')
                self.disconnect_path(path)
                changed = True
            except (nx.NetworkXError, nx.NetworkXNoPath, nx.NetworkXException):
                pass
        self._undirected.add_edge(u, v)
        super(self.__class__, self).add_edge(u, v, *args, **kwargs)

        if self.flags['assert_forest']:
            # this is quite slow but makes very sure structure is correct
            # so is mainly used for testing
            assert nx.is_forest(nx.Graph(self))

        return changed
Example #4
0
def run_graph(graph):
    """
    :param graph:
    :return:
    """
    results = []
    if nx.is_forest(graph):
        while len(leaves(graph)) > 0:
            current_leaves = leaves(graph)
            for n in current_leaves:
                for edge in graph.edges_iter(n):
                    local_data = graph.node[n]['data'].copy()
                    if 'data' not in graph.node[edge[1]]:
                        graph.node[edge[1]]['data'] = apply_edge(local_data, graph.edge[edge[0]][edge[1]]['transformation']).copy()
                    else:
                        graph.node[edge[1]]['data'] = pd.merge( left=graph.node[edge[1]]['data'],
                                                                right=apply_edge(local_data,
                                                                graph.edge[edge[0]][edge[1]]['transformation']).copy(),
                                                                how='left',
                                                                left_on=graph.node[edge[1]]['match_keys'],
                                                                right_on=graph.node[edge[1]]['match_keys']
                                                                )

                if 'producer' in graph.node[n]:
                    if graph.node[n]['producer']:
                        results.append(graph.node[n]['data'])

                graph.remove_node(n)
    return results
Example #5
0
def _print_forest(graph):
    """
    Nice ascii representation of a forest

    Ignore:
        graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph)
        _print_forest(graph)

        graph = CategoryTree.demo('coco').graph
        _print_forest(graph)
    """
    if len(graph.nodes) == 0:
        print('--')
        return
    assert nx.is_forest(graph)

    def _recurse(node, indent='', islast=False):
        if islast:
            this_prefix = indent + '└── '
            next_prefix = indent + '    '
        else:
            this_prefix = indent + '├── '
            next_prefix = indent + '│   '
        label = graph.nodes[node].get('label', node)
        print(this_prefix + str(label))
        graph.succ[node]
        children = graph.succ[node]
        for idx, child in enumerate(children, start=1):
            islast_next = (idx == len(children))
            _recurse(child, indent=next_prefix, islast=islast_next)

    sources = [n for n in graph.nodes if graph.in_degree[n] == 0]
    for idx, node in enumerate(sources, start=1):
        islast_next = (idx == len(sources))
        _recurse(node, indent='', islast=islast_next)
Example #6
0
 def edge_conditions(t, h, d):
     yield 0 <= d < N
     #yield (h, d) not in t.edges()
     #yield (d, h) not in t.edges()
     test_t = copy.deepcopy(t)
     test_t.add_edge(h, d)
     yield nx.is_forest(test_t)
Example #7
0
    def add_edge(self, u, v, *args, **kwargs):
        changed = False
        if u == v:
            if self.flags['strict']:
                raise ValueError('Edge must be between two unique nodes!')
            return changed
        if self._undirected.has_edge(u, v):
            self.remove_edges_from([[u, v], [v, u]])
        elif len(self.nodes()) > 0:
            try:
                path = nx.shortest_path(self._undirected, u, v)
                if self.flags['strict']:
                    raise ValueError(
                        'Multiple edge path exists between nodes!')
                self.disconnect_path(path)
                changed = True
            except (nx.NetworkXError, nx.NetworkXNoPath, nx.NetworkXException):
                pass
        self._undirected.add_edge(u, v)
        super(self.__class__, self).add_edge(u, v, *args, **kwargs)

        if self.flags['assert_forest']:
            # this is quite slow but makes very sure structure is correct
            # so is mainly used for testing
            assert nx.is_forest(nx.Graph(self))

        return changed
Example #8
0
def tree_depth(graph, root=None):
    """
    Maximum depth of the forest / tree

    Example:
        >>> from kwcoco.category_tree import *
        >>> graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph)
        >>> tree_depth(graph)
        4
        >>> tree_depth(nx.balanced_tree(r=2, h=0, create_using=nx.DiGraph))
        1
    """
    if len(graph) == 0:
        return 0
    if root is not None:
        assert root in graph.nodes
    assert nx.is_forest(graph)

    def _inner(root):
        if root is None:
            return max(it.chain([0], (_inner(n) for n in source_nodes(graph))))
        else:
            return max(
                it.chain([0], (_inner(n) for n in graph.successors(root)))) + 1

    depth = _inner(root)
    return depth
Example #9
0
def run_graph(graph):
    """
    :param graph:
    :return:
    """
    results = []
    if nx.is_forest(graph):
        while len(leaves(graph)) > 0:
            current_leaves = leaves(graph)
            for n in current_leaves:
                for edge in graph.edges_iter(n):
                    local_data = graph.node[n]['data'].copy()
                    if 'data' not in graph.node[edge[1]]:
                        graph.node[edge[1]]['data'] = apply_edge(
                            local_data, graph.edge[edge[0]][edge[1]]
                            ['transformation']).copy()
                    else:
                        graph.node[edge[1]]['data'] = pd.merge(
                            left=graph.node[edge[1]]['data'],
                            right=apply_edge(
                                local_data, graph.edge[edge[0]][edge[1]]
                                ['transformation']).copy(),
                            how='left',
                            left_on=graph.node[edge[1]]['match_keys'],
                            right_on=graph.node[edge[1]]['match_keys'])

                if 'producer' in graph.node[n]:
                    if graph.node[n]['producer']:
                        results.append(graph.node[n]['data'])

                graph.remove_node(n)
    return results
Example #10
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
Example #11
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")
Example #12
0
def show_props(graph):
    print("Nodes: {}, Edges: {}".format(len(graph.nodes), len(graph.edges)))
    treewidth, decomp = approximation.treewidth_min_degree(graph)
    print("TreeWidth: {}".format(treewidth))
    cluster_ceof = approximation.clustering_coefficient.average_clustering(
        graph)
    print("Average Clustering Coefficient: {}".format(cluster_ceof))
    print("Is Acyclic: {}".format(nx.is_forest(graph)))
    node, degree = max([(n, d) for n, d in graph.degree()], key=lambda x: x[1])
    print("Max degree: {}".format(degree))
Example #13
0
def search_longest_path_efficient(G, weight='weight'):
    """
    Info: Search algorithm to find longest path in a graph. 
    Breadth first search (BFS) used twice for acyclic graphs.
    BFS over all endnodes used for cyclic graphs
    input: nx.Graph
    optional: edge paramater weight -> either 'weight' or 'thick'
    output: [list] of all paths between all nodes, [list] of length of each path
    """
    def _bfs_tree(G):
        # twice BFS in undirected acyclic graph (Tree) to find endnodes
        # bfs for longest path is performed in Directed Tree
        endnodes = [x for x in G.nodes() if G.degree(x) == 1]
        DiTree1 = nx.traversal.bfs_tree(G, endnodes[0])
        SG1 = G.subgraph(nx.dag_longest_path(DiTree1, weight=weight))
        new_root = [
            x for x in SG1.nodes() if G.degree(x) == 1 and x != endnodes[0]
        ][0]
        DiTree2 = nx.traversal.bfs_tree(SG1, new_root)
        SG2 = G.subgraph(nx.dag_longest_path(DiTree2, weight=weight))
        return SG2, nx.dag_longest_path_length(DiTree2)

    def _exhaustive(G):
        # Finds longest shortest path by iterating over all endnodes
        path_list = []
        path_length = []
        #         node_pairs = []
        endnodes = [x for x in G.nodes() if G.degree(x) == 1]
        for source in endnodes:
            for target in endnodes:
                sh_p = nx.shortest_path(G, source, target, weight=weight)
                sh_p_l = nx.shortest_path_length(G,
                                                 source,
                                                 target,
                                                 weight=weight)
                path_list.append(sh_p)
                path_length.append(sh_p_l)


#                 node_pairs.append([source, target])

        nbunch = path_list[np.argmax(path_length)]
        SG = G.subgraph(nbunch)
        return SG, np.max(
            path_length)  #, nbunch, node_pairs[np.argmax(path_length)]

    if nx.tree.is_tree(G):  #single connected acyclic graph
        return _bfs_tree(G)

    else:
        if nx.is_forest(G):  #multiple disconnected trees
            #todo: loop over connected components (=trees), compare longest branches
            return _exhaustive(G)
        else:  #cyclic graph
            return _exhaustive(G)
Example #14
0
def freqCount(thread_map):
    dictionary = corpora.Dictionary.load("gensim_dictionary")
    maptofreq = dict()
    for head in sorted(thread_map):
        assert (nx.is_forest(thread_map[head]))
        thread_string = ""
        for node, data in thread_map[head].nodes_iter(data=True):
            thread_string += " " + data["body"]
        words_in_thread = re.findall(r"[\w'-]+", thread_string.lower())
        word_vector = dictionary.doc2bow(words_in_thread)
        maptofreq[head] = word_vector
    return maptofreq
Example #15
0
def is_merge_tree(M):
    acyclic = nx.is_forest(M)
    connected = nx.is_connected(M)
    red = reduced(M)
    
    print('---')
    print("M is acyclic: " + str(acyclic))
    print("M is connected: " + str(connected))
    print("M is reduced: " + str(red))
    print('---')
    
    return acyclic and connected and red
Example #16
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)
Example #17
0
 def attempt():
     result = nx.Graph()
     result.add_nodes_from(range(len(dl_seq) + 1))
     for dl, k in dl_counter.items():
         possibles = possible_edges_with_dl(result, dl)
         if not possibles:
             return None
         else:
             possible_sets = itertools.combinations(possibles, k)
             edge_set = random.choice(list(possible_sets))
             result.add_edges_from(edge_set)
             if not nx.is_forest(result):
                 return None
     return result
Example #18
0
    def is_tree(self) -> bool:
        """Returns whether neuron is a tree. Alsos returns True if neuron
        consists of multiple separate trees.

        See also
        --------
        networkx.is_forest()
                    Function used to test whether neuron is a tree.
        :attr:`TreeNeuron.cycles`
                    If your neuron is not a tree, this will help you identify
                    cycles.

        """
        return nx.is_forest(self.graph)
Example #19
0
def number_of_rforest(G, r1, r2):
    edge_list = G.edges()
    count = 0
    for e in powerset(range(len(edge_list))):
        H = nx.Graph()
        H.add_nodes_from(range(len(G.nodes())))
        #print H.nodes()
        for i in e:
            H.add_edge(*edge_list[i])
        #print H.edges()
        if not nx.has_path(H, r1, r2) and nx.number_connected_components(H) == 2 and nx.is_forest(H):
            count += 1
            #print H.edges()
    return count
Example #20
0
def number_of_rforest(G, r1, r2):
    edge_list = G.edges()
    count = 0
    for e in powerset(range(len(edge_list))):
        H = nx.Graph()
        H.add_nodes_from(range(len(G.nodes())))
        #print H.nodes()
        for i in e:
            H.add_edge(*edge_list[i])
        #print H.edges()
        if not nx.has_path(H, r1, r2) and nx.number_connected_components(
                H) == 2 and nx.is_forest(H):
            count += 1
            #print H.edges()
    return count
Example #21
0
def number_of_pathmatching(G):
    edge_list = G.edges()
    count = 0
    for e in powerset(range(len(edge_list))):
        H = nx.Graph()
        H.add_nodes_from(range(len(G.nodes())))
        #print H.nodes()
        for i in e:
            H.add_edge(*edge_list[i])
        #print H.edges()
        is_pm = True
        for v in G.nodes():
            if nx.degree(H, v) > 2:
                is_pm = False
                break
        if is_pm:
            if nx.is_forest(H):
                count += 1
                #print H.edges()
    return count
Example #22
0
def number_of_pathmatching(G):
    edge_list = G.edges()
    count = 0
    for e in powerset(range(len(edge_list))):
        H = nx.Graph()
        H.add_nodes_from(range(len(G.nodes())))
        #print H.nodes()
        for i in e:
            H.add_edge(*edge_list[i])
        #print H.edges()
        is_pm = True
        for v in G.nodes():
            if nx.degree(H, v) > 2:
                is_pm = False
                break
        if is_pm:
            if nx.is_forest(H):
                count += 1
                #print H.edges()
    return count
def two_char_compatibility_test(c1,c2, ancestral_type_known = False, ancestral_type = (0,0)):
    '''
    Takes two columns of equal length (representing characters on a phylogeny),
    and returns true if and only if they are compatible (in the sense that the
    number of mutations nessecary to place both characters on a single tree is
    the sum of the numbr of mutations nessecary to place each character on a
    tree individually)
    '''
    if len(c1) != len(c2): raise(ValueError('Cannot compare characters of unequal length'))

    #convert input to list
    c1_list = list(c1)
    c2_list = list(c2)

    if ancestral_type_known:
        c1_list.append(ancestral_type[0])
        c2_list.append(ancestral_type[1])

    # G_dict = partition_intersection_graph([c1_list,c2_list])
    # G_nx = nx.Graph(G_dict['E'])
    G_nx = partition_intersection_graph([c1_list,c2_list])

    return nx.is_forest(G_nx)
Example #24
0
File: nx.py Project: nrbgt/ipyelk
def get_roots(tree: nx.DiGraph, g: nx.DiGraph) -> Iterable[Hashable]:
    """Iterate through the roots in the tree and any orphaned nodes in the graph
    
    :param tree: Hierarchical graph
    :type tree: nx.DiGraph
    :param g: [description]
    :type g: nx.DiGraph
    :return: [description]
    :rtype: Hashable
    :yield: [description]
    :rtype: Hashable
    """
    if len(tree) == 0:
        # graph is empty
        return []
    assert nx.is_forest(
        tree
    ), "The given hierarchy should be a NetworkX DiGraph that is also a Forest"
    for node, degree in tree.in_degree():
        if degree == 0:
            yield node
    for node in g.nodes():
        if node not in tree:
            yield node
 def test_is_not_forest(self):
     assert_false(nx.is_forest(self.N4))
     assert_false(nx.is_forest(self.N6))
     assert_false(nx.is_forest(self.NF1))
Example #26
0
 def test_multidigraph_forest(self):
     assert_false(nx.is_forest(self.N3))
Example #27
0
import matplotlib.pyplot as plt
import networkx as nx
from definition import G


if nx.is_forest(G) :
    print('ffforest')

def leaves(graph):
    return([n for n,d in graph.in_degree().items() if d==0])

while len(leaves(G)) > 0:
    for n in leaves(G):
        print(n)
        G.remove_node(n)


#
# for n,d in G.in_degree().items():
#     print(n)
#     print(d)


# print(nx.all_shortest_paths(G))

# print('ddd {here}'.format(here= G.number_of_nodes()))

# nx.draw(G)
# plt.show()
Example #28
0
def maximum_common_ordered_tree_embedding(tree1, tree2, node_affinity='auto'):
    """
    Finds the maximum common subtree-embedding between two ordered trees.

    A tree S is an embedded subtree of T if it can be obtained from T by a
    series of edge contractions.

    Note this produces a subtree embedding, which is not necessarilly a
    subgraph isomorphism (although a subgraph isomorphism is also an
    embedding.)

    The maximum common embedded subtree problem can be solved in in
    `O(n1 * n2 * min(d1, l1) * min(d2, l2))` time on ordered trees with n1 and
    n2 nodes, of depth d1 and d2 and with l1 and l2 leaves, respectively

    Implements algorithm described in [1]_.

    References:
        On the Maximum Common Embedded Subtree Problem for Ordered Trees
        https://pdfs.semanticscholar.org/0b6e/061af02353f7d9b887f9a378be70be64d165.pdf

        http://algo.inria.fr/flajolet/Publications/FlSiSt90.pdf

    Notes:
        Exact algorithms for computing the tree edit distance between unordered trees - https://pdf.sciencedirectassets.com/271538/1-s2.0-S0304397510X00299/1-s2.0-S0304397510005463/main.pdf ?

        Tree Edit Distance and Common Subtrees - https://upcommons.upc.edu/bitstream/handle/2117/97554/R02-20.pdf

        A Survey on Tree Edit Distance and Related Problems - https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf

    Args:

        tree1 (nx.OrderedDiGraph): first ordered tree
        tree2 (nx.OrderedDiGraph): second ordered tree
        node_affinity (callable): function

    Example:
        >>> from netharn.initializers._nx_extensions import *  # NOQA
        >>> from netharn.initializers._nx_extensions import _lcs, _print_forest
        >>> def random_ordered_tree(n, seed=None):
        >>>     tree = nx.dfs_tree(nx.random_tree(n, seed=seed))
        >>>     otree = nx.OrderedDiGraph()
        >>>     otree.add_edges_from(tree.edges)
        >>>     return otree
        >>> tree1 = random_ordered_tree(10, seed=1)
        >>> tree2 = random_ordered_tree(10, seed=2)
        >>> print('tree1')
        >>> _print_forest(tree1)
        >>> print('tree2')
        >>> _print_forest(tree2)

        >>> embedding1, embedding2 = maximum_common_ordered_tree_embedding(tree1, tree2 )
        >>> print('embedding1')
        >>> _print_forest(embedding1)
        >>> print('embedding2')
        >>> _print_forest(embedding2)
    """
    if not (isinstance(tree1, nx.OrderedDiGraph) and nx.is_forest(tree1)):
        raise nx.NetworkXNotImplemented(
            'only implemented for directed ordered trees')
    if not (isinstance(tree1, nx.OrderedDiGraph) and nx.is_forest(tree2)):
        raise nx.NetworkXNotImplemented(
            'only implemented for directed ordered trees')

    # Convert the trees to balanced sequences
    sequence1, open_to_close, toks = tree_to_seq(tree1,
                                                 open_to_close=None,
                                                 toks=None)
    sequence2, open_to_close, toks = tree_to_seq(tree2, open_to_close, toks)
    seq1 = sequence1
    seq2 = sequence2

    open_to_tok = ub.invert_dict(toks)

    # Solve the longest common balanced sequence problem
    best, value = longest_common_balanced_sequence(seq1,
                                                   seq2,
                                                   open_to_close,
                                                   open_to_tok=open_to_tok,
                                                   node_affinity=node_affinity)
    subseq1, subseq2 = best

    # Convert the subsequence back into a tree
    embedding1 = seq_to_tree(subseq1, open_to_close, toks)
    embedding2 = seq_to_tree(subseq2, open_to_close, toks)
    return embedding1, embedding2
Example #29
0
def maximum_common_ordered_subtree_isomorphism(tree1,
                                               tree2,
                                               node_affinity='auto'):
    """
    Isomorphic version of `maximum_common_ordered_tree_embedding`.

    CommandLine:
        xdoctest -m /home/joncrall/code/netharn/netharn/initializers/_nx_extensions.py maximum_common_ordered_subtree_isomorphism:1 --profile && cat profile_output.txt

    Example:
        >>> from netharn.initializers._nx_extensions import *  # NOQA
        >>> from netharn.initializers._nx_extensions import _lcs, _print_forest
        >>> def random_ordered_tree(n, seed=None):
        >>>     tree = nx.dfs_tree(nx.random_tree(n, seed=seed))
        >>>     otree = nx.OrderedDiGraph()
        >>>     otree.add_edges_from(tree.edges)
        >>>     return otree
        >>> tree1 = random_ordered_tree(10, seed=3)
        >>> tree2 = random_ordered_tree(10, seed=2)
        >>> tree1.add_edges_from(tree2.edges, weight=1)
        >>> tree1 = nx.minimum_spanning_arborescence(tree1)
        >>> tree2.add_edges_from(tree1.edges, weight=1)
        >>> tree2 = nx.minimum_spanning_arborescence(tree2)

        >>> tree1.remove_edge(4, 7)
        >>> tree1.remove_edge(4, 9)
        >>> tree1.add_edge(4, 10)
        >>> tree1.add_edge(10, 7)
        >>> tree1.add_edge(10, 9)
        >>> #tree1.add_edges_from([(9, 11), (11, 12), (12, 13), (13, 14)])
        >>> #tree2.add_edges_from([(9, 11), (11, 12), (12, 13), (13, 14)])
        >>> tree1.add_edges_from([(9, 11), (11, 12)])
        >>> tree2.add_edges_from([(9, 11), (11, 12)])
        >>> tree2.add_edge(100, 0)
        >>> tree1.add_edge(102, 100)
        >>> tree1.add_edge(100, 101)
        >>> tree1.add_edge(101, 0)
        >>> tree1.add_edge(5, 201)
        >>> tree1.add_edge(5, 202)
        >>> tree1.add_edge(5, 203)
        >>> tree1.add_edge(201, 2000)
        >>> tree1.add_edge(2000, 2001)
        >>> tree1.add_edge(2001, 2002)
        >>> tree1.add_edge(2002, 2003)

        >>> tree2.add_edge(5, 202)
        >>> tree2.add_edge(5, 203)
        >>> tree2.add_edge(5, 201)
        >>> tree2.add_edge(201, 2000)
        >>> tree2.add_edge(2000, 2001)
        >>> tree2.add_edge(2001, 2002)
        >>> tree2.add_edge(2002, 2003)

        >>> print('-----')
        >>> print('tree1')
        >>> _print_forest(tree1)
        >>> print('tree2')
        >>> _print_forest(tree2)

        >>> subtree1, subtree2 = maximum_common_ordered_subtree_isomorphism(tree1, tree2 )
        >>> print('-----')
        >>> print('subtree1')
        >>> _print_forest(subtree1)
        >>> print('subtree2')
        >>> _print_forest(subtree2)

        >>> embedding1, embedding2 = maximum_common_ordered_tree_embedding(tree1, tree2)
        >>> print('-----')
        >>> print('embedding1')
        >>> _print_forest(embedding1)
        >>> print('embedding2')
        >>> _print_forest(embedding2)

        >>> if 0:
        >>>     ti = timerit.Timerit(6, bestof=2, verbose=2)
        >>>     for timer in ti.reset('isomorphism'):
        >>>         with timer:
        >>>             maximum_common_ordered_subtree_isomorphism(tree1, tree2 )
        >>>     for timer in ti.reset('embedding'):
        >>>         with timer:
        >>>             maximum_common_ordered_tree_embedding(tree1, tree2 )

        >>> from networkx import isomorphism
        >>> assert isomorphism.DiGraphMatcher(tree1, subtree1).subgraph_is_isomorphic()
        >>> assert isomorphism.DiGraphMatcher(tree2, subtree2).subgraph_is_isomorphic()

        >>> list(isomorphism.DiGraphMatcher(tree1, tree2).subgraph_isomorphisms_iter())
        >>> list(isomorphism.DiGraphMatcher(tree1, tree2).subgraph_monomorphisms_iter())

        >>> list(isomorphism.DiGraphMatcher(subtree1, subtree2).subgraph_isomorphisms_iter())
        >>> list(isomorphism.DiGraphMatcher(tree1, subtree1).subgraph_isomorphisms_iter())
        >>> list(isomorphism.DiGraphMatcher(tree2, subtree2).subgraph_isomorphisms_iter())

    Example:
        >>> from netharn.initializers._nx_extensions import *  # NOQA
        >>> from netharn.initializers._nx_extensions import _lcs, _print_forest
        >>> def random_ordered_tree(n, seed=None):
        >>>     if n > 0:
        >>>         tree = nx.dfs_tree(nx.random_tree(n, seed=seed))
        >>>     otree = nx.OrderedDiGraph()
        >>>     if n > 0:
        >>>         otree.add_edges_from(tree.edges)
        >>>     return otree
        >>> import random
        >>> rng = random.Random(90269698983701724775426457020022)
        >>> num = 1000
        >>> def _gen_seeds(num):
        >>>     for _ in range(num):
        >>>         yield (rng.randint(0, 50), rng.randint(0, 50), rng.randint(0, 2 ** 64), rng.randint(0, 2 ** 64))
        >>> for n1, n2, s1, s2 in ub.ProgIter(_gen_seeds(num=num), total=num, verbose=3):
        >>>     tree1 = random_ordered_tree(n1, seed=s1)
        >>>     tree2 = random_ordered_tree(n2, seed=s2)
        >>>     #print('-----')
        >>>     #print('tree1')
        >>>     #_print_forest(tree1)
        >>>     #print('tree2')
        >>>     #_print_forest(tree2)
        >>>     subtree1, subtree2 = maximum_common_ordered_subtree_isomorphism(tree1, tree2, node_affinity='auto')
        >>>     #print('-----')
        >>>     #print('subtree1')
        >>>     #_print_forest(subtree1)
        >>>     #print('subtree2')
        >>>     #_print_forest(subtree2)
        >>>     from networkx import isomorphism
        >>>     assert isomorphism.DiGraphMatcher(tree1, subtree1).subgraph_is_isomorphic()
        >>>     assert isomorphism.DiGraphMatcher(tree2, subtree2).subgraph_is_isomorphic()

    """
    try:
        if not (isinstance(tree1, nx.OrderedDiGraph) and nx.is_forest(tree1)):
            raise nx.NetworkXNotImplemented(
                'only implemented for directed ordered trees')
        if not (isinstance(tree1, nx.OrderedDiGraph) and nx.is_forest(tree2)):
            raise nx.NetworkXNotImplemented(
                'only implemented for directed ordered trees')
    except nx.NetworkXPointlessConcept:
        subtree1 = nx.OrderedDiGraph()
        subtree2 = nx.OrderedDiGraph()
        return subtree1, subtree2

    # Convert the trees to balanced sequences
    sequence1, open_to_close, toks = tree_to_seq(tree1,
                                                 open_to_close=None,
                                                 toks=None,
                                                 mode='chr')
    sequence2, open_to_close, toks = tree_to_seq(tree2,
                                                 open_to_close,
                                                 toks,
                                                 mode='chr')
    seq1 = sequence1
    seq2 = sequence2

    open_to_tok = ub.invert_dict(toks)

    # Solve the longest common balanced sequence problem
    best, value = longest_common_isomorphic_sequence(
        seq1,
        seq2,
        open_to_close,
        open_to_tok=open_to_tok,
        node_affinity=node_affinity)
    subseq1, subseq2 = best

    # Convert the subsequence back into a tree
    subtree1 = seq_to_tree(subseq1, open_to_close, toks)
    subtree2 = seq_to_tree(subseq2, open_to_close, toks)
    return subtree1, subtree2
Example #30
0
def forest_str(graph, with_labels=True, sources=None, write=None):
    """
    Creates a nice utf8 representation of a directed forest

    Parameters
    ----------
    graph : nx.DiGraph | nx.Graph
        Graph to represent (must be a tree, forest, or the empty graph)

    with_labels : bool
        If True will use the "label" attribute of a node to display if it
        exists otherwise it will use the node value itself. Defaults to True.

    sources : List
        Mainly relevant for undirected forests, specifies which nodes to list
        first. If unspecified the root nodes of each tree will be used for
        directed forests; for undirected forests this defaults to the nodes
        with the smallest degree.

    write : callable
        Function to use to write to, if None new lines are appended to
        a list and returned. If set to the `print` function, lines will
        be written to stdout as they are generated. If specified,
        this function will return None. Defaults to None.

    Returns
    -------
    str | None :
        utf8 representation of the tree / forest

    Example
    -------
    >>> import networkx as nx
    >>> graph = nx.balanced_tree(r=2, h=3, create_using=nx.DiGraph)
    >>> print(forest_str(graph))
    ╙── 0
        ├─╼ 1
        │   ├─╼ 3
        │   │   ├─╼ 7
        │   │   └─╼ 8
        │   └─╼ 4
        │       ├─╼ 9
        │       └─╼ 10
        └─╼ 2
            ├─╼ 5
            │   ├─╼ 11
            │   └─╼ 12
            └─╼ 6
                ├─╼ 13
                └─╼ 14


    >>> graph = nx.balanced_tree(r=1, h=2, create_using=nx.Graph)
    >>> print(forest_str(graph))
    ╙── 0
        └── 1
            └── 2
    """
    import networkx as nx

    printbuf = []
    if write is None:
        _write = printbuf.append
    else:
        _write = write

    if len(graph.nodes) == 0:
        _write("╙")
    else:
        if not nx.is_forest(graph):
            raise nx.NetworkXNotImplemented(
                "input must be a forest or the empty graph")

        is_directed = graph.is_directed()
        succ = graph.succ if is_directed else graph.adj

        if sources is None:
            if is_directed:
                # use real source nodes for directed trees
                sources = [n for n in graph.nodes if graph.in_degree[n] == 0]
            else:
                # use arbitrary sources for undirected trees
                sources = [
                    min(cc, key=lambda n: graph.degree[n])
                    for cc in nx.connected_components(graph)
                ]

        # Populate the stack with each source node, empty indentation, and mark
        # the final node. Reverse the stack so sources are popped in the
        # correct order.
        last_idx = len(sources) - 1
        stack = [(node, "", (idx == last_idx))
                 for idx, node in enumerate(sources)][::-1]

        seen = set()
        while stack:
            node, indent, islast = stack.pop()
            if node in seen:
                continue
            seen.add(node)

            # Notes on available box and arrow characters
            # https://en.wikipedia.org/wiki/Box-drawing_character
            # https://stackoverflow.com/questions/2701192/triangle-arrow
            if not indent:
                # Top level items (i.e. trees in the forest) get different
                # glyphs to indicate they are not actually connected
                if islast:
                    this_prefix = indent + "╙── "
                    next_prefix = indent + "    "
                else:
                    this_prefix = indent + "╟── "
                    next_prefix = indent + "╎   "

            else:
                # For individual forests distinguish between directed and
                # undirected cases
                if is_directed:
                    if islast:
                        this_prefix = indent + "└─╼ "
                        next_prefix = indent + "    "
                    else:
                        this_prefix = indent + "├─╼ "
                        next_prefix = indent + "│   "
                else:
                    if islast:
                        this_prefix = indent + "└── "
                        next_prefix = indent + "    "
                    else:
                        this_prefix = indent + "├── "
                        next_prefix = indent + "│   "

            if with_labels:
                label = graph.nodes[node].get("label", node)
            else:
                label = node

            _write(this_prefix + str(label))

            # Push children on the stack in reverse order so they are popped in
            # the original order.
            children = [child for child in succ[node] if child not in seen]
            for idx, child in enumerate(children[::-1], start=1):
                islast_next = idx <= 1
                try_frame = (child, next_prefix, islast_next)
                stack.append(try_frame)

    if write is None:
        # Only return a string if the custom write function was not specified
        return "\n".join(printbuf)
Example #31
0
 def test_is_not_forest(self):
     assert not nx.is_forest(self.N4)
     assert not nx.is_forest(self.N6)
     assert not nx.is_forest(self.NF1)
Example #32
0
 def test_is_forest(self):
     assert nx.is_forest(self.T2)
     assert nx.is_forest(self.T3)
     assert nx.is_forest(self.T5)
     assert nx.is_forest(self.F1)
     assert nx.is_forest(self.N5)
Example #33
0
 def test_null_forest2(self):
     with pytest.raises(nx.NetworkXPointlessConcept):
         nx.is_forest(self.multigraph())
m = 3
import networkx as nx
trees = []
G = nx.grid_graph([m, m])
n = len(G.nodes())
sorted_edges = list(G.edges())
for i in range(5000):
    edge_list = []
    T = nx.Graph()
    random.shuffle(sorted_edges)
    i = 0
    while len(T.edges()) < n - 1:
        e = sorted_edges[i]
        T.add_edges_from([e])
        if nx.is_forest(T) == False:
            T.remove_edges_from([e])
        i += 1
    trees.append(T)

partitions = []
for tree in trees:
    for e in tree.edges():
        partitions.append(R(G, tree, e))

print("now making histogram")
histogram = make_histogram(list_of_partitions, partitions)
total_variation = 0
for k in histogram.keys():
    total_variation += np.abs(histogram[k] - 1 / len(list_of_partitions))
print(total_variation)
Example #35
0
 def test_is_not_forest(self):
     assert_false(nx.is_forest(self.N4))
     assert_false(nx.is_forest(self.N6))
     assert_false(nx.is_forest(self.NF1))
 def test_is_forest(self):
     assert_true(nx.is_forest(self.T2))
     assert_true(nx.is_forest(self.T3))
     assert_true(nx.is_forest(self.T5))
     assert_true(nx.is_forest(self.F1))
     assert_true(nx.is_forest(self.N5))
 def test_null_forest(self):
     nx.is_forest(self.graph())
     nx.is_forest(self.multigraph())
Example #38
0
 def test_null_forest(self):
     nx.is_forest(self.graph())
     nx.is_forest(self.multigraph())
Example #39
0
 def test_is_forest(self):
     assert_true(nx.is_forest(self.T2))
     assert_true(nx.is_forest(self.T3))
     assert_true(nx.is_forest(self.T5))
     assert_true(nx.is_forest(self.F1))
     assert_true(nx.is_forest(self.N5))
Example #40
0
# Part A: Analysis of Connected Components
print("The Amount of Connected Components: ",
      nx.number_connected_components(ug))
ccs = [
    len(c) for c in sorted(nx.connected_components(ug), key=len, reverse=True)
]
print("Largest Connected Component: ", ccs[0])
print("Smallest Connected Component: ", ccs[-1])
# Part E: Euler Network
print("Is subnetwork 1 Eularian? ", nx.is_eulerian(separate1))
print("Is subnetwork 2 Eularian? ", nx.is_eulerian(separate2))
# Part H: Minimum Spanning tree of network (ug) and largest CC (separate1)
a = nx.minimum_spanning_tree(ug)
print("Is tree?", nx.is_tree(a))
print("Is forest?", nx.is_forest(a))
separate1.remove_edge(3, 11)
b = nx.minimum_spanning_tree(separate1)
print("Removed edge from largest CC")
print("Is tree?", nx.is_tree(b))
print("Is forest?", nx.is_forest(b))

flName = 'moreno_highschool\README.moreno_highschool'
f = open(flName, 'r')
lines = f.readlines()

print('###################################################################')
print('############### Directed weighted network: README #################')
print('###################################################################')
## Reading the data
flName = 'moreno_highschool\out.moreno_highschool_highschool'
Example #41
0
 def test_digraph_forest(self):
     assert_false(nx.is_forest(self.N1))