Ticket #7594: trac_7594.patch

File trac_7594.patch, 3.7 KB (added by ncohen, 11 years ago)
  • sage/graphs/graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1249573009 25200
    # Node ID 3b89427f6ea37f47e08750fb167dec887edd46f8
    # Parent  fd8e478f4c9d226e5b6df665da65a8bd82e71c5b
    Graph.dominating_set
    
    diff -r fd8e478f4c9d -r 3b89427f6ea3 sage/graphs/graph.py
    a b  
    32543254            v = pv
    32553255        return B, C
    32563256
     3257    def dominating_set(self, independent=False, value_only=False,log=0):
     3258        r"""
     3259        Returns a minimum dominating set of the graph
     3260        ( cf. http://en.wikipedia.org/wiki/Dominating_set )
     3261        represented by the list of its vertices.
     3262
     3263        A minimum dominating set `S` of a graph `G` is
     3264        a set of its vertices of minimal cardinality such
     3265        that any vertex of `G` is in `S` or has one of its neighbors
     3266        in `S`.
     3267       
     3268        As an optimization problem, it can be expressed as :
     3269
     3270        .. MATH::
     3271            \mbox{Minimize : }&\sum_{v\in G} b_v\\
     3272            \mbox{Such that : }&\forall v \in G, b_v+\sum_{(u,v)\in G.edges()} b_u\geq 1\\
     3273            &\forall x\in G, b_x\mbox{ is a binary variable}
     3274   
     3275        INPUT:
     3276       
     3277        - ``value_only`` (boolean)
     3278
     3279           - If ``True``, only the cardinality of a minimum
     3280              dominating set is returned.
     3281           - If ``False`` ( default ), a minimum dominating set
     3282             is returned as the list of its vertices.
     3283
     3284        - ``independent`` (boolean)
     3285            - If ``True``, computes a minimum independent
     3286              dominating set.
     3287   
     3288        - ``log`` (integer)
     3289          As minimum dominating set is a `NP`-complete problem, its
     3290          solving may take some time depending on the graph. Use
     3291          ``log`` to define the level of verbosity you want from the linear program solver.
     3292         
     3293          By default ``log=0``, meaning that there will be no message printed by the solver.
     3294   
     3295        EXAMPLE:
     3296
     3297        A basic illustration on a ``PappusGraph`` ::
     3298       
     3299           sage: g=graphs.PappusGraph()
     3300           sage: g.dominating_set(value_only=True)    # optional - requires Glpk or COIN-OR/CBC
     3301           5.0
     3302
     3303        If we build a graph from two disjoint stars, then link their centers
     3304        we will find a difference between the cardinality of an independent set
     3305        and a stable independent set ::
     3306
     3307           sage: g = 2 * graphs.StarGraph(5)
     3308           sage: g.add_edge(0,6)
     3309           sage: len(g.dominating_set())                       # optional - requires Glpk or COIN-OR/CBC
     3310           2
     3311           sage: len(g.dominating_set(independent=True))       # optional - requires Glpk or COIN-OR/CBC
     3312           6
     3313   
     3314        """
     3315        from sage.numerical.mip import MixedIntegerLinearProgram
     3316        g=self
     3317        p=MixedIntegerLinearProgram(maximization=False)
     3318        b=p.new_variable()
     3319       
     3320        # For any vertex v, one of its neighbors or v itself is in
     3321        # the minimum dominating set
     3322        [p.add_constraint(b[v]+sum([b[u] for u in g.neighbors(v)]),min=1) for v in g.vertices()]
     3323
     3324
     3325        if independent:
     3326            # no two adjacent vertices are in the set
     3327            [p.add_constraint(b[u]+b[v],max=1) for (u,v) in g.edges(labels=None)]
     3328
     3329        # Minimizes the number of vertices used
     3330        p.set_objective(sum([b[v] for v in g.vertices()]))
     3331
     3332        p.set_integer(b)
     3333
     3334        if value_only:
     3335            return p.solve(objective_only=True,log=log)
     3336        else:
     3337            obj=p.solve(log=log)
     3338            b=p.get_values(b)
     3339            return [v for v in g.vertices() if b[v]==1]
     3340
    32573341    ### Vertex handlers
    32583342
    32593343    def add_vertex(self, name=None):