Exemplo n.º 1
0
def local_clustering_binary_undirected(g, nodes=None):
    '''
    Returns the undirected local clustering coefficient of some `nodes`.

    If `g` is directed, then it is converted to a simple undirected graph
    (no parallel edges).

    Parameters
    ----------
    g : :class:`~nngt.Graph`
        Graph to analyze.
    nodes : list, optional (default: all nodes)
        The list of nodes for which the clustering will be returned

    Returns
    -------
    lc : :class:`numpy.ndarray`
        The list of clustering coefficients, on per node.

    References
    ----------
    .. [gt-local-clustering] :gtdoc:`clustering.locall_clustering`
    '''
    # use undirected graph view, filter parallel edges
    u = GraphView(g.graph, directed=False)
    u = GraphView(u, efilt=label_parallel_edges(u).fa == 0)

    # compute clustering
    lc = gtc.local_clustering(u, weight=None, undirected=None).a

    if nodes is None:
        return lc

    return lc[nodes]
def min_steiner_tree(g, obs_nodes, debug=False, verbose=False):
    if g.num_vertices() == len(obs_nodes):
        print('it\'s a minimum spanning tree problem')

    gc, eweight, r2pred = build_closure(g,
                                        obs_nodes,
                                        debug=debug,
                                        verbose=verbose)
    # print('gc', gc)

    tree_map = min_spanning_tree(gc, eweight, root=None)
    tree = GraphView(gc, directed=False, efilt=tree_map)

    tree_edges = set()
    # print('tree', tree)
    for e in tree.edges():
        u, v = map(int, e)
        recovered_edges = extract_edges_from_pred(u, v, r2pred[u])
        assert recovered_edges, 'empty!'
        for i, j in recovered_edges:
            tree_edges.add(((i, j)))

    tree_nodes = list(set(itertools.chain(*tree_edges)))

    vfilt = g.new_vertex_property('bool')
    vfilt.set_value(False)
    for n in tree_nodes:
        vfilt[n] = True

    efilt = g.new_edge_property('bool')
    for i, j in tree_edges:
        efilt[g.edge(i, j)] = 1
    return GraphView(g, efilt=efilt, vfilt=vfilt)
def test_fill_missing_time():
    """simple chain graph test
    """
    g = Graph(directed=False)
    g.add_vertex(4)
    g.add_edge_list([(0, 1), (1, 2), (2, 3)])

    t = GraphView(g, directed=True)
    efilt = t.new_edge_property('bool')
    efilt.a = True
    efilt[t.edge(2, 3)] = False
    t.set_edge_filter(efilt)
    vfilt = t.new_vertex_property('bool')
    vfilt.a = True
    vfilt[3] = False
    t.set_vertex_filter(vfilt)

    root = 0
    obs_nodes = {0, 2}
    infection_times = [0, 1.5, 3, -1]

    pt = fill_missing_time(g, t, root, obs_nodes, infection_times, debug=False)

    for i in range(4):
        assert pt[i] == infection_times[i]
def draw_community(gml_fn,
                   output,
                   layout_name=None,
                   layout_kwargs=dict(),
                   **draw_kwargs):
    g = load_graph(gml_fn)

    # Sampel of graph g
    # g = GraphView(g, vfilt=lambda v: g.vertex_index[v]%2==0)
    g.vp['wdeg'] = g.degree_property_map('total', weight=g.ep['weight'])
    # g = GraphView(g, vfilt=lambda v: g.vp['wdeg'][v]>0)

    # label for hub account only in each community
    g.vp['clabel'] = g.new_vertex_property("string", val="")
    for c in np.nditer(np.unique(g.vp['community'].a)):
        cg = GraphView(g, vfilt=(g.vp['community'].a == c))
        v_hub = find_vertex(cg, cg.vp['wdeg'], cg.vp['wdeg'].fa.max())[0]
        cg.vp['clabel'][v_hub] = cg.vp['screenname'][v_hub]

    v_size = prop_to_size(
        g.vp['wdeg'],
        mi=MIN_V_SIZE,
        ma=MAX_V_SIZE,
        log=V_SIZE_LOG,
        power=V_SIZE_POWER)
    e_width = prop_to_size(
        g.ep['weight'],
        mi=MIN_E_WIDTH,
        ma=MAX_E_WIDTH,
        log=E_WIDTH_LOG,
        power=E_WIDTH_POWER)
    if layout_name is not None:
        try:
            pos = globals()[layout_name](g, **layout_kwargs)
        except KeyError as e:
            logger.critical('No such layout function found!')
            raise
    graph_draw(
        g,
        pos,
        output=output,
        vprops=dict(
            fill_color=g.vp['community'],
            # color='grey',
            size=v_size,
            pen_width=0.01,
            text=g.vp['clabel'],
            text_position='centered',
            font_size=8,),
        eprops=dict(
            pen_width=e_width,
            end_marker="arrow",),
        **draw_kwargs)
