Ticket #7294: trac_7294.patch

File trac_7294.patch, 3.3 KB (added by ncohen, 10 years ago)
  • sage/graphs/graph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1257095161 -3600
    # Node ID 127d1815434e1bf4d27f01836569c4a4add3bc00
    # Parent  f8413793dd4ffbd88312368e031e45b653cf205e
     degree constrined subgraph in Graph class
    
    diff -r f8413793dd4f -r 127d1815434e sage/graphs/graph.py
    a b  
    98269826        except:
    98279827            return False
    98289828
     9829    def degree_constrained_subgraph(self, bounds=None):
     9830        r"""
     9831        Returns a degree-constrained subgraph.
     9832
     9833        Given a graph `G` and two functions `f, g:V(G)\rightarrow \mathbb Z`
     9834        such that `f \leq g`, a degree-constrained subgraph in `G` is
     9835        a subgraph `G' \subseteq G` such that for any vertex `v \in G`,
     9836        `f(v) \leq d_{G'}(v) \leq g(v)`.
     9837
     9838        INPUT:
     9839
     9840        - ``bounds`` -- Two possibilities :
     9841            - A dictionary whose keys are the vertices, and values a pair of
     9842              real values ``(min,max)`` corresponding to the values `(f(v),g(v))`.
     9843            - A function associating to each vertex a pair of
     9844              real values ``(min,max)`` corresponding to the values `(f(v),g(v))`.
     9845
     9846        OUTPUT:
     9847
     9848        - When a solution exists, this method outputs the degree-constained subgraph
     9849          as a Graph object.
     9850        - When no solution exists, returns ``False``
     9851
     9852        NOTES:
     9853
     9854        - This algorithm computes the degree-constrained subgraph of minimum weight.
     9855        - If the graph's edges are weighted, these are taken into account.
     9856        - This problem can be solved in polynomial time.
     9857
     9858        EXAMPLES ::
     9859
     9860        Is there a perfect matching in an even cycle ?
     9861
     9862            sage: g = graphs.CycleGraph(6)
     9863            sage: bounds = lambda x : [1,1]
     9864            sage: m=g.degree_constrained_subgraph(bounds=bounds) # optional - requires GLPK or CBC
     9865            sage: m.size()
     9866            3
     9867        """
     9868
     9869        from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException
     9870
     9871        p = MixedIntegerLinearProgram(maximization=False)
     9872        b = p.new_variable()
     9873
     9874        reorder = lambda x: (min(x[0],x[1]),max(x[0],x[1]),x[2])
     9875
     9876        if bounds == None:
     9877            raise ValueError,"The `bounds` keyword can not be equal to None"
     9878        elif isinstance(bounds,dict):
     9879            f_bounds = lambda x : bounds[x]
     9880        else:
     9881            f_bounds = bounds
     9882           
     9883
     9884        if self.weighted():
     9885            weight = lambda x: x[2] if x[2] != None else 1
     9886        else:
     9887            weight = lambda x: 1
     9888
     9889        for v in self:
     9890            minimum,maximum = f_bounds(v)
     9891            p.add_constraint(sum([ b[reorder(e)]*weight(e) for e in self.edges_incident(v)]),min=minimum, max=maximum)
     9892       
     9893        p.set_objective(sum([ b[reorder(e)]*weight(e) for e in self.edge_iterator()]))
     9894        p.set_binary(b)
     9895
     9896        try:
     9897            p.solve()
     9898            g = self.copy()
     9899            b = p.get_values(b)
     9900            g.delete_edges([e for e in g.edge_iterator() if b[reorder(e)] == 0])
     9901            return g
     9902           
     9903       
     9904        except MIPSolverException:
     9905            return False
     9906           
     9907
     9908       
     9909       
     9910
    98299911    ### Coloring
    98309912
    98319913    def bipartite_color(self):