diff --git a/doc/attr.xml b/doc/attr.xml index 3a6769da8..bb13665ff 100644 --- a/doc/attr.xml +++ b/doc/attr.xml @@ -1374,6 +1374,46 @@ gap> DigraphLongestSimpleCircuit(D); <#/GAPDoc> +<#GAPDoc Label="DigraphAllUndirectedSimpleCircuits"> + + + A list of lists of vertices. + + If digraph is a digraph, then DigraphAllUndirectedSimpleCircuits + returns a list of the undirected simple circuits in digraph.

+ + See Section for the definition + of a simple circuit, and related notions. Note that a loop is a simple + circuit. A simple circuit is undirected if the orientation of the edges + in the circuit does not matter.

+ + The attribute DigraphAllUndirectedSimpleCircuitss ignores + multiple edges, and identifies a undirected simple circuit using only its subsequence + of vertices. + See Section for more details + on simple circuits.

+ + D := ChainDigraph(10);; +gap> DigraphAllUndirectedSimpleCircuits(D); +[ ] +gap> D := Digraph([[1, 1]]); + +gap> DigraphAllUndirectedSimpleCircuits(D); +[ [ 1 ] ] +gap> D := CycleDigraph(IsMutableDigraph, 3); + +gap> DigraphAllUndirectedSimpleCircuits(D); +[ [ 1, 2, 3 ] ] +gap> D := DigraphSymmetricClosure(CycleDigraph(IsMutableDigraph, 3)); + +gap> DigraphAllUndirectedSimpleCircuits(D); +[ [ 1, 2, 3 ] ] +]]> + + +<#/GAPDoc> + <#GAPDoc Label="DigraphAllChordlessCycles"> diff --git a/doc/z-chap4.xml b/doc/z-chap4.xml index 0f2ebe1ee..4af3cab3e 100644 --- a/doc/z-chap4.xml +++ b/doc/z-chap4.xml @@ -76,6 +76,7 @@ <#Include Label="IteratorOfPaths"> <#Include Label="DigraphAllSimpleCircuits"> <#Include Label="DigraphLongestSimpleCircuit"> + <#Include Label="DigraphAllUndirectedSimpleCircuits"> <#Include Label="DigraphAllChordlessCycles"> <#Include Label="DigraphLayers"> <#Include Label="DigraphDegeneracy"> diff --git a/gap/attr.gd b/gap/attr.gd index d0c1732ff..020bf0899 100644 --- a/gap/attr.gd +++ b/gap/attr.gd @@ -58,6 +58,7 @@ DeclareAttribute("DigraphAbsorptionExpectedSteps", IsDigraph); DeclareAttribute("DigraphAllSimpleCircuits", IsDigraph); DeclareAttribute("DigraphLongestSimpleCircuit", IsDigraph); +DeclareAttribute("DigraphAllUndirectedSimpleCircuits", IsDigraph); DeclareAttribute("DigraphAllChordlessCycles", IsDigraph); DeclareAttribute("HamiltonianPath", IsDigraph); DeclareAttribute("DigraphPeriod", IsDigraph); diff --git a/gap/attr.gi b/gap/attr.gi index c2fde5582..a247a6f51 100644 --- a/gap/attr.gi +++ b/gap/attr.gi @@ -1524,6 +1524,26 @@ function(D) return Concatenation(loops, out); end); +# Compute all undirected simple ciruits by filtering the output +# of DigraphAllSimpleCircuits +InstallMethod(DigraphAllUndirectedSimpleCircuits, "for a digraph", + [IsDigraph], function(D) + local digraph, cycles, remove, cycle, cycleRev; + digraph := DigraphSymmetricClosure( + DigraphRemoveAllMultipleEdges(DigraphMutableCopyIfMutable(D))); + cycles := Filtered(DigraphAllSimpleCircuits(digraph), + c -> Length(c) > 2 or Length(c) = 1); + remove := []; + for cycle in cycles do + if not cycle in remove and Length(cycle) <> 1 then + cycleRev := [cycle[1]]; + Append(cycleRev, Reversed(cycle{[2 .. Length(cycle)]})); + Add(remove, cycleRev); + fi; + od; + return Difference(cycles, remove); +end); + # Compute all chordless cycles for a given symmetric digraph # Algorithm based on https://arxiv.org/pdf/1404.7610 InstallMethod(DigraphAllChordlessCycles, "for a digraph", diff --git a/tst/standard/attr.tst b/tst/standard/attr.tst index 167efe8be..c7f54b004 100644 --- a/tst/standard/attr.tst +++ b/tst/standard/attr.tst @@ -948,6 +948,37 @@ gap> gr := Digraph([[3, 6, 7], [3, 6, 8], [1, 2, 3, 6, 7, 8], gap> Length(DigraphAllSimpleCircuits(gr)); 259 +# DigraphAllUndirectedSimpleCircuits +gap> gr := Digraph([]);; +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ ] +gap> gr := ChainDigraph(4);; +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ ] +gap> gr := CompleteDigraph(2);; +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ ] +gap> gr := CompleteDigraph(3);; +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ [ 1, 2, 3 ] ] +gap> gr := Digraph([[], [3], [2, 4], [5, 4], [4]]); + +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ [ 4 ] ] +gap> gr := Digraph([[1, 2], [2, 1]]); + +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ [ 1 ], [ 2 ] ] +gap> gr := Digraph([[4], [1, 3], [1, 2], [2, 3]]);; +gap> DigraphAllUndirectedSimpleCircuits(gr); +[ [ 1, 2, 3 ], [ 1, 2, 3, 4 ], [ 1, 2, 4 ], [ 1, 2, 4, 3 ], [ 1, 3, 2, 4 ], + [ 1, 3, 4 ], [ 2, 3, 4 ] ] +gap> gr := Digraph([[3, 6, 7], [3, 6, 8], [1, 2, 3, 6, 7, 8], +> [2, 3, 4, 8], [2, 3, 4, 5, 6, 7], [1, 3, 4, 5, 7], [2, 3, 6, 8], +> [1, 2, 3, 8]]);; +gap> Length(DigraphAllUndirectedSimpleCircuits(gr)); +1330 + # DigraphAllChordlessCycles gap> gr := Digraph([]);; gap> DigraphAllChordlessCycles(gr);