Exemplo n.º 5
0
def fs_digraph_using_basic_properties(D, stats, options={'features': []}):
    """"""

    # at least one of these features needed to continue
    if len([
            f for f in ['degree', 'parallel_edges', 'fill']
            if f in options['features']
    ]) == 0:
        return

    # feature: order
    num_vertices = D.num_vertices()
    log.debug('done order')

    # feature: size
    num_edges = D.num_edges()
    log.debug('done size')

    stats['n'] = num_vertices
    stats['m'] = num_edges

    # feature: mean_degree
    if 'degree' in options['features']:
        stats['mean_degree'] = float(2 * num_edges) / num_vertices
        log.debug('done mean_degree')

    # feature: fill_overall
    if 'fill' in options['features']:
        stats['fill_overall'] = float(num_edges) / (num_vertices *
                                                    num_vertices)
        log.debug('done fill_overall')

    if 'parallel_edges' in options['features'] or 'fill' in options['features']:
        eprop = label_parallel_edges(D, mark_only=True)
        PE = GraphView(D, efilt=eprop)
        num_edges_PE = PE.num_edges()

        stats['m_unique'] = num_edges - num_edges_PE

        # feature: parallel_edges
        if 'parallel_edges' in options['features']:
            stats['parallel_edges'] = num_edges_PE
            log.debug('done parallel_edges')

        # feature: fill
        if 'fill' in options['features']:
            stats['fill'] = float(num_edges - num_edges_PE) / (num_vertices *
                                                               num_vertices)
            log.debug('done fill')
Exemplo n.º 6
0
    def new_function(eptm, *args, **kwargs):
        from .epithelium import Epithelium
        from graph_tool import Graph, GraphView
        local_graph = Graph(GraphView(eptm.graph,
                                      vfilt=eptm.is_local_vert,
                                      efilt=eptm.is_local_edge),
                            prune=True)
        local_eptm = Epithelium(paramtree=eptm.paramtree, graph=local_graph)
        # if local_eptm.at_boundary.fa.sum() > 0:
        #     local_eptm.rotate(np.pi)
        #     local_eptm.current_angle = np.pi
        #     print('rotated')
        out = meth(local_eptm, *args, **kwargs)
        # if not -1e-8 < local_eptm.current_angle < 1e-8:
        #     local_eptm.rotate(-local_eptm.current_angle)
        #     local_eptm.current_angle = 0.
        #     print( 'rotated back')
        eptm.graph.set_vertex_filter(eptm.is_local_vert)
        eptm.graph.set_edge_filter(eptm.is_local_edge)
        for key, val in local_eptm.graph.vertex_properties.items():
            eptm.graph.vertex_properties[key].fa = val.a
        for key, val in local_eptm.graph.edge_properties.items():
            eptm.graph.edge_properties[key].fa = val.a
        eptm.graph.set_vertex_filter(None)
        eptm.graph.set_edge_filter(None)
        eptm.reset_topology()

        return out
