diff --git a/doc/planar.xml b/doc/planar.xml index 6c9e44d5c..fae0f411e 100644 --- a/doc/planar.xml +++ b/doc/planar.xml @@ -427,3 +427,34 @@ fail <#/GAPDoc> + +<#GAPDoc Label="DualPlanarGraph"> + + + A digraph or fail. + + If digraph is a planar digraph, then DualPlanarGraph returns the the dual graph of digraph. + If digraph is not planar, then fail is returned.

+ + The dual graph of a planar digraph digraph has a vertex for each face of digraph and an edge for + each pair of faces that are separated by an edge from each other. + Vertex i of the dual graph corresponds to the facial walk at the i-th position calling + FacialWalks of digraph with the rotation system returned by PlanarEmbedding. + + D := CompleteDigraph(4);; +gap> dualD := DualPlanarGraph(D); + +gap> IsIsomorphicDigraph(D, dualD); +true +gap> cube := Digraph([[2, 4, 5], [1, 3, 6], [2, 4, 7], [1, 3, 8], +> [1, 6, 8], [2, 5, 7], [3, 6, 8], [4, 5, 7]]); + +gap> oct := DualPlanarGraph(cube);; +gap> IsIsomorphicDigraph(oct, CompleteMultipartiteDigraph([2, 2, 2])); +true +]]> + + + +<#/GAPDoc> \ No newline at end of file diff --git a/doc/z-chap4.xml b/doc/z-chap4.xml index 789c3f1f7..d0c764ab1 100644 --- a/doc/z-chap4.xml +++ b/doc/z-chap4.xml @@ -106,6 +106,7 @@ <#Include Label="PlanarEmbedding"> <#Include Label="OuterPlanarEmbedding"> <#Include Label="SubdigraphHomeomorphicToK"> + <#Include Label="DualPlanarGraph">

