Ticket #7528: trac_7528.patch

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

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1260022794 -3600
    # Node ID 9e9369ded04860639298f8e4a46b506f054fae3b
    # Parent  18a4ec53e18a7dd51639dc0ea4f3bd9541430e32
    Graph.minimum_outdegree_orientation()
    
    diff -r 18a4ec53e18a -r 9e9369ded048 sage/graphs/graph.py
    a b  
    22062206                else:
    22072207                    return d
    22082208
     2209    def minimum_outdegree_orientation(self, use_edge_labels=False):
     2210        r"""
     2211        Returns a DiGraph which is an orientation with the smallest
     2212        possible maximum outdegree of the current graph.
     2213
     2214        Given a Graph `G`, is is polynomial to compute an orientation
     2215        `D` of the edges of `G` such that the maximum out-degree in `D`
     2216         is minimized. This problem, though, is NP-complete in the
     2217        weighted case [AMOZ06]_.
     2218
     2219        INPUT:
     2220
     2221        - ``use_edge_labels`` (boolean)
     2222
     2223            - When set to ``True``, uses edge labels as weights to
     2224              compute the orientation and assumes a weight of `1`
     2225              when there is no value available for a given edge.
     2226
     2227            - When set to ``False`` (default), gives a weight of 1
     2228              to all the edges.       
     2229
     2230        EXAMPLE:
     2231
     2232        Given a complete bipartite graph `K_{n,m}`, the maximum out-degree
     2233        of an optimal orientation is
     2234        `\left\lceil \frac {nm} {n+m}\right\rceil`::
     2235
     2236            sage: g = graphs.CompleteBipartiteGraph(3,4)
     2237            sage: o = g.minimum_outdegree_orientation() # optional - requires GLPK or CBC
     2238            sage: max(o.out_degree()) == ceil((4*3)/(3+4)) # optional - requires GLPK or CBC
     2239            True
     2240
     2241
     2242
     2243        REFERENCES:
     2244       
     2245        .. [AMOZ06] Asahiro, Y. and Miyano, E. and Ono, H. and Zenmyo, K.
     2246          Graph orientation algorithms to minimize the maximum outdegree
     2247          Proceedings of the 12th Computing: The Australasian Theroy Symposium
     2248          Volume 51, page 20
     2249          Australian Computer Society, Inc. 2006
     2250
     2251        """
     2252
     2253        if self.is_directed():
     2254            raise ValueError("Cannot compute an orientation of a DiGraph. "+\
     2255                                 "Please convert it to a Graph if you really mean it.")
     2256
     2257        if use_edge_labels:
     2258            weight = lambda u,v : self.edge_label(u,v) if self.edge_label(u,v)!=None else 1
     2259        else:
     2260            weight = lambda u,v : 1
     2261
     2262        from sage.numerical.mip import MixedIntegerLinearProgram
     2263       
     2264        p = MixedIntegerLinearProgram(maximization=False)
     2265
     2266        # The orientation of an edge is boolean
     2267        # and indicates whether the edge uv
     2268        # with u<v goes from u to v ( equal to 0 )
     2269        # or from v to u ( equal to 1)
     2270        orientation = p.new_variable(dim=2)
     2271       
     2272        degree = p.new_variable()
     2273
     2274        # Whether an edge adjacent to a vertex u counts
     2275        # positively or negatively
     2276        outgoing = lambda u,v,variable : (1-variable) if u>v else variable
     2277       
     2278        for u in self:
     2279            p.add_constraint(sum([weight(u,v)*outgoing(u,v,orientation[min(u,v)][max(u,v)]) for v in self.neighbors(u)])-degree['max'],max=0)
     2280
     2281        p.set_objective(degree['max'])
     2282
     2283        p.set_binary(orientation)
     2284
     2285        p.solve()
     2286
     2287        orientation = p.get_values(orientation)
     2288
     2289        # All the edges from self are doubled in O
     2290        # ( one in each direction )
     2291        O = DiGraph(self)
     2292
     2293        # Builds the list of edges that should be removed
     2294        edges=[]
     2295
     2296        for u,v in self.edge_iterator(labels=None):
     2297            # assumes u<v
     2298            if u>v:
     2299                u,v=v,u
     2300
     2301            if orientation[min(u,v)][max(u,v)] == 1:
     2302                edges.append((max(u,v),min(u,v)))
     2303            else:
     2304                edges.append((min(u,v),max(u,v)))
     2305
     2306        O.delete_edges(edges)
     2307
     2308        return O       
     2309
    22092310    ### Planarity
    22102311
    22112312    def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, set_pos=False):