def get_steiner_tree(g, root, obs_nodes, debug=False, verbose=False):
    gc, eweight, r2pred = build_closure(g, obs_nodes,
                                        debug=debug, verbose=verbose)

    tree_map = min_spanning_tree(gc, eweight, root=None)
    tree = GraphView(gc, directed=False, efilt=tree_map)

    tree_edges = set()
    for e in tree.edges():
        u, v = map(int, e)
        for i, j in extract_edges_from_pred(g, u, v, r2pred[u]):
            tree_edges.add((j, i))

    # a bit involved...
    und_tree = edges_to_directed_tree(g, root, tree_edges)
    return build_minimum_tree(g, root, obs_nodes, extract_edges(und_tree))
def min_steiner_tree(g,
                     obs_nodes,
                     p=None,
                     return_type='tree',
                     debug=False,
                     verbose=False):
    assert len(obs_nodes) > 0, 'no terminals'

    if g.num_vertices() == len(obs_nodes):
        print('it\'s a minimum spanning tree problem')

    gc, eweight, r2pred = build_closure(g,
                                        obs_nodes,
                                        p=p,
                                        debug=debug,
                                        verbose=verbose)
    # print('gc', gc)

    tree_map = min_spanning_tree(gc, eweight, root=None)
    tree = GraphView(gc, directed=False, efilt=tree_map)

    tree_edges = set()

    for e in tree.edges():
        u, v = map(int, e)
        recovered_edges = extract_edges_from_pred(u, v, r2pred[u])
        assert recovered_edges, 'empty!'
        for i, j in recovered_edges:
            tree_edges.add((i, j))

    tree_nodes = list(set(itertools.chain(*tree_edges)))

    if return_type == 'nodes':
        return tree_nodes
    elif return_type == 'edges':
        return list(map(edge2tuple, tree_edges))
    elif return_type == 'tree':
        vfilt = g.new_vertex_property('bool')
        vfilt.set_value(False)
        for n in tree_nodes:
            vfilt[n] = True

        efilt = g.new_edge_property('bool')
        for i, j in tree_edges:
            efilt[g.edge(i, j)] = 1
        subg = GraphView(g, efilt=efilt, vfilt=vfilt, directed=False)

        if p is not None:
            weights = subg.new_edge_property('float')
            for e in subg.edges():
                weights[e] = p[e]
        else:
            weights = None
        # remove cycles
        tree_map = min_spanning_tree(subg, weights, root=None)
        t = GraphView(g, directed=False, vfilt=vfilt, efilt=tree_map)
        return t
Exemplo n.º 9
0
def ratio_of_typed_subjects(D,
                            edge_labels=np.empty(0),
                            stats=dict(),
                            print_stats=False):
    """
        (1) number of all different typed subjects
        (2) ratio of typed subjects
    """

    if edge_labels is None or edge_labels.size == 0:
        edge_labels = np.array([D.ep.c0[p] for p in D.get_edges()])

    # ae98476863dc6ec5 = http://www.w3.org/1999/02/22-rdf-syntax-ns#type
    rdf_type = hash('ae98476863dc6ec5')
    S_C_G = GraphView(D, efilt=edge_labels == rdf_type)
    S_C_G = np.unique(S_C_G.get_edges()[:, 0])

    if print_stats:
        print("number of different typed subjects S^{C}_G: %s" % S_C_G.size)

    S_G = GraphView(D, vfilt=D.get_out_degrees(D.get_vertices()))

    if print_stats:
        print("ratio of typed subjects r_T(G): %s" %
              (float(S_C_G.size) / S_G.num_vertices()))

    stats['typed_subjects'], stats['ratio_of_typed_subjects'] = S_C_G.size, (
        float(S_C_G.size) / S_G.num_vertices())

    return S_C_G
Exemplo n.º 10
0
def f_pseudo_diameter( D, stats, options={ 'features': [] } ):
    """"""

    LC = label_largest_component(D)
    LCD = GraphView( D, vfilt=LC )

    if 'diameter' in options['features']:
        if LCD.num_vertices() == 0 or LCD.num_vertices() == 1:
            # if largest component does practically not exist, use the whole graph
            dist, ends = pseudo_diameter(D)
        else:
            dist, ends = pseudo_diameter(LCD)

        stats['pseudo_diameter']=dist
        # D may be used in both cases
        stats['pseudo_diameter_src_vertex']=D.vertex_properties['name'][ends[0]]
        stats['pseudo_diameter_trg_vertex']=D.vertex_properties['name'][ends[1]]
        log.debug( 'done pseudo_diameter' )