Hashing diff --git a/gap/planar.gd b/gap/planar.gd index 6afb5f1e8..36e0726a4 100644 --- a/gap/planar.gd +++ b/gap/planar.gd @@ -25,6 +25,7 @@ DeclareAttribute("KuratowskiOuterPlanarSubdigraph", IsDigraph); DeclareAttribute("SubdigraphHomeomorphicToK23", IsDigraph); DeclareAttribute("SubdigraphHomeomorphicToK4", IsDigraph); DeclareAttribute("SubdigraphHomeomorphicToK33", IsDigraph); +DeclareAttribute("DualPlanarGraph", IsDigraph); # Properties . . . diff --git a/gap/planar.gi b/gap/planar.gi index 8a36385ca..dbcee889e 100644 --- a/gap/planar.gi +++ b/gap/planar.gi @@ -73,6 +73,47 @@ SUBGRAPH_HOMEOMORPHIC_TO_K4); InstallMethod(SubdigraphHomeomorphicToK33, "for a digraph", [IsDigraph], SUBGRAPH_HOMEOMORPHIC_TO_K33); +InstallMethod(DualPlanarGraph, "for a digraph", [IsDigraph], +function(D) + local digraph, rotationSystem, facialWalks, dualEdges, + cycle1, cycle2, commonNodes, i; + + if not IsPlanarDigraph(D) then + return fail; + fi; + + digraph := DigraphSymmetricClosure(DigraphRemoveLoops( + DigraphRemoveAllMultipleEdges(DigraphMutableCopyIfMutable(D)))); + rotationSystem := PlanarEmbedding(digraph); + facialWalks := FacialWalks(digraph, rotationSystem); + + dualEdges := []; + for cycle1 in [1 .. Length(facialWalks) - 1] do + for cycle2 in [cycle1 .. Length(facialWalks)] do + if cycle1 = cycle2 then + if not IsDuplicateFree(facialWalks[cycle1]) then + Add(dualEdges, [cycle1, cycle1]); + fi; + else + commonNodes := Intersection(facialWalks[cycle1], + facialWalks[cycle2]); + if Length(commonNodes) = Length(facialWalks[cycle1]) then + for i in [1 .. Length(commonNodes)] do + Add(dualEdges, [cycle1, cycle2]); + Add(dualEdges, [cycle2, cycle1]); + od; + else + for i in [1 .. Length(commonNodes) - 1] do + Add(dualEdges, [cycle1, cycle2]); + Add(dualEdges, [cycle2, cycle1]); + od; + fi; + fi; + od; + od; + return DigraphByEdges(dualEdges); +end); + ######################################################################## # 2. Properties ######################################################################## diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index 8e87659b5..39a88872e 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -1074,11 +1074,11 @@ gap> DigraphAllUndirectedSimpleCircuits(g); # FacialCycles gap> g := Digraph([]);; gap> rotationSy := [];; -gap> FacialWalks(g,rotationSy); +gap> FacialWalks(g, rotationSy); [ ] -gap> g := Digraph([[2],[1,3],[2,4],[3]]);;; -gap> rotationSy := [[2],[1,3],[2,4],[3]];; -gap> FacialWalks(g,rotationSy); +gap> g := Digraph([[2], [1, 3], [2, 4], [3]]);;; +gap> rotationSy := [[2], [1, 3], [2, 4], [3]];; +gap> FacialWalks(g, rotationSy); [ [ 1, 2, 3, 4, 3, 2 ] ] gap> g := CycleDigraph(4);; gap> planar := PlanarEmbedding(g); @@ -1095,6 +1095,13 @@ gap> rotationSystem := PlanarEmbedding(g); gap> FacialWalks(g, rotationSystem); [ [ 1, 3, 6 ], [ 1, 4, 5 ], [ 1, 5, 3 ], [ 1, 6, 4 ], [ 2, 3, 5 ], [ 2, 4, 6 ], [ 2, 5, 4 ], [ 2, 6, 3 ] ] +gap> g := Digraph([[2, 3, 4], [1, 3, 5], [1, 2, 4], [1, 3, 5], [2, 4, 6], [5, 7, 9], [6, 8, 10], [7, 9, 10], [6, 8, 10], [7, 8, 9]]);; +gap> rotationSy := PlanarEmbedding(g); +[ [ 2, 4, 3 ], [ 3, 5, 1 ], [ 1, 4, 2 ], [ 1, 5, 3 ], [ 2, 4, 6 ], + [ 5, 7, 9 ], [ 8, 10, 6 ], [ 9, 10, 7 ], [ 6, 10, 8 ], [ 7, 8, 9 ] ] +gap> FacialWalks(g, rotationSy); +[ [ 1, 2, 3 ], [ 1, 3, 4 ], [ 1, 4, 5, 6, 7, 8, 9, 6, 5, 2 ], [ 2, 5, 4, 3 ], + [ 6, 9, 10, 7 ], [ 7, 10, 8 ], [ 8, 10, 9 ] ] # Issue #676 gap> D := Digraph([[], [3], []]);; diff --git a/tst/standard/planar.tst b/tst/standard/planar.tst index b0d08f622..870f2d6f7 100644 --- a/tst/standard/planar.tst +++ b/tst/standard/planar.tst @@ -230,6 +230,26 @@ gap> D := CompleteDigraph(3); gap> KuratowskiOuterPlanarSubdigraph(D); fail +# DualPlanarGraph +gap> DualPlanarGraph(CompleteDigraph(5)); +fail +gap> D := CycleDigraph(4); + +gap> DualPlanarGraph(D); + +gap> D := ChainDigraph(4); + +gap> DualPlanarGraph(D); + +gap> D := Digraph([[2, 3, 4], [1, 3, 5], [1, 2, 4], [1, 3, 5], [2, 4, 6], [5, 7, 9], [6, 8, 10], [7, 9, 10], [6, 8, 10], [7, 8, 9]]);; +gap> dualD := DualPlanarGraph(D); + +gap> DigraphHasLoops(dualD); +true +gap> D := CompleteDigraph(3);; +gap> DualPlanarGraph(D); + + # Kernel function boyers_planarity_check, errors gap> IS_PLANAR(2); Error, Digraphs: boyers_planarity_check (C): the 1st argument must be a digrap\