| 11415 | def two_factor_petersen(self): |
| 11416 | r""" |
| 11417 | Returns a decomposition of the graph into 2-factors. |
| 11418 | |
| 11419 | Petersen's 2-factor decomposition theorem asserts that any |
| 11420 | `2r`-regular graph `G` can be decomposed into 2-factors. |
| 11421 | Equivalently, it means that the edges of any `2r`-regular |
| 11422 | graphs can be partitionned in `r` sets `C_1,\dots,C_r` such |
| 11423 | that for all `i`, the set `C_i` is a disjoint union of cycles |
| 11424 | ( a 2-regular graph ). |
| 11425 | |
| 11426 | As any graph of maximal degree `\Delta` can be completed into |
| 11427 | a regular graph of degree `2\lceil\frac\Delta 2\rceil`, this |
| 11428 | result also means that the edges of any graph of degree `\Delta` |
| 11429 | can be partitionned in `r=2\lceil\frac\Delta 2\rceil` sets |
| 11430 | `C_1,\dots,C_r` such that for all `i`, the set `C_i` is a |
| 11431 | graph of maximal degree `2` ( a disjoint union of paths |
| 11432 | and cycles ). |
| 11433 | |
| 11434 | EXAMPLE: |
| 11435 | |
| 11436 | The Complete Graph on `7` vertices is a `6`-regular graph, so it can |
| 11437 | be edge-partitionned into `2`-regular graphs:: |
| 11438 | |
| 11439 | sage: g = graphs.CompleteGraph(7) |
| 11440 | sage: classes = g.two_factor_petersen() # optional - requires GLPK or CBC |
| 11441 | sage: for c in classes: # optional - requires GLPK or CBC |
| 11442 | ... gg = Graph() # optional - requires GLPK or CBC |
| 11443 | ... gg.add_edges(c) # optional - requires GLPK or CBC |
| 11444 | ... print max(gg.degree())<=2 # optional - requires GLPK or CBC |
| 11445 | True |
| 11446 | True |
| 11447 | True |
| 11448 | sage: Set(set(classes[0]) | set(classes[1]) | set(classes[2])).cardinality() == g.size() # optional - requires GLPK or CBC |
| 11449 | True |
| 11450 | """ |
| 11451 | |
| 11452 | d = self.eulerian_orientation() |
| 11453 | |
| 11454 | # This new graph is bipartite, and built the following way : |
| 11455 | # |
| 11456 | # To each vertex v of the digraph are associated two vertices, |
| 11457 | # a sink (-1,v) and a source (1,v) |
| 11458 | # Any edge (u,v) in the digraph is then added as ((-1,u),(1,v)) |
| 11459 | |
| 11460 | from sage.graphs.graph import Graph |
| 11461 | g = Graph() |
| 11462 | g.add_edges([((-1,u),(1,v)) for (u,v) in d.edge_iterator(labels=None)]) |
| 11463 | |
| 11464 | # This new bipartite graph is now edge_colored |
| 11465 | from sage.graphs.graph_coloring import edge_coloring |
| 11466 | classes = edge_coloring(g,log=1) |
| 11467 | |
| 11468 | # The edges in the classes are of the form ((-1,u),(1,v)) |
| 11469 | # and have to be translated back to (u,v) |
| 11470 | classes_b = [] |
| 11471 | for c in classes: |
| 11472 | classes_b.append([(u,v) for ((uu,u),(vv,v),t) in c]) |
| 11473 | |
| 11474 | return classes_b |
| 11475 | |
| 11476 | |