def get_steiner_tree(g, root, obs_nodes, debug=False, verbose=False):
    gc, eweight, r2pred = build_closure(g,
                                        obs_nodes,
                                        debug=debug,
                                        verbose=verbose)

    tree_map = min_spanning_tree(gc, eweight, root=None)
    tree = GraphView(gc, directed=False, efilt=tree_map)

    tree_edges = set()
    for e in tree.edges():
        u, v = map(int, e)
        for i, j in extract_edges_from_pred(g, u, v, r2pred[u]):
            tree_edges.add((j, i))

    # a bit involved...
    und_tree = edges_to_directed_tree(g, root, tree_edges)
    return build_minimum_tree(g, root, obs_nodes, extract_edges(und_tree))
Exemplo n.º 12
0
def egonets(graph, direction):
    egonets = dict()
    for node in graph.vertices():
        mask = graph.new_vertex_property("bool")
        for u in node.out_neighbours():
            mask[u] = True
        mask[node] = True
        label_node = graph.vertex_properties["name"][node]
        egonets[label_node] = GraphView(graph, vfilt=mask)
    return egonets
Exemplo n.º 13
0
def egoNetwork(inGraph, node):
    '''
    Compute the ego-network subgraph of the -inGraph- where the ego is the -node-.    
    Precondition: inGraph is undirected
    '''
    neighbors = [int(n) for n in node.out_neighbours()]
    neighborhood = inGraph.new_vertex_property("bool")
    neighborhood.a[neighbors] = 1
    neighborhood.a[int(node)] = 1
    return GraphView(inGraph, vfilt=neighborhood)
Exemplo n.º 14
0
def number_of_classes(D,
                      edge_labels=np.empty(0),
                      stats=dict(),
                      print_stats=False):
    """counts the number of different classes"""

    if edge_labels is None or edge_labels.size == 0:
        edge_labels = np.array([D.ep.c0[p] for p in D.get_edges()])

    # ae98476863dc6ec5 = http://www.w3.org/1999/02/22-rdf-syntax-ns#type
    rdf_type = hash('ae98476863dc6ec5')
    C_G = GraphView(D, efilt=edge_labels == rdf_type)
    C_G = np.unique(C_G.get_edges()[:, 1])

    if print_stats:
        print("number of different classes C_G: %s" % C_G.size)

    stats['distinct_classes'] = C_G.size

    return C_G
Exemplo n.º 15
0
def produce_answer(entry, g, prune):
    qc_fltr = g.new_vertex_property("bool")
    qc_fltr = make_filter(g, entry.qc, qc_fltr)
    qg = GraphView(g, qc_fltr)
    qg = Graph(qg, prune=prune)

    best_score = 0.0
    answer = -1
    for i, ac in enumerate(entry.ac):
        ac_fltr = g.new_vertex_property("bool")
        ac_fltr = None  #make_filter(g, ac, ac_fltr)
        ag = GraphView(g, ac_fltr)
        ag = Graph(ag, prune=prune)
        score = reason_over_paths(qg, ag)
        if score > best_score:
            best_score = score
            answer = i
        del ac_fltr
    del qc_fltr
    return answer
def observe_cascade(c,
                    source,
                    q,
                    method='uniform',
                    tree=None,
                    source_includable=False):
    """
    given a cascade `c` and `source`,
    return a list of observed nodes according to probability `q`
    """
    all_infection = np.nonzero(c != -1)[0]
    if not source_includable:
        all_infection = list(set(all_infection) - {source})
    num_obs = int(math.ceil(len(all_infection) * q))

    if num_obs < 2:
        num_obs = 2

    if method == 'uniform':
        return np.random.permutation(all_infection)[:num_obs]
    elif method == 'late':
        return np.argsort(c)[-num_obs:]
    elif method == 'leaves':
        assert tree is not None, 'to get the leaves, the cascade tree is required'
        # extract_steiner_tree(tree, )
        nodes_in_order = reverse_bfs(tree)
        return nodes_in_order[:num_obs]
    elif method == 'bfs-head':
        assert tree is not None, 'the cascade tree is required'
        vis = BFSNodeCollector()
        bfs_search(GraphView(tree, directed=False), source, vis)
        sampling_weights_by_order
        vis.nodes_in_order
        return vis.nodes_in_order[:num_obs]  # head
    elif method == 'bfs-tail':
        assert tree is not None, 'the cascade tree is required'
        vis = BFSNodeCollector()
        bfs_search(GraphView(tree, directed=False), source, vis)
        return vis.nodes_in_order[-num_obs:]  # tail
    else:
        raise ValueError('unknown method {}'.format(method))
