8803 | | A Graph `G` is said to be chordal if it contains no induced |
8804 | | hole. Being chordal is equivalent to having an elimination |
8805 | | order on the vertices such that the neighborhood of each |
8806 | | vertex, before being removed from the graph, is a complete |
8807 | | graph [Fulkerson65]_. |
8808 | | |
8809 | | Such an ordering is called a Perfect Elimination Order. |
| 8803 | A Graph `G` is said to be chordal if it contains no induced hole (a |
| 8804 | cycle of length at least 4). |
| 8805 | |
| 8806 | Alternatively, chordality can be defined using a Perfect Elimination |
| 8807 | Order : |
| 8808 | |
| 8809 | A Perfect Elimination Order of a graph `G` is an ordering `v_1,...,v_n` |
| 8810 | of its vertex set such that for all `i`, the neighbors of `v_i` whose |
| 8811 | index is greater that `i` induce a complete subgraph in `G`. Hence, the |
| 8812 | graph `G` can be totally erased by successively removing vertices whose |
| 8813 | neighborhood is a clique (also called *simplicial* vertices) |
| 8814 | [Fulkerson65]_. |
| 8815 | |
| 8816 | (It can be seen that if `G` contains an induced hole, then it can not |
| 8817 | have a perfect elimination order. Indeed, if we write `h_1,...,h_k` the |
| 8818 | `k` vertices of such a hole, then the first of those vertices to be |
| 8819 | removed would have two non-adjacent neighbors in the graph.) |
| 8820 | |
| 8821 | A Graph is then chordal if and only if it has a Perfect Elimination |
| 8822 | Order. |
| 8823 | |
| 8824 | INPUT: |
| 8825 | |
| 8826 | - ``certificate`` (boolean) -- Whether to return a certificate. |
| 8827 | |
| 8828 | * If ``certificate = False`` (default), returns ``True`` or |
| 8829 | ``False`` accordingly. |
| 8830 | |
| 8831 | * If ``certificate = True``, returns : |
| 8832 | |
| 8833 | * ``(True, peo)`` when the graph is chordal, where ``peo`` is a |
| 8834 | perfect elimination order of its vertices. |
| 8835 | |
| 8836 | * ``(False, Hole)`` when the graph is not chordal, where |
| 8837 | ``Hole`` (a ``Graph`` object) is an induced subgraph of |
| 8838 | ``self`` isomorphic to a hole. |
8813 | | This algorithm works through computing a Lex BFS on the |
8814 | | graph, then checking whether the order is a Perfect |
8815 | | Elimination Order by computing for each vertex `v` the |
8816 | | subgraph induces by its non-deleted neighbors, then |
8817 | | testing whether this graph is complete. |
8818 | | |
8819 | | This problem can be solved in `O(m)` [Rose75]_ ( where `m` |
8820 | | is the number of edges in the graph ) but this |
8821 | | implementation is not linear because of the complexity of |
8822 | | Lex BFS. Improving Lex BFS to linear complexity would make |
8823 | | this algorithm linear. |
8824 | | |
8825 | | The complexity of this algorithm is equal to the |
8826 | | complexity of the implementation of Lex BFS. |
| 8842 | This algorithm works through computing a Lex BFS on the graph, then |
| 8843 | checking whether the order is a Perfect Elimination Order by computing |
| 8844 | for each vertex `v` the subgraph induces by its non-deleted neighbors, |
| 8845 | then testing whether this graph is complete. |
| 8846 | |
| 8847 | This problem can be solved in `O(m)` [Rose75]_ ( where `m` is the number |
| 8848 | of edges in the graph ) but this implementation is not linear because of |
| 8849 | the complexity of Lex BFS. Improving Lex BFS to linear complexity would |
| 8850 | make this algorithm linear. |
| 8851 | |
| 8852 | The complexity of this algorithm is equal to the complexity of the |
| 8853 | implementation of Lex BFS. |
8872 | | for gg in self.connected_components_subgraphs(): |
8873 | | if not gg.is_chordal(): |
8874 | | return False |
8875 | | |
8876 | | return True |
8877 | | |
8878 | | |
| 8917 | |
| 8918 | # If the user wants a certificate, we had no choice but to |
| 8919 | # collect the perfect elimination orders... But we return |
| 8920 | # a hole immediately if we find any ! |
| 8921 | if certificate: |
| 8922 | peo = [] |
| 8923 | for gg in self.connected_components_subgraphs(): |
| 8924 | |
| 8925 | b, certif = gg.is_chordal(certificate = True) |
| 8926 | if not b: |
| 8927 | return certif |
| 8928 | else: |
| 8929 | peo.extend(certif) |
| 8930 | |
| 8931 | return True, peo |
| 8932 | |
| 8933 | # One line if no certificate is requested |
| 8934 | else: |
| 8935 | return all( gg.is_chordal() for gg in self.connected_components_subgraphs() ) |
| 8936 | |