Ticket #10044: trac_10044.patch

File trac_10044.patch, 4.8 KB (added by ncohen, 9 years ago)
  • sage/graphs/generic_graph_pyx.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1285889116 -7200
    # Node ID 3f18ff19f41a73e50f52d8a0ad0da2b8aba401c5
    # Parent  5c9ed0fbc0efa3956f509f6cfccc6039eeb8ac1a
    trac 10044 -- Fractional Chromatic Index
    
    diff -r 5c9ed0fbc0ef -r 3f18ff19f41a sage/graphs/generic_graph_pyx.pyx
    a b  
    11551155    return []
    11561156
    11571157
     1158##############################
     1159# Fractional Chromatic index #
     1160##############################
     1161
     1162cpdef fractional_chromatic_index(gr, constraint_log = 0,solver_log = 0):
     1163    r"""
     1164    Computes the fractional chromatic index of ``gr``
     1165
     1166    INPUT:
     1167
     1168    - ``gr`` -- a graph
     1169
     1170    - ``constraint_log`` -- whether to print information on the
     1171      constraints generated
     1172
     1173    - ``solver_log`` -- level of verbosity required from the solver
     1174
     1175
     1176    TODO:
     1177
     1178    Can be improved by computing matchings through a LP formulation,
     1179    and not using the Python implementation of Edmonds' algorithm
     1180    (which requires to copy the graph, etc). With a LP formulation, as
     1181    we are computing a matching at each loop by only changing the
     1182    weight of the vertices, it is more efficient to create a LP and
     1183    update its costs at each turn.
     1184
     1185    EXAMPLE:
     1186
     1187    The fractional chromatic index of a `C_5` is `5/2`::
     1188
     1189        sage: from sage.graphs.generic_graph_pyx import fractional_chromatic_index
     1190        sage: g = graphs.CycleGraph(5)
     1191        sage: fractional_chromatic_index(g)
     1192        2.5
     1193    """
     1194
     1195    g = gr.copy()
     1196    cdef int m = g.size()
     1197    cdef list indices
     1198    cdef list values
     1199    cdef float weight
     1200    cdef list matching
     1201    cdef int i
     1202
     1203    # Associating its variable number to each edge of the graph
     1204    cdef dict edge_id = dict( [(x,y) for (y,x)
     1205                               in enumerate(g.edges(labels = False))] )
     1206
     1207    cdef GenericBackend p
     1208    from sage.numerical.backends.generic_backend import get_solver
     1209    p = get_solver()
     1210
     1211    p.add_variables(m)
     1212    p.set_sense(+1)
     1213
     1214    p.set_objective([1]*m)
     1215
     1216    p.set_verbosity(solver_log)
     1217
     1218    # Let us add, as our first set of matching, a singleton for each
     1219    # edge
     1220
     1221    for 0 <= i < m:
     1222        p.add_linear_constraint([i], [1], 1, 1)
     1223
     1224    p.solve()
     1225
     1226    while (1):
     1227        # Computing a matching of maximum weight...
     1228
     1229        # Updating the value on the edges of g
     1230        for u,v in g.edges(labels = False):
     1231            g.set_edge_label(u,v,p.get_variable_value(edge_id[(u,v)]))
     1232
     1233        matching = g.matching()
     1234
     1235        # Summing the weights
     1236        weight = 0
     1237        for u,v,_ in matching:
     1238            weight += g.edge_label(u,v)
     1239
     1240
     1241        # If the maximum matching has weight at most 1, we are done !
     1242        if weight <= 1:
     1243            break
     1244
     1245        # Otherwise, we add it..
     1246
     1247        if constraint_log:
     1248            print "Adding a constraint on matching : ",matching
     1249
     1250        indices = []
     1251        for u,v,_ in matching:
     1252            indices.append(edge_id[(u,v)])
     1253
     1254        values = [1] * len(indices)
     1255        p.add_linear_constraint(indices, values, 1, 1)
     1256
     1257        # And solve again
     1258        p.solve()
     1259
     1260    # Getting the objective back
     1261    obj = p.get_objective_value()
     1262
     1263    # Accomplished !
     1264    return obj
     1265
     1266
    11581267cpdef tuple find_hamiltonian( G, long max_iter=100000, long reset_bound=30000, long backtrack_bound=1000, find_path=False ):
    11591268    r"""
    11601269    Randomized backtracking for finding hamiltonian cycles and paths.
  • sage/graphs/graph.py

    diff -r 5c9ed0fbc0ef -r 3f18ff19f41a sage/graphs/graph.py
    a b  
    22752275            return first_coloring(self, hex_colors=hex_colors)
    22762276        else:
    22772277            raise ValueError("The 'algorithm' keyword must be set to either 'DLX' or 'MILP'.")
     2278
     2279    def fractional_chromatic_index(self, constraint_log = 0,solver_log = 0):
     2280        r"""
     2281        Computes the fractional chromatic index of ``self``
     2282   
     2283        INPUT:
     2284
     2285        - ``constraint_log`` -- whether to display which constraints
     2286          are being generated.
     2287   
     2288        - ``solver_log`` -- level of verbosity required from the LP
     2289          solver
     2290   
     2291        EXAMPLE:
     2292   
     2293        The fractional chromatic index of a `C_5` is `5/2`::
     2294   
     2295            sage: g = graphs.CycleGraph(5)
     2296            sage: g.fractional_chromatic_index()
     2297            2.5
     2298        """
     2299
     2300        from sage.graphs.generic_graph_pyx import fractional_chromatic_index
     2301
     2302        return fractional_chromatic_index(self,
     2303                                          constraint_log = constraint_log,
     2304                                          solver_log = solver_log)
    22782305   
    22792306    def independent_set_of_representatives(self, family, solver=None, verbose=0):
    22802307        r"""