def is_order_respected(tree, root, obs_nodes, infection_times):
    tree = GraphView(tree)
    obs_set = set(obs_nodes)
    vfilt = tree.new_vertex_property('bool')
    vfilt.a = True
    tree.set_vertex_filter(vfilt)

    leaves = [o for o in obs_nodes if tree.vertex(o).out_degree() == 0]
    vis = init_visitor(tree, root)
    pbfs_search(tree, root, terminals=leaves, visitor=vis, count_threshold=-1)
    for l in leaves:
        edges = extract_edges_from_pred(tree, root, l, vis.pred)
        edges = edges[::-1]
        path = list(edges[0]) + [u for _, u in edges[1:]]
        useful_nodes_on_path = [v for v in path if v in obs_set]

        for i in range(len(useful_nodes_on_path)-1):
            u, v = useful_nodes_on_path[i: i+2]
            if infection_times[u] > infection_times[v]:
                return False
    return True
Exemplo n.º 18
0
def global_clustering_binary_undirected(g):
    '''
    Returns the undirected global clustering coefficient.

    This corresponds to the ratio of undirected triangles to the number of
    undirected triads.

    Parameters
    ----------
    g : :class:`~nngt.Graph`
        Graph to analyze.

    References
    ----------
    .. [gt-global-clustering] :gtdoc:`clustering.global_clustering`
    '''
    # use undirected graph view, filter parallel edges
    u = GraphView(g.graph, directed=False)
    u = GraphView(u, efilt=label_parallel_edges(u).fa == 0)

    return gtc.global_clustering(u, weight=None)[0]
Exemplo n.º 19
0
        def solve(g):
            if g.num_vertices() == 0:
                W0 = self.pg.new_vertex_property("bool")
                W1 = self.pg.new_vertex_property("bool")
                return {0: W0, 1: W1}
            else:
                p = self.maxparity(g)
                i = p % 2

                U = self.vertices_with_priority(g, p)

                A = self.attractor(U, i)  # get i attractor of U in g
                WW = solve(GraphView(g, vfilt=self.complement(A)))

                #if WW[1-i].ma.all():  ## does not work
                gg = GraphView(g, vfilt=WW[1 - i])  # just to check emptiness
                if gg.num_vertices() == 0:
                    res = {}
                    res[i] = self.maskplus(g, WW[i], A)
                    res[1 - i] = WW[1 - i]
                    return res
                else:
                    B = self.attractor(WW[1 - i], 1 - i)
                    gg = GraphView(g, vfilt=self.complement(B))
                    WW = solve(gg)

                    res = {}
                    res[i] = WW[i]
                    res[1 - i] = self.maskplus(g, WW[1 - i], B)
                    return res
Exemplo n.º 20
0
    def save(self, file_name, fmt="auto"):
        """ overload Graph.save to make output dotfiles pretty.
            This is entirely cosmetic. """
        u = self

        # add some properties to prettify dot output
        if fmt is "dot" or fmt is "auto" and file_name.endswith(".dot"):
            u = GraphView(self)

            # add shape property according to vertex owners
            shape = u.new_vertex_property("string")
            for v in u.vertices():
                if u.vp.owner[v] == 1:
                    shape[v] = "box"
                else:
                    shape[v] = "diamond"
            u.vp.shape = shape

            # add label property according to priorities
            #u.vertex_properties['label'] = u.vertex_properties['priority']
            label = u.new_vertex_property("string")
            for v in u.vertices():
                prio = u.vertex_properties['priority'][v]
                name = u.vertex_index[v]
                label[v] = "%d (%d)" % (name, prio)
            u.vp.label = label

        Graph.save(u, file_name, fmt)
