# Ticket #8405: trac_8405.patch

File trac_8405.patch, 13.0 KB (added by ncohen, 3 years ago)
• ## sage/graphs/graph_coloring.py

# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1267402255 -3600
# Node ID 8a9ba9a2bf689cea5261ba2e6ccfd1127a9d08aa
# Parent  efdf887eeb279c193a08fd5252953cc691f385cf
trac 8405 - linear arboricity, acyclic edge coloring

diff -r efdf887eeb27 -r 8a9ba9a2bf68 sage/graphs/graph_coloring.py
 a g.delete_vertex(n) return g def linear_arboricity(g, hex_colors=False, value_only=False, k=1, **kwds): r""" Computes the linear arboricity of the given graph. The linear arboricity of a graph G is the least number la(G) such that the edges of G can be partitioned into linear forests (i.e. into forests of paths). Obviously, la(G)\geq \lceil \frac {\Delta(G)} 2 \rceil. It is conjectured in [Aki80]_ that la(G)\leq \lceil \frac {\Delta(G)+1} 2 \rceil. INPUT: - hex_colors (boolean) - If hex_colors = True, the function returns a dictionary associating to each color a list of edges (meant as an argument to the edge_colors keyword of the plot method). - If hex_colors = False (default value), returns a list of graphs corresponding to each color class. - value_only (boolean) - If value_only = True, only returns the linear arboricity as an integer value. - If value_only = False, returns the color classes according to the value of hex_colors - k (integer) -- the number of colors to use. - If 0, computes a decomposition of G into \lceil \frac {\Delta(G)} 2 \rceil forests of paths - If 1 (default), computes a decomposition of G into \lceil \frac {\Delta(G)+1} 2 \rceil colors, which is the conjectured general bound. - If k=None, computes a decomposition using the least possible number of colors. - **kwds -- arguments to be passed down to the solve function of MixedIntegerLinearProgram. See the documentation of MixedIntegerLinearProgram.solve for more informations. ALGORITHM: Linear Programming COMPLEXITY: NP-Hard EXAMPLE: Obviously, a square grid has a linear arboricity of 2, as the set of horizontal lines and the set of vertical lines are an admissible partition:: sage: from sage.graphs.graph_coloring import linear_arboricity sage: g = graphs.GridGraph([4,4])                                 # optional - requires GLPK CPLEX or CBC sage: g1,g2 = linear_arboricity(g, k=0)                           # optional - requires GLPK CPLEX or CBC Each graph is of course a forest:: sage: g1.is_forest() and g2.is_forest()                           # optional - requires GLPK CPLEX or CBC True Of maximum degree 2:: sage: max(g1.degree()) <= 2 and max(g2.degree()) <= 2             # optional - requires GLPK CPLEX or CBC True Which constitutes a partition of the whole edge set:: sage: all([g1.has_edge(e) or g2.has_edge(e) for e in g.edges()])  # optional - requires GLPK CPLEX or CBC True REFERENCES: .. [Aki80] Akiyama, J. and Exoo, G. and Harary, F. Covering and packing in graphs. III: Cyclic and acyclic invariants Mathematical Institute of the Slovak Academy of Sciences Mathematica Slovaca vol30, n4, pages 405--417, 1980 """ from sage.rings.integer import Integer if k is None: try: return linear_arboricity(g, value_only = value_only,hex_colors = hex_colors, k = (Integer(max(g.degree()))/2).ceil() ) except ValueError: return linear_arboricity(g, value_only = value_only,hex_colors = hex_colors, k = 0) elif k==1: k = (Integer(1+max(g.degree()))/2).ceil() elif k==0: k = (Integer(max(g.degree()))/2).ceil() from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException from sage.plot.colors import rainbow p = MixedIntegerLinearProgram() # c is a boolean value such that c[i][(u,v)] = 1 if and only if (u,v) is colored with i c = p.new_variable(dim=2) # relaxed value r = p.new_variable(dim=2) E = lambda x,y : (x,y) if x0, computes an acyclic edge coloring using k colors. - If k=0 (default), computes a coloring of G into \Delta(G) + 2 colors, which is the conjectured general bound. - If k=None, computes a decomposition using the least possible number of colors. - **kwds -- arguments to be passed down to the solve function of MixedIntegerLinearProgram. See the documentation of MixedIntegerLinearProgram.solve for more informations. ALGORITHM: Linear Programming EXAMPLE: The complete graph on 8 vertices can not be acyclically edge-colored with less \Delta+1 colors, but it can be colored with \Delta+2=9:: sage: from sage.graphs.graph_coloring import acyclic_edge_coloring sage: g = graphs.CompleteGraph(8) sage: colors = acyclic_edge_coloring(g)                                     # optional - requires GLPK CPLEX or CBC Each color class is of course a matching :: sage: all([max(gg.degree())<=1 for gg in colors])                           # optional - requires GLPK CPLEX or CBC True These matchings being a partition of the edge set:: sage: all([ any([gg.has_edge(e) for gg in colors]) for e in g.edges()])     # optional - requires GLPK CPLEX or CBC True Besides, the union of any two of them is a forest :: sage: all([g1.union(g2).is_forest() for g1 in colors for g2 in colors])     # optional - requires GLPK CPLEX or CBC True If one wants to acyclically color a cycle on 4 vertices, at least 3 colors will be necessary. The function raises an exception when asked to color it with only 2:: sage: g = graphs.CycleGraph(4) sage: acyclic_edge_coloring(g, k=2)                                         # optional - requires GLPK CPLEX or CBC Traceback (most recent call last): ... ValueError: This graph can not be colored with the given number of colors. The optimal coloring give us 3 classes:: sage: colors = acyclic_edge_coloring(g, k=None)                             # optional - requires GLPK CPLEX or CBC sage: len(colors)                                                           # optional - requires GLPK CPLEX or CBC 3 """ from sage.rings.integer import Integer from sage.combinat.subset import Subsets if k is None: k = max(g.degree()) while True: try: return acyclic_edge_coloring(g, value_only = value_only,hex_colors = hex_colors, k = k) except ValueError: k = k+1 raise Exception("This should not happen. Please report a bug !") elif k==0: k = max(g.degree())+2 from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException from sage.plot.colors import rainbow p = MixedIntegerLinearProgram() # c is a boolean value such that c[i][(u,v)] = 1 if and only if (u,v) is colored with i c = p.new_variable(dim=2) # relaxed value r = p.new_variable(dim=2) E = lambda x,y : (x,y) if x