Changeset 2ca0c3


Ignore:
Timestamp:
06/04/12 17:36:59 (13 months ago)
Author:
Tiago de Paula Peixoto <tiago@…>
Branches:
master
Children:
ebc00a
Parents:
fa8ca4
git-author:
Tiago de Paula Peixoto <tiago@…> (06/04/12 17:22:05)
git-committer:
Tiago de Paula Peixoto <tiago@…> (06/04/12 17:36:59)
Message:
Implement random_spanning_tree() and label_out_component()
Location:
src
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • src/graph/topology/Makefile.am

    rfa8ca4 r2ca0c3  
    2727    graph_planar.cc \ 
    2828    graph_random_matching.cc \ 
     29    graph_random_spanning_tree.cc \ 
    2930    graph_reciprocity.cc \ 
    3031    graph_similarity.cc \ 
  • src/graph/topology/graph_components.cc

    r6b0e17 r2ca0c3  
    5151} 
    5252 
     53void do_label_out_component(GraphInterface& gi, size_t root, boost::any prop) 
     54{ 
     55    run_action<>()(gi, bind<void>(label_out_component(), _1, _2, root), 
     56                   writable_vertex_scalar_properties())(prop); 
     57} 
     58 
    5359void export_components() 
    5460{ 
     
    5662    python::def("label_biconnected_components", 
    5763                &do_label_biconnected_components); 
     64    python::def("label_out_component", &do_label_out_component); 
    5865}; 
  • src/graph/topology/graph_components.hh

    rde6e73 r2ca0c3  
    6464 
    6565        vector<size_t>& h = _hist; 
    66         size_t bin = v;         
     66        size_t bin = v; 
    6767        if (bin > _max) 
    6868            return; 
     
    161161 
    162162 
     163struct label_out_component 
     164{ 
     165    template <class CompMap> 
     166    class marker_visitor: public bfs_visitor<> 
     167    { 
     168    public: 
     169        marker_visitor() { } 
     170        marker_visitor(CompMap comp) : _comp(comp) { } 
     171 
     172        template <class Vertex, class Graph> 
     173        void discover_vertex(Vertex u, const Graph& g) 
     174        { 
     175            _comp[u] = true; 
     176        } 
     177    private: 
     178        CompMap _comp; 
     179    }; 
     180 
     181    template <class Graph, class CompMap> 
     182    void operator()(const Graph& g, CompMap comp_map, size_t root) const 
     183    { 
     184        marker_visitor<CompMap> marker(comp_map); 
     185        breadth_first_search(g, vertex(root, g), visitor(marker)); 
     186    } 
     187}; 
     188 
     189 
    163190} // graph_tool namespace 
    164191 
  • src/graph/topology/graph_topology.cc

    rfa8ca4 r2ca0c3  
    4040double reciprocity(GraphInterface& gi); 
    4141bool is_bipartite(GraphInterface& gi, boost::any part_map); 
     42void get_random_spanning_tree(GraphInterface& gi, size_t root, 
     43                              boost::any weight_map, boost::any tree_map, 
     44                              size_t seed); 
    4245 
    4346void export_components(); 
     
    6265    def("reciprocity", &reciprocity); 
    6366    def("is_bipartite", &is_bipartite); 
     67    def("random_spanning_tree", &get_random_spanning_tree); 
    6468    export_components(); 
    6569    export_similarity(); 
  • src/graph_tool/topology/__init__.py

    rfa8ca4 r2ca0c3  
    3939   max_independent_vertex_set 
    4040   min_spanning_tree 
     41   random_spanning_tree 
    4142   dominator_tree 
    4243   topological_sort 
     
    4546   label_biconnected_components 
    4647   label_largest_component 
     48   label_out_component 
    4749   is_bipartite 
    4850   is_planar 
     
    6567__all__ = ["isomorphism", "subgraph_isomorphism", "mark_subgraph", 
    6668           "max_cardinality_matching", "max_independent_vertex_set", 
    67            "min_spanning_tree", "dominator_tree", "topological_sort", 
    68            "transitive_closure", "label_components", "label_largest_component", 
    69            "label_biconnected_components", "shortest_distance", "shortest_path", 
    70            "pseudo_diameter", "is_bipartite", "is_planar", "similarity", "edge_reciprocity"] 
     69           "min_spanning_tree", "random_spanning_tree", "dominator_tree", 
     70           "topological_sort", "transitive_closure", "label_components", 
     71           "label_largest_component", "label_biconnected_components", 
     72           "label_out_component", "shortest_distance", "shortest_path", 
     73           "pseudo_diameter", "is_bipartite", "is_planar", "similarity", 
     74           "edge_reciprocity"] 
    7175 
    7276 
     
    285289    g : :class:`~graph_tool.Graph` 
    286290        Graph to be used. 
    287     weights : :class:`~graph_tool.PropertyMap` (optional, default: None) 
     291    weights : :class:`~graph_tool.PropertyMap` (optional, default: `None`) 
    288292        The edge weights. If provided, the minimum spanning tree will minimize 
    289293        the edge weights. 
    290     root : :class:`~graph_tool.Vertex` (optional, default: None) 
     294    root : :class:`~graph_tool.Vertex` (optional, default: `None`) 
    291295        Root of the minimum spanning tree. If this is provided, Prim's algorithm 
    292296        is used. Otherwise, Kruskal's algorithm is used. 
    293     tree_map : :class:`~graph_tool.PropertyMap` (optional, default: None) 
     297    tree_map : :class:`~graph_tool.PropertyMap` (optional, default: `None`) 
    294298        If provided, the edge tree map will be written in this property map. 
    295299 
     
    362366 
    363367 
     368def random_spanning_tree(g, weights=None, root=None, tree_map=None): 
     369    """ 
     370    Return a random spanning tree of a given graph, which can be directed or 
     371    undirected. 
     372 
     373    Parameters 
     374    ---------- 
     375    g : :class:`~graph_tool.Graph` 
     376        Graph to be used. 
     377    weights : :class:`~graph_tool.PropertyMap` (optional, default: `None`) 
     378        The edge weights. If provided, the probability of a particular spanning 
     379        tree being selected is the product of its edge weights. 
     380    root : :class:`~graph_tool.Vertex` (optional, default: `None`) 
     381        Root of the spanning tree. If not provided, it will be selected randomly. 
     382    tree_map : :class:`~graph_tool.PropertyMap` (optional, default: `None`) 
     383        If provided, the edge tree map will be written in this property map. 
     384 
     385    Returns 
     386    ------- 
     387    tree_map : :class:`~graph_tool.PropertyMap` 
     388        Edge property map with mark the tree edges: 1 for tree edge, 0 
     389        otherwise. 
     390 
     391    Notes 
     392    ----- 
     393    The typical running time for random graphs is :math:`O(N\log N)`. 
     394 
     395    Examples 
     396    -------- 
     397    >>> from numpy.random import seed, random 
     398    >>> seed(42) 
     399    >>> g, pos = gt.triangulation(random((400, 2)) * 10, type="delaunay") 
     400    >>> weight = g.new_edge_property("double") 
     401    >>> for e in g.edges(): 
     402    ...    weight[e] = linalg.norm(pos[e.target()].a - pos[e.source()].a) 
     403    >>> tree = gt.random_spanning_tree(g, weights=weight) 
     404    >>> gt.graph_draw(g, pos=pos, output="rtriang_orig.pdf") 
     405    <...> 
     406    >>> g.set_edge_filter(tree) 
     407    >>> gt.graph_draw(g, pos=pos, output="triang_min_span_tree.pdf") 
     408    <...> 
     409 
     410 
     411    .. image:: rtriang_orig.* 
     412        :width: 400px 
     413    .. image:: triang_random_span_tree.* 
     414        :width: 400px 
     415 
     416    *Left:* Original graph, *Right:* A random spanning tree. 
     417 
     418    References 
     419    ---------- 
     420 
     421    .. [wilson-generating-1996] David Bruce Wilson, "Generating random spanning 
     422       trees more quickly than the cover time", Proceedings of the twenty-eighth 
     423       annual ACM symposium on Theory of computing, Pages 296-303, ACM New York, 
     424       1996, :doi:`10.1145/237814.237880` 
     425    .. [boost-rst] http://www.boost.org/libs/graph/doc/random_spanning_tree.html 
     426    """ 
     427    if tree_map is None: 
     428        tree_map = g.new_edge_property("bool") 
     429    if tree_map.value_type() != "bool": 
     430        raise ValueError("edge property 'tree_map' must be of value type bool.") 
     431 
     432    if root is None: 
     433        root = g.vertex(numpy.random.randint(0, g.num_vertices()), 
     434                        use_index=False) 
     435 
     436    # we need to restrict ourselves to the in-component of root 
     437    l = label_out_component(GraphView(g, reversed=True), root) 
     438    g = GraphView(g, vfilt=l) 
     439 
     440    seed = numpy.random.randint(0, sys.maxsize) 
     441    libgraph_tool_topology.\ 
     442        random_spanning_tree(g._Graph__graph, int(root), 
     443                             _prop("e", g, weights), 
     444                             _prop("e", g, tree_map), seed) 
     445    return tree_map 
     446 
     447 
    364448def dominator_tree(g, root, dom_map=None): 
    365449    """Return a vertex property map the dominator vertices for each vertex. 
     
    598682    else: 
    599683        label.a = (c.a == h.argmax()) & (vfilt.a ^ inv) 
     684    return label 
     685 
     686 
     687def label_out_component(g, root): 
     688    """ 
     689    Label the out-component (or simply the component for undirected graphs) of a 
     690    root vertex. 
     691 
     692    Parameters 
     693    ---------- 
     694    g : :class:`~graph_tool.Graph` 
     695        Graph to be used. 
     696    root : :class:`~graph_tool.Vertex` 
     697        The root vertex. 
     698 
     699    Returns 
     700    ------- 
     701    comp : :class:`~graph_tool.PropertyMap` 
     702         Boolean vertex property map which labels the out-component. 
     703 
     704    Notes 
     705    ----- 
     706    The algorithm runs in :math:`O(V + E)` time. 
     707 
     708    Examples 
     709    -------- 
     710    >>> from numpy.random import seed, poisson 
     711    >>> seed(43) 
     712    >>> g = gt.random_graph(100, lambda: poisson(1), directed=False) 
     713    >>> l = gt.label_out_component(g, g.vertex(0)) 
     714    >>> print(l.a) 
     715    [1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 
     716     1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 
     717     0 0 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0] 
     718 
     719    The in-component can be obtained by reversing the graph. 
     720 
     721    >>> l = gt.label_out_component(GraphView(g, reversed=True), g.vertex(0)) 
     722    >>> print(l.a) 
     723    [1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 
     724     1 1 0 0 0 0 1 0 1 1 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 
     725     0 0 0 1 1 0 1 1 0 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0] 
     726    """ 
     727 
     728    label = g.new_vertex_property("bool") 
     729    libgraph_tool_topology.\ 
     730             label_out_component(g._Graph__graph, int(root), 
     731                                 _prop("v", g, label)) 
    600732    return label 
    601733 
Note: See TracChangeset for help on using the changeset viewer.