def is_tree(tree):
    # is tree?
    l, _ = label_components(GraphView(tree, directed=False))
    if not np.all(np.array(l.a) == 0):
        print('not connected')
        print(np.array(l.a))
        return False

    if tree.num_edges() != (tree.num_vertices() - 1):
        print('n. edges != n. nodes - 1')
        return False
    
    return True
Exemplo n.º 22
0
 def get(self, args):
   from depth_first_searcher import dfs_search_with_limit
   root = int(args["root"])
   limit = int(args["limit"])
   vertices = dfs_search_with_limit(graph, graph.vertex(root), limit)
   v_filter = graph.new_vertex_property('bool')
   for v in vertices:
     v_filter[v] = True
   subgraph = GraphView(graph, v_filter)
   from graph_tool.stats import remove_parallel_edges
   remove_parallel_edges(subgraph)
   subgraph = self.set_properties(subgraph)
   from graph_json_builder import create_json_graph
   return create_json_graph(subgraph)
Exemplo n.º 23
0
def repeated_predicate_lists(D,
                             edge_labels=np.empty(0),
                             stats=dict(),
                             print_stats=False,
                             return_collected=True):
    """"""

    if edge_labels is None or edge_labels.size == 0:
        edge_labels = [D.ep.c0[p] for p in D.get_edges()]

    # filter those vertices v | out-degree(v) > 0
    S = GraphView(D, vfilt=D.get_out_degrees(D.get_vertices()))

    # .. is defined as the ratio of repeated predicate lists from the total lists in the graph G
    df = pd.DataFrame(data=list(zip(D.get_edges()[:, 0], edge_labels)),
                      index=np.arange(0,
                                      D.get_edges().shape[0]),
                      columns=np.arange(0,
                                        D.get_edges().shape[1]))

    df = df.groupby(0)[1].apply(tuple).apply(hash).to_frame().reset_index()

    if return_collected:
        df = df.groupby(1).count()[0]

        if print_stats:
            print("(Eq.17) ratio of repeated predicate lists r_L(G): %f" %
                  (1 - (df.size / S.num_vertices())))
            print(
                "(Eq.18/19) predicate list degree deg_{PL}(G). max: %f, mean: %f"
                % (df.max(), df.mean()))

        stats['repeated_predicate_lists'] = 1 - (df.size / S.num_vertices())
        stats['max_predicate_list_degree'], stats[
            'mean_predicate_list_degree'] = df.max(), df.mean()

    return df
def sample_graph_by_p(g, p):
    """
    for IC model
    graph_tool version of sampling a graph
    mask the edge according to probability p and return the masked graph

    g: the graph
    p: float or np.array
    """
    if isinstance(p, PropertyMap):
        p = p.a
    flags = (np.random.random(p.shape) <= p)
    p = g.new_edge_property('bool')
    p.set_2d_array(flags)
    return GraphView(g, efilt=p)
def remove_filters(g):
    """
    remove all filters and add filter with all entries on

    so that we won't get null vertex_filter or edge_filter
    """
    efilt = g.new_edge_property('bool')
    efilt.a = True
    vfilt = g.new_vertex_property('bool')
    vfilt.a = True

    # print('making GraphView started')
    gv = GraphView(g, efilt=efilt, vfilt=vfilt, directed=g.is_directed())
    # print('making GraphView done')
    return gv
def filter_graph_by_edges(g, edges):
    """returns GraphView
    """
    efilt = g.new_edge_property('bool')
    efilt.set_value(False)

    for i, j in edges:
        efilt[g.edge(i, j)] = True

    vfilt = g.new_vertex_property('bool')
    vfilt.set_value(False)
    for e in edges:
        for u in e:
            vfilt[u] = True

    return GraphView(g, efilt=efilt, vfilt=vfilt)
