Ticket #8953: trac_8953.patch

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

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1276001765 -7200
    # Node ID 90a1fda9099b6741567239beb684301137b22c41
    # Parent  cb1ad1ee5bd452850fde04d47f9618dec4c3e997
    trac 8953 -- Graph.is_perfect
    
    diff -r cb1ad1ee5bd4 -r 90a1fda9099b sage/graphs/graph.py
    a b  
    16541654        return left == right
    16551655
    16561656
     1657    def is_perfect(self, certificate = False):
     1658        r"""
     1659        Tests whether the graph is perfect.
     1660
     1661        A graph `G` is said to be perfect if `\chi(H)=\omega(H)` hold
     1662        for any induced subgraph `H\subseteq_i G` (and so for `G`
     1663        itself, too), where `\chi(H)` represents the chromatic number
     1664        of `H`, and `\omega(H)` its clique number. The Strong Perfect
     1665        Graph Theorem [SPGT]_ gives another characterization of
     1666        perfect graphs:
     1667
     1668        A graph is perfect if and only if it contains no odd hole
     1669        (cycle on an odd number `k` of vertices, `k>3`) nor any odd
     1670        antihole (complement of a hole) as an induced subgraph.
     1671
     1672        INPUT:
     1673
     1674        - ``certificate`` (boolean) -- whether to return
     1675          a certificate (default : ``False``)
     1676
     1677        OUTPUT:
     1678
     1679        When ``certificate = False``, this function returns
     1680        a boolean value. When ``certificate = True``, it returns
     1681        a subgraph of ``self`` isomorphic to an odd hole or an odd
     1682        antihole if any, and ``None`` otherwise.
     1683
     1684        EXAMPLE:
     1685
     1686        A Bipartite Graph is always perfect ::
     1687
     1688            sage: g = graphs.RandomBipartite(8,4,.5)
     1689            sage: g.is_perfect()
     1690            True
     1691
     1692        Interval Graphs, which are chordal graphs, too ::
     1693
     1694            sage: g =  graphs.RandomInterval(7)
     1695            sage: g.is_perfect()
     1696            True
     1697
     1698        The PetersenGraph, which is triangle-free and
     1699        has chromatic number 3 is obviously not perfect::
     1700
     1701            sage: g = graphs.PetersenGraph()
     1702            sage: g.is_perfect()
     1703            False
     1704
     1705        We can obtain an induced 5-cycle as a certificate::
     1706
     1707            sage: g.is_perfect(certificate = True)
     1708            Subgraph of (Petersen graph): Graph on 5 vertices
     1709
     1710        REFERENCES:
     1711
     1712        .. [SPGT] M. Chudnovsky, N. Robertson, P. Seymour, R. Thomas.
     1713          The strong perfect graph theorem
     1714          Annals of Mathematics
     1715          vol 164, number 1, pages 51--230
     1716          2006
     1717        """
     1718
     1719        from sage.graphs.bipartite_graph import BipartiteGraph
     1720       
     1721        if isinstance(self, BipartiteGraph) or self.is_bipartite():
     1722            return True if not certificate else None
     1723
     1724        self_complement = self.complement()
     1725
     1726        start_complement = self_complement.girth()
     1727        start_self = self.girth()
     1728
     1729        from sage.graphs.graph_generators import graphs
     1730
     1731
     1732        # In these cases, we know the graph is no perfect.
     1733        if start_self == 5:
     1734            if certificate:
     1735                return self.subgraph_search(graphs.CycleGraph(5), induced = True)
     1736            else:
     1737                return False
     1738
     1739        if start_complement == 5:
     1740            if certificate:
     1741                return self_complement.subgraph_search(graphs.CycleGraph(5), induced = True).complement()
     1742            else:
     1743                return False
     1744
     1745        # We are only looking for odd holes of size at least 5
     1746        from sage.rings.finite_rings.integer_mod import Mod
     1747
     1748        start = lambda x : (x+1) if Mod(x,2) == 0 else ( 5 if x == 3 else x )
     1749
     1750        # these values are possibly the infinity !!!!
     1751
     1752        start_self = start(start_self) if start_self <= self.order() else self.order()+2
     1753        start_complement = start(start_complement) if start_complement <= self.order() else self.order()+2
     1754           
     1755        counter_example = None
     1756
     1757        for i in range(min(start_self, start_complement), self.order()+1,2):
     1758
     1759            # trying in self
     1760            if i >= start_self:
     1761                counter_example = self.subgraph_search(graphs.CycleGraph(i), induced = True)
     1762               
     1763                if counter_example is not None:
     1764                    break
     1765
     1766            # trying in the complement
     1767            if i >= start_complement:
     1768                counter_example = self.subgraph_search(graphs.CycleGraph(i), induced = True)
     1769                if counter_example is not None:
     1770                    counter_example = counter_example.complement()
     1771                    break
     1772
     1773        if certificate:
     1774            return counter_example
     1775        else:
     1776            return counter_example is None
     1777
     1778
    16571779    def degree_constrained_subgraph(self, bounds=None, solver=None, verbose=0):
    16581780        r"""
    16591781        Returns a degree-constrained subgraph.