Ticket #7527: trac_7527-reviewer.patch

File trac_7527-reviewer.patch, 10.5 KB (added by mvngu, 11 years ago)

reviewer patch

  • sage/graphs/graph_coloring.py

    # HG changeset patch
    # User Minh Van Nguyen <nguyenminh2@gmail.com>
    # Date 1260298074 28800
    # Node ID 81b01e7a0099b3e9d9b920bae9e12352500b8c60
    # Parent  8ca939870ef50e8f8ec3d94a0b9508d32489867c
    trac 7527: graph colouring: reviewer patch
    
    diff -r 8ca939870ef5 -r 81b01e7a0099 sage/graphs/graph_coloring.py
    a b  
    11"""
    2 Graph Coloring Functions
     2Graph Coloring
    33
    44AUTHORS:
    55
     
    2828    into an implementation of the Dancing Links algorithm described
    2929    by Knuth (who attributes the idea to Hitotumatu and Noshita).
    3030
    31     The construction works as follows:
    32      (columns)
    33       * The first `|V|` columns correspond to a vertex -- a `1` in this
    34            column indicates that that vertex has a color.
    35       * After those `|V|` columns, we add `n*|E|` columns -- a `1` in
    36            these columns indicate that a particular edge is
    37            incident to a vertex with a certain color.
     31    The construction works as follows. Columns:
    3832
    39      (rows)
    40       * For each vertex, add `n` rows; one for each color `c`.  Place
    41            a `1` in the column corresponding to the vertex, and a `1`
    42            in the appropriate column for each edge incident to the
    43            vertex, indicating that that edge is incident to the
    44            color `c`.
    45       * If `n > 2`, the above construction cannot be exactly covered
    46            since each edge will be incident to only two vertices
    47            (and hence two colors) - so we add `n*|E|` rows, each one
    48            containing a `1` for each of the `n*|E|` columns.  These
    49            get added to the cover solutions "for free" during the
    50            backtracking.
     33    * The first `|V|` columns correspond to a vertex -- a `1` in this
     34      column indicates that that vertex has a color.
     35
     36    * After those `|V|` columns, we add `n*|E|` columns -- a `1` in
     37      these columns indicate that a particular edge is
     38      incident to a vertex with a certain color.
     39
     40    Rows:
     41
     42    * For each vertex, add `n` rows; one for each color `c`.  Place
     43      a `1` in the column corresponding to the vertex, and a `1`
     44      in the appropriate column for each edge incident to the
     45      vertex, indicating that that edge is incident to the
     46      color `c`.
     47
     48    * If `n > 2`, the above construction cannot be exactly covered
     49      since each edge will be incident to only two vertices
     50      (and hence two colors) - so we add `n*|E|` rows, each one
     51      containing a `1` for each of the `n*|E|` columns.  These
     52      get added to the cover solutions "for free" during the
     53      backtracking.
    5154
    5255    Note that this construction results in `n*|V| + 2*n*|E| + n*|E|`
    5356    entries in the matrix.  The Dancing Links algorithm uses a
    5457    sparse representation, so if the graph is simple, `|E| \leq |V|^2`
    5558    and `n <= |V|`, this construction runs in `O(|V|^3)` time.
    5659    Back-conversion to a coloring solution is a simple scan of the
    57     solutions, which will contain `|V| + (n-2)*|E|` entries,  so 
     60    solutions, which will contain `|V| + (n-2)*|E|` entries,  so
    5861    runs in `O(|V|^3)` time also.  For most graphs, the conversion
    5962    will be much faster -- for example, a planar graph will be
    6063    transformed for `4`-coloring in linear time since `|E| = O(|V|)`.
    6164
    6265    REFERENCES:
    63         http://www-cs-staff.stanford.edu/~uno/papers/dancing-color.ps.gz
     66
     67    http://www-cs-staff.stanford.edu/~uno/papers/dancing-color.ps.gz
    6468
    6569    EXAMPLES::
    6670
     
    225229        sage: from sage.graphs.graph_coloring import chromatic_number
    226230        sage: G = Graph({0:[1,2,3],1:[2]})
    227231        sage: chromatic_number(G)
    228         3   
     232        3
    229233
    230234        sage: G = graphs.PetersenGraph()
    231235        sage: G.chromatic_number()
    232236        3
    233 
    234237    """
    235238    o = G.order()
    236239    if o == 0:
     
    245248        return m
    246249    for n in range(m,o+1):
    247250        for C in all_graph_colorings(G,n):
    248             return n   
     251            return n
    249252
    250253def vertex_coloring(g, k=None, value_only=False, hex_colors=False, log=0):
    251254    r"""
    252255    Computes the chromatic number of the given graph or tests its
    253256    `k`-colorability. See http://en.wikipedia.org/wiki/Graph_coloring for
    254257    further details on graph coloring.
    255    
     258
    256259    INPUT:
    257260
    258261    - ``g`` -- a graph.
     
    279282      be no message printed by the solver.
    280283
    281284    OUTPUT:
    282    
     285
    283286    - If ``k=None`` and ``value_only=False``, then return a partition of the
    284287      vertex set into the minimum possible of independent sets.
    285288
    286289    - If ``k=None`` and ``value_only=True``, return the chromatic number.
    287              
     290
    288291    - If ``k`` is set and ``value_only=None``, return ``False`` if the
    289292      graph is not `k`-colorable, and a partition of the vertex set into
    290293      `k` independent sets otherwise.
     
    293296      `k`-colorable, and return ``True`` or ``False`` accordingly.
    294297
    295298    EXAMPLE::
    296    
     299
    297300       sage: from sage.graphs.graph_coloring import vertex_coloring
    298301       sage: g = graphs.PetersenGraph()
    299302       sage: vertex_coloring(g, value_only=True) # optional - requires GLPK or CBC
     
    376379                return dict(zip(rainbow(k), value))
    377380            else:
    378381                return value
    379                    
     382
    380383        # Degeneracy
    381384        # Vertices whose degree is less than k are of no importance in
    382385        # the coloring.
     
    412415                return dict(zip(rainbow(k), value))
    413416            else:
    414417                return value
    415        
     418
    416419        p = MixedIntegerLinearProgram(maximization=True)
    417420        color = p.new_variable(dim=2)
    418421        # a vertex has exactly one color
    419422        [p.add_constraint(sum([color[v][i] for i in xrange(k)]), min=1, max=1)
    420423             for v in g.vertices()]
    421424        # adjacent vertices have different colors
    422         [p.add_constraint(color[u][i] + color[v][i], max=1) 
     425        [p.add_constraint(color[u][i] + color[v][i], max=1)
    423426             for (u, v) in g.edge_iterator(labels=None)
    424427                 for i in xrange(k)]
    425428        # anything is good as an objective value as long as it is satisfiable
     
    439442        color = p.get_values(color)
    440443        # builds the color classes
    441444        classes = [[] for i in xrange(k)]
    442         [classes[i].append(v) 
    443              for i in xrange(k) 
    444                  for v in g.vertices() 
     445        [classes[i].append(v)
     446             for i in xrange(k)
     447                 for v in g.vertices()
    445448                     if color[v][i] == 1]
    446449        if hex_colors:
    447450            return dict(zip(rainbow(len(classes)), classes))
     
    453456    Properly colors the edges of a graph. See the URL
    454457    http://en.wikipedia.org/wiki/Edge_coloring for further details on
    455458    edge coloring.
    456    
     459
    457460    INPUT:
    458461
    459462    - ``g`` -- a graph.
     
    489492
    490493    In the following, `\Delta` is equal to the maximum degree in the graph
    491494    ``g``.
    492    
     495
    493496    - If ``vizing=True`` and ``value_only=False``, return a partition of
    494497      the edge set into `\Delta + 1` matchings.
    495498
     
    497500
    498501    - If ``vizing=False`` and ``value_only=False``, return a partition of
    499502      the edge set into the minimum number of matchings.
    500              
     503
    501504    - If ``vizing=True`` and ``value_only=True``, should return something,
    502505      but mainly you are just trying to compute the maximum degree of the
    503506      graph, and this is not the easiest way. By Vizing's theorem, a graph
    504507      has a chromatic index equal to `\Delta` or to `\Delta + 1`.
    505508
    506509    EXAMPLE::
    507    
     510
    508511       sage: from sage.graphs.graph_coloring import edge_coloring
    509512       sage: g = graphs.PetersenGraph()
    510513       sage: edge_coloring(g, value_only=True) # optional - requires GLPK or CBC
     
    532535        if hex_colors:
    533536            return zip(rainbow(len(classes)), classes)
    534537        else:
    535             return classes             
     538            return classes
    536539
    537540    p = MixedIntegerLinearProgram(maximization=True)
    538541    color = p.new_variable(dim=2)
     
    556559    e = g.edge_iterator().next()
    557560    p.set_objective(color[R(e)][0])
    558561    p.set_binary(color)
    559     try: 
     562    try:
    560563        if value_only:
    561564            p.solve(objective_only=True, log=log)
    562565        else:
     
    572575    # Builds the color classes
    573576    color = p.get_values(color)
    574577    classes = [[] for i in xrange(k)]
    575     [classes[i].append(e) 
    576          for e in g.edge_iterator() 
    577              for i in xrange(k) 
     578    [classes[i].append(e)
     579         for e in g.edge_iterator()
     580             for i in xrange(k)
    578581                 if color[R(e)][i] == 1]
    579582    # if needed, builds a dictionary from the color classes adding colors
    580583    if hex_colors:
     
    632635        sage: sum([Set([e[2] for e in g.edges_incident(v)]).cardinality() for v in g]) == 2*g.size()
    633636        True
    634637        sage: Set([e[2] for e in g.edge_iterator()]).cardinality()
    635         9       
     638        9
    636639    """
    637640    if n <= 1:
    638641        raise ValueError("There must be at least two vertices in the graph.")
     
    652655class Test:
    653656    r"""
    654657    This class performs randomized testing for all_graph_colorings.
    655     Since everything else in this file is derived from 
     658    Since everything else in this file is derived from
    656659    all_graph_colorings, this is a pretty good randomized tester for
    657660    the entire file.  Note that for a graph `G`, ``G.chromatic_polynomial()``
    658661    uses an entirely different algorithm, so we provide a good,
     
    661664
    662665    def random(self,tests = 1000):
    663666        r"""
    664         Calls ``self.random_all_graph_colorings()``.  In the future, if 
     667        Calls ``self.random_all_graph_colorings()``.  In the future, if
    665668        other methods are added, it should call them, too.
    666        
     669
    667670        TESTS::
    668671
    669672            sage: from sage.graphs.graph_coloring import Test
     
    673676
    674677    def random_all_graph_colorings(self,tests = 1000):
    675678        r"""
    676         Verifies the results of all_graph_colorings in three ways:
    677             1) all colorings are unique
    678             2) number of m-colorings is `P(m)` (where `P` is the chromatic
    679                polynomial of the graph being tested)
    680             3) colorings are valid -- that is, that no two vertices of
    681                the same color share an edge.
     679        Verifies the results of ``all_graph_colorings()`` in three ways:
     680
     681        #. all colorings are unique
     682
     683        #. number of m-colorings is `P(m)` (where `P` is the chromatic
     684           polynomial of the graph being tested)
     685
     686        #. colorings are valid -- that is, that no two vertices of
     687           the same color share an edge.
    682688
    683689        TESTS::
    684690