Exemplo n.º 27
0
    def get_subgraph(self, vertices, genes=False):
        r'''
        Return the subgraph of self induced by the given vertices.

        Args:
            vertices: a set of vertex IDs (or a set of genes)
            genes: a boolean with value `True` if `vertices` is a set of genes
                and `False` if it is a set of vertex IDs.

        Returns:
            :math:`\Delta_{\text{vertices}}(G)`
        '''
        if genes:
            vertices = self.verts_id(vertices)
        filt = self.G.new_vertex_property('bool')
        filt.a[vertices] = True
        return GraphView(self.G, vfilt=filt)
def is_arborescence(tree):
    # is tree?
    l, _ = label_components(GraphView(tree, directed=False))
    if not np.all(np.array(l.a) == 0):
        print('not connected')
        print(np.array(l.a))
        return False

    in_degs = np.array([v.in_degree() for v in tree.vertices()])
    if in_degs.max() > 1:
        print('in_degree.max() > 1')
        return False
    if np.sum(in_degs == 1) != (tree.num_vertices() - 1):
        print('should be: only root has no parent')
        return False

    roots = get_roots(tree)
    assert len(roots) == 1, '>1 roots'
    
    return True
def is_tree(t):
    # to undirected
    t = GraphView(t, directed=False)

    # num nodes = num edges+1
    if t.num_vertices() != (t.num_edges() + 1):
        return False

    # all nodes have degree > 0
    vs = list(map(int, t.vertices()))
    degs = t.degree_property_map('out').a[vs]
    if np.all(degs > 0) == 0:
        return False

    return True
Exemplo n.º 30
0
def extract_tree(g, source, pred, terminals=None):
    """return a tree from source to terminals based on `pred`"""
    edges = set()

    if terminals:
        visited = set()
        for t in sorted(terminals):
            c = t
            while c != source and c not in visited:
                visited.add(c)
                if pred[c] != -1:
                    edges.add((pred[c], c))
                    c = pred[c]
                else:
                    break
    else:
        for c, p in enumerate(pred.a):
            if p != -1:
                edges.add((c, p))
    efilt = g.new_edge_property('bool')
    for u, v in edges:
        efilt[g.edge(g.vertex(u), g.vertex(v))] = 1
    return GraphView(g, efilt=efilt)
Exemplo n.º 31
0
    def minimum_spanning_tree(self,
                              distance,
                              write=False,
                              write_property=None):
        """Compute the minimum spanning tree.

        Parameters
        ----------
        distance : str
            Distance to minimize when computing the minimum spanning tree
            (MST)
        write : bool, optional
            Flag indicating whether the MST should be returned as
            a new graph
            object or saved within a Boolean edge property being True whenever
            a given edge belongs to the MST.
        write_property : str, optional
            Edge property name for marking edges beloning to the MST.

        Returns
        -------
        tree : nx.Graph
            The minimum spanning tree graph object
        """
        mst_property = min_spanning_tree(self.graph,
                                         weights=self.graph.ep[distance])
        if write:
            if write_property is None:
                raise PathFinder.PathSearchException(
                    "The minimum spanning tree finder has the write option set "
                    "to True, the write property name must be specified")

            self.graph.ep[write_property] = mst_property
        else:
            tree = GraphView(self.graph, efilt=mst_property)
            return tree
def is_order_respected(tree, root, obs_nodes, infection_times):
    tree = GraphView(tree)
    obs_set = set(obs_nodes)
    vfilt = tree.new_vertex_property('bool')
    vfilt.a = True
    tree.set_vertex_filter(vfilt)

    leaves = [o for o in obs_nodes if tree.vertex(o).out_degree() == 0]
    vis = init_visitor(tree, root)
    pbfs_search(tree, root, terminals=leaves, visitor=vis, count_threshold=-1)
    for l in leaves:
        edges = extract_edges_from_pred(tree, root, l, vis.pred)
        edges = edges[::-1]
        path = list(edges[0]) + [u for _, u in edges[1:]]
        useful_nodes_on_path = [v for v in path if v in obs_set]

        for i in range(len(useful_nodes_on_path)-1):
            u, v = useful_nodes_on_path[i: i+2]
            if infection_times[u] > infection_times[v]:
                return False
    return True