Goto Chapter: Top 1 2 3 4 5 6 7 8 9 A Bib Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

3 Creating digraphs
 3.1 Creating digraphs
 3.2 Changing representations
 3.3 New digraphs from old

  3.3-1 DigraphImmutableCopy

  3.3-2 DigraphImmutableCopyIfImmutable

  3.3-3 InducedSubdigraph

  3.3-4 ReducedDigraph

  3.3-5 MaximalSymmetricSubdigraph

  3.3-6 MaximalAntiSymmetricSubdigraph

  3.3-7 UndirectedSpanningForest

  3.3-8 DigraphShortestPathSpanningTree

  3.3-9 QuotientDigraph

  3.3-10 DigraphReverse

  3.3-11 DigraphDual

  3.3-12 DigraphSymmetricClosure

  3.3-13 DigraphTransitiveClosure

  3.3-14 DigraphTransitiveReduction

  3.3-15 DigraphAddVertex

  3.3-16 DigraphAddVertices

  3.3-17 DigraphAddEdge

  3.3-18 DigraphAddEdgeOrbit

  3.3-19 DigraphAddEdges

  3.3-20 DigraphRemoveVertex

  3.3-21 DigraphRemoveVertices

  3.3-22 DigraphRemoveEdge

  3.3-23 DigraphRemoveEdgeOrbit

  3.3-24 DigraphRemoveEdges

  3.3-25 DigraphRemoveLoops

  3.3-26 DigraphRemoveAllMultipleEdges

  3.3-27 DigraphContractEdge

  3.3-28 DigraphReverseEdges

  3.3-29 DigraphDisjointUnion

  3.3-30 DigraphEdgeUnion

  3.3-31 DigraphJoin

  3.3-32 DigraphCartesianProduct

  3.3-33 DigraphDirectProduct

  3.3-34 ConormalProduct

  3.3-35 HomomorphicProduct

  3.3-36 LexicographicProduct

  3.3-37 ModularProduct

  3.3-38 StrongProduct

  3.3-39 DigraphCartesianProductProjections

  3.3-40 DigraphDirectProductProjections

  3.3-41 LineDigraph

  3.3-42 LineUndirectedDigraph

  3.3-43 DoubleDigraph

  3.3-44 BipartiteDoubleDigraph

  3.3-45 DigraphAddAllLoops

  3.3-46 DistanceDigraph

  3.3-47 DigraphClosure

  3.3-48 DigraphMycielskian
 3.4 Random digraphs
 3.5 Standard examples

3 Creating digraphs

In this chapter we describe how to create digraphs.

3.1 Creating digraphs

3.1-1 IsDigraph
‣ IsDigraph( category )

Every digraph in Digraphs belongs to the category IsDigraph. Some basic attributes and operations for digraphs are DigraphVertices (5.1-1), DigraphEdges (5.1-3), and OutNeighbours (5.2-6).

3.1-2 IsMutableDigraph
‣ IsMutableDigraph( category )

IsMutableDigraph is a synonym for IsDigraph (3.1-1) and IsMutable (Reference: IsMutable). A mutable digraph may be changed in-place by methods in the Digraphs package, and is not attribute-storing – see IsAttributeStoringRep (Reference: IsAttributeStoringRep).

A mutable digraph may be converted into an immutable attribute-storing digraph by calling MakeImmutable (Reference: MakeImmutable) on the digraph.

3.1-3 IsImmutableDigraph
‣ IsImmutableDigraph( category )

IsImmutableDigraph is a subcategory of IsDigraph (3.1-1). Digraphs that lie in IsImmutableDigraph are immutable and attribute-storing. In particular, they lie in IsAttributeStoringRep (Reference: IsAttributeStoringRep).

A mutable digraph may be converted to an immutable digraph that lies in the category IsImmutableDigraph by calling MakeImmutable (Reference: MakeImmutable) on the digraph.

The operation DigraphMutableCopy (3.3-1) can be used to construct a mutable copy of an immutable digraph. It is however not possible to convert an immutable digraph into a mutable digraph in-place.

3.1-4 IsCayleyDigraph
‣ IsCayleyDigraph( category )

IsCayleyDigraph is a subcategory of IsDigraph. Digraphs that are Cayley digraphs of a group and that are constructed by the operation CayleyDigraph (3.1-12) are constructed in this category, and are always immutable.

3.1-5 IsDigraphWithAdjacencyFunction
‣ IsDigraphWithAdjacencyFunction( category )

IsDigraphWithAdjacencyFunction is a subcategory of IsDigraph. Digraphs that are created using an adjacency function are constructed in this category.

3.1-6 DigraphByOutNeighboursType
‣ DigraphByOutNeighboursType( global variable )
‣ DigraphFamily( family )

The type of all digraphs is DigraphByOutNeighboursType. The family of all digraphs is DigraphFamily.

3.1-7 Digraph
‣ Digraph( [filt, ]obj[, source, range] )( operation )
‣ Digraph( [filt, ]list, func )( operation )
‣ Digraph( [filt, ]G, list, act, adj )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

for a list (i.e. an adjacency list)

if obj is a list of lists of positive integers in the range from 1 to Length(obj), then this function returns the digraph with vertices \(E ^ 0 = \)[1 .. Length(obj)], and edges corresponding to the entries of obj.

More precisely, there is an edge from vertex i to j if and only if j is in obj[i]; the source of this edge is i and the range is j. If j occurs in obj[i] with multiplicity k, then there are k edges from i to j.

for three lists

if obj is a duplicate-free list, and source and range are lists of equal length consisting of positive integers in the list [1 .. Length(obj)], then this function returns a digraph with vertices \(E ^ 0 = \)[1 .. Length(obj)], and Length(source) edges. For each i in [1 .. Length(source)] there exists an edge with source vertex source[i] and range vertex range[i]. See DigraphSource (5.2-5) and DigraphRange (5.2-5).

The vertices of the digraph will be labelled by the elements of obj.

for an integer, and two lists

if obj is an integer, and source and range are lists of equal length consisting of positive integers in the list [1 .. obj], then this function returns a digraph with vertices \(E ^ 0 = \)[1 .. obj], and Length(source) edges. For each i in [1 .. Length(source)] there exists an edge with source vertex source[i] and range vertex range[i]. See DigraphSource (5.2-5) and DigraphRange (5.2-5).

for a list and a function

if list is a list and func is a function taking 2 arguments that are elements of list, and func returns true or false, then this operation creates a digraph with vertices [1 .. Length(list)] and an edge from vertex i to vertex j if and only if func(list[i], list[j]) returns true.

for a group, a list, and two functions

The arguments will be G, list, act, adj.

Let G be a group acting on the objects in list via the action act, and let adj be a function taking two objects from list as arguments and returning true or false. The function adj will describe the adjacency between objects from list, which is invariant under the action of G. This variant of the constructor returns a digraph with vertices the objects of list and directed edges [x, y] when f(x, y) is true.

The action of the group G on the objects in list is stored in the attribute DigraphGroup (7.2-10), and is used to speed up operations like DigraphDiameter (5.4-1).

for a Grape package graph

if obj is a GRAPE package graph (i.e. a record for which the function IsGraph returns true), then this function returns a digraph isomorphic to obj.

for a binary relation

if obj is a binary relation on the points [1 .. n] for some positive integer \(n\), then this function returns the digraph defined by obj. Specifically, this function returns a digraph which has \(n\) vertices, and which has an edge with source i and range j if and only if [i,j] is a pair in the binary relation obj.

for a string naming a digraph

if obj is a non-empty string, then this function returns the digraph that has name obj. Digraphs comes with a database containing a few hundred common digraph names that can be loaded in this way. Valid names include "folkman", "diamond" and "brinkmann". If the name is commonly followed by the word "graph", then it is called without writing "graph" at the end. You can explore the available graph names using ListNamedDigraphs (3.1-13). Digraph names are case and whitespace insensitive.

Note that any undirected graphs in the database are stored as symmetric digraphs, so the resulting digraph will have twice as many edges as its undirected counterpart.

gap> gr := Digraph([
> [2, 5, 8, 10], [2, 3, 4, 2, 5, 6, 8, 9, 10], [1],
> [3, 5, 7, 8, 10], [2, 5, 7], [3, 6, 7, 9, 10], [1, 4],
> [1, 5, 9], [1, 2, 7, 8], [3, 5]]);
<immutable multidigraph with 10 vertices, 38 edges>
gap> gr := Digraph(["a", "b", "c"], ["a"], ["b"]);
<immutable digraph with 3 vertices, 1 edge>
gap> gr := Digraph(5, [1, 2, 2, 4, 1, 1], [2, 3, 5, 5, 1, 1]);
<immutable multidigraph with 5 vertices, 6 edges>
gap> Petersen := Graph(SymmetricGroup(5), [[1, 2]], OnSets,
> function(x, y) return Intersection(x, y) = []; end);;
gap> Digraph(Petersen);
<immutable digraph with 10 vertices, 30 edges>
gap> gr := Digraph([1 .. 10], ReturnTrue);
<immutable digraph with 10 vertices, 100 edges>
gap> Digraph("Diamond");
<immutable digraph with 4 vertices, 10 edges>

The next example illustrates the uses of the fourth and fifth variants of this constructor. The resulting digraph is a strongly regular graph, and it is actually the point graph of the van Lint-Schrijver partial geometry, [vLS81]. The algebraic description is taken from the seminal paper of Calderbank and Kantor [CK86].

gap> f := GF(3 ^ 4);
GF(3^4)
gap> gamma := First(f, x -> Order(x) = 5);
Z(3^4)^64
gap> L := Union([Zero(f)], List(Group(gamma)));
[ 0*Z(3), Z(3)^0, Z(3^4)^16, Z(3^4)^32, Z(3^4)^48, Z(3^4)^64 ]
gap> omega := Union(List(L, x -> List(Difference(L, [x]), y -> x - y)));
[ Z(3)^0, Z(3), Z(3^4)^5, Z(3^4)^7, Z(3^4)^8, Z(3^4)^13, Z(3^4)^15, 
  Z(3^4)^16, Z(3^4)^21, Z(3^4)^23, Z(3^4)^24, Z(3^4)^29, Z(3^4)^31, 
  Z(3^4)^32, Z(3^4)^37, Z(3^4)^39, Z(3^4)^45, Z(3^4)^47, Z(3^4)^48, 
  Z(3^4)^53, Z(3^4)^55, Z(3^4)^56, Z(3^4)^61, Z(3^4)^63, Z(3^4)^64, 
  Z(3^4)^69, Z(3^4)^71, Z(3^4)^72, Z(3^4)^77, Z(3^4)^79 ]
gap> adj := function(x, y)
>   return x - y in omega;
> end;
function( x, y ) ... end
gap> digraph := Digraph(AsList(f), adj);
<immutable digraph with 81 vertices, 2430 edges>
gap> group := Group(Z(3));;
gap> act := \*;
<Operation "*">
gap> digraph := Digraph(group, List(f), act, adj);
<immutable digraph with 81 vertices, 2430 edges>

3.1-8 DigraphByAdjacencyMatrix
‣ DigraphByAdjacencyMatrix( [filt, ]list )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

If list is the adjacency matrix of a digraph in the sense of AdjacencyMatrix (5.2-1), then this operation returns the digraph which is defined by list.

Alternatively, if list is a square boolean matrix, then this operation returns the digraph with Length(list) vertices which has the edge [i,j] if and only if list[i][j] is true.

gap> DigraphByAdjacencyMatrix([
> [0, 1, 0, 2, 0],
> [1, 1, 1, 0, 1],
> [0, 3, 2, 1, 1],
> [0, 0, 1, 0, 1],
> [2, 0, 0, 0, 0]]);
<immutable multidigraph with 5 vertices, 18 edges>
gap> D := DigraphByAdjacencyMatrix([
> [true, false, true],
> [false, false, true],
> [false, true, false]]);
<immutable digraph with 3 vertices, 4 edges>
gap> OutNeighbours(D);
[ [ 1, 3 ], [ 3 ], [ 2 ] ]
gap> D := DigraphByAdjacencyMatrix(IsMutableDigraph, 
> [[true, false, true],
>  [false, false, true],
>  [false, true, false]]);
<mutable digraph with 3 vertices, 4 edges>

3.1-9 DigraphByEdges
‣ DigraphByEdges( [filt, ]list[, n] )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

If list is list of pairs of positive integers, then this function returns the digraph with the minimum number of vertices m such that its list equal list.

If the optional second argument n is a positive integer with n >= m (with m defined as above), then this function returns the digraph with n vertices and list list.

See DigraphEdges (5.1-3).

gap> DigraphByEdges(
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]]);
<immutable digraph with 6 vertices, 10 edges>
gap> DigraphByEdges(
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]], 12);
<immutable digraph with 12 vertices, 10 edges>
gap> DigraphByEdges(IsMutableDigraph, 
> [[1, 3], [2, 1], [2, 3], [2, 5], [3, 6],
>  [4, 6], [5, 2], [5, 4], [5, 6], [6, 6]], 12);
<mutable digraph with 12 vertices, 10 edges>

3.1-10 EdgeOrbitsDigraph
‣ EdgeOrbitsDigraph( G, edges[, n] )( operation )

Returns: An immutable digraph.

If G is a permutation group, edges is an edge or list of edges, and n is a non-negative integer such that G fixes [1 .. n] setwise, then this operation returns an immutable digraph with n vertices and the union of the orbits of the edges in edges under the action of the permutation group G. An edge in this context is simply a pair of positive integers.

If the optional third argument n is not present, then the largest moved point of the permutation group G is used by default.

gap> digraph := EdgeOrbitsDigraph(Group((1, 3), (1, 2)(3, 4)),
>                                 [[1, 2], [4, 5]], 5);
<immutable digraph with 5 vertices, 12 edges>
gap> OutNeighbours(digraph);
[ [ 2, 4, 5 ], [ 1, 3, 5 ], [ 2, 4, 5 ], [ 1, 3, 5 ], [  ] ]
gap> RepresentativeOutNeighbours(digraph);
[ [ 2, 4, 5 ], [  ] ]

3.1-11 DigraphByInNeighbours
‣ DigraphByInNeighbours( [filt, ]list )( operation )
‣ DigraphByInNeighbors( [filt, ]list )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

If list is a list of lists of positive integers list the range [1 .. Length(list)], then this function returns the digraph with vertices \(E^0=\)[1 .. Length(list)], and edges corresponding to the entries of list. More precisely, there is an edge with source vertex i and range vertex j if i is in the list list[j].

If i occurs in the list list[j] with multiplicity k, then there are k multiple edges from i to j.

See InNeighbours (5.2-7).

gap> D := DigraphByInNeighbours([
> [2, 5, 8, 10], [2, 3, 4, 5, 6, 8, 9, 10],
> [1], [3, 5, 7, 8, 10], [2, 5, 7], [3, 6, 7, 9, 10], [1, 4],
> [1, 5, 9], [1, 2, 7, 8], [3, 5]]);
<immutable digraph with 10 vertices, 37 edges>
gap> D := DigraphByInNeighbours([[2, 3, 2], [1], [1, 2, 3]]);
<immutable multidigraph with 3 vertices, 7 edges>
gap> D := DigraphByInNeighbours(IsMutableDigraph, 
>                               [[2, 3, 2], [1], [1, 2, 3]]);
<mutable multidigraph with 3 vertices, 7 edges>

3.1-12 CayleyDigraph
‣ CayleyDigraph( G[, gens] )( operation )

Returns: An immutable digraph.

Let G be any group and let gens be a list of elements of G. This operation returns an immutable digraph that corresponds to the Cayley graph of G with respect to gens.

The vertices of the digraph correspond to the elements of G, in the order given by AsList(G). There exists an edge from vertex u to vertex v if and only if there exists a generator g in gens such that AsList(G)[u] * g = AsList(G)[v].

The labels of the vertices u, v, and the edge [u, v] are the corresponding elements AsList(G)[u], AsList(G)[v], and generator g, respectively; see DigraphVertexLabel (5.1-11) and DigraphEdgeLabel (5.1-13).

If the optional second argument gens is not present, then the generators of G are used by default.

The digraph created by this operation belongs to the category IsCayleyDigraph (3.1-4), the group G can be recovered from the digraph using GroupOfCayleyDigraph (5.5-1), and the generators gens can be obtained using GeneratorsOfCayleyDigraph (5.5-2).

Note that this function can only return an immutable digraph.

gap> G := DihedralGroup(8);
<pc group of size 8 with 3 generators>
gap> CayleyDigraph(G);
<immutable digraph with 8 vertices, 24 edges>
gap> G := DihedralGroup(IsPermGroup, 8);
Group([ (1,2,3,4), (2,4) ])
gap> CayleyDigraph(G);
<immutable digraph with 8 vertices, 16 edges>
gap> digraph := CayleyDigraph(G, [()]);
<immutable digraph with 8 vertices, 8 edges>
gap> GroupOfCayleyDigraph(digraph) = G;
true
gap> GeneratorsOfCayleyDigraph(digraph);
[ () ]

3.1-13 ListNamedDigraphs
‣ ListNamedDigraphs( s[, level] )( operation )

Returns: A list of strings representing digraph names.

This function searches through the list of names that are currently in the Digraphs database of named digraphs. The first argument s should be a partially completed string; this function returns all completions str of the string s such that Digraph(str) will successfully return a digraph.

The optional second argument level controls the flexibility of the search. If level = 1, then only strings beginning exactly with s are returned. If level = 2, then all names containing s as a substring are returned. If level = 3, then once again a substring search is carried out, but characters that are not alphanumeric are ignored in the search.

If level is not specified, it is set by default to equal 2.

The search is always case and whitespace insensitive, and this is also the case when applying Digraph (3.1-7) to a string.

3.2 Changing representations

3.2-1 AsBinaryRelation
‣ AsBinaryRelation( digraph )( operation )

Returns: A binary relation.

If digraph is a digraph with a positive number of vertices \(n\), and no multiple edges, then this operation returns a binary relation on the points [1..n]. The pair [i,j] is in the binary relation if and only if [i,j] is an edge in digraph.

gap> D := Digraph([[3, 2], [1, 2], [2], [3, 4]]);
<immutable digraph with 4 vertices, 7 edges>
gap> AsBinaryRelation(D);
Binary Relation on 4 points

3.2-2 AsDigraph
‣ AsDigraph( [filt, ]f[, n] )( operation )

Returns: A digraph, or fail.

If f is a binary relation represented as one of the following in GAP:

a transformation

satisfying IsTransformation (Reference: IsTransformation);

a permutation

satisfying IsPerm (Reference: IsPerm);

a partial perm

satisfying IsPartialPerm (Reference: IsPartialPerm);

a binary relation

satisfying IsBinaryRelation (Reference: IsBinaryRelation);

and n is a non-negative integer, then AsDigraph attempts to construct a digraph with n vertices whose edges are determined by f.

The digraph returned by AsDigraph has for each vertex v in [1 .. n], an edge with source v and range v ^ f. If v ^ f is greater than n for any v, then fail is returned.

If the optional second argument n is not supplied, then the degree of the transformation f, the largest moved point of the permutation f, the maximum of the degree and the codegree of the partial perm f, or as applicable, is used by default.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> f := Transformation([4, 3, 3, 1, 7, 9, 10, 4, 2, 3]);
Transformation( [ 4, 3, 3, 1, 7, 9, 10, 4, 2, 3 ] )
gap> AsDigraph(f);
<immutable functional digraph with 10 vertices>
gap> AsDigraph(f, 4);
<immutable functional digraph with 4 vertices>
gap> AsDigraph(f, 5);
fail
gap> AsDigraph((1, 2, 3, 4)) = CycleDigraph(4);
true
gap> D := AsDigraph(IsMutableDigraph, (1, 3)(2, 4), 5);
<mutable digraph with 5 vertices, 5 edges>
gap> DigraphEdges(D);
[ [ 1, 3 ], [ 2, 4 ], [ 3, 1 ], [ 4, 2 ], [ 5, 5 ] ]
gap> b := BinaryRelationOnPoints(
> [[3], [1, 3, 5], [1], [1, 2, 4], [2, 3, 5]]);
Binary Relation on 5 points
gap> D := AsDigraph(b);
<immutable digraph with 5 vertices, 11 edges>

3.2-3 Graph
‣ Graph( digraph )( operation )

Returns: A GRAPE package graph.

If digraph is a mutable or immutable digraph without multiple edges, then this operation returns a GRAPE package graph that is isomorphic to digraph.

If digraph is a multidigraph, then since GRAPE does not support multiple edges, the multiple edges will be reduced to a single edge in the result. In order words, for a multidigraph this operation will return the same as Graph(DigraphRemoveAllMultipleEdges(digraph)).

gap> Petersen := Graph(SymmetricGroup(5), [[1, 2]], OnSets,
> function(x, y) return Intersection(x, y) = []; end);;
gap> Display(Petersen);
rec(
  adjacencies := [ [ 3, 5, 8 ] ],
  group := 
   Group( [ ( 1, 2, 3, 5, 7)( 4, 6, 8, 9,10), ( 2, 4)( 6, 9)( 7,10) 
     ] ),
  isGraph := true,
  names := [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 1, 3 ], [ 4, 5 ], 
      [ 2, 4 ], [ 1, 5 ], [ 3, 5 ], [ 1, 4 ], [ 2, 5 ] ],
  order := 10,
  representatives := [ 1 ],
  schreierVector := [ -1, 1, 1, 2, 1, 1, 1, 1, 2, 2 ] )
gap> Digraph(Petersen);
<immutable digraph with 10 vertices, 30 edges>
gap> Graph(last) = Petersen;
true

3.2-4 AsGraph
‣ AsGraph( digraph )( attribute )

Returns: A GRAPE package graph.

If digraph is a digraph, then this method returns the same as Graph (3.2-3), except that if digraph is immutable, then the result will be stored as a mutable attribute of digraph. In this latter case, when AsGraph(digraph) is called subsequently, the same GAP object will be returned as before.

gap> D := Digraph([[1, 2], [3], []]);
<immutable digraph with 3 vertices, 3 edges>
gap> G := AsGraph(D);
rec( adjacencies := [ [ 1, 2 ], [ 3 ], [  ] ], group := Group(()), 
  isGraph := true, names := [ 1 .. 3 ], order := 3, 
  representatives := [ 1, 2, 3 ], schreierVector := [ -1, -2, -3 ] )

3.2-5 AsTransformation
‣ AsTransformation( digraph )( attribute )

Returns: A transformation, or fail

If digraph is a functional digraph, then AsTransformation returns the transformation which is defined by digraph. See IsFunctionalDigraph (6.2-9). Otherwise, AsTransformation(digraph) returns fail.

If digraph is a functional digraph with \(n\) vertices, then AsTransformation(digraph) will return the transformation f of degree at most \(n\) where for each \(1 \leq i \leq n\), i ^ f is equal to the unique out-neighbour of vertex i in digraph.

gap> D := Digraph([[1], [3], [2]]);
<immutable digraph with 3 vertices, 3 edges>
gap> AsTransformation(D);
Transformation( [ 1, 3, 2 ] )
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> AsTransformation(D);
Transformation( [ 2, 3, 1 ] )
gap> AsPermutation(last);
(1,2,3)
gap> D := Digraph([[2, 3], [], []]);
<immutable digraph with 3 vertices, 2 edges>
gap> AsTransformation(D);
fail

3.3 New digraphs from old

3.3-1 DigraphImmutableCopy
‣ DigraphImmutableCopy( digraph )( operation )
‣ DigraphMutableCopy( digraph )( operation )
‣ DigraphCopySameMutability( digraph )( operation )
‣ DigraphCopy( digraph )( operation )

Returns: A digraph.

Each of these operations returns a new copy of digraph, of the appropriate mutability, retaining none of the attributes or properties of digraph.

DigraphCopy is a synonym for DigraphCopySameMutability.

gap> D := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> DigraphCopy(D) = D;
true
gap> IsIdenticalObj(DigraphCopy(D), D);
false
gap> DigraphMutableCopy(D);
<mutable digraph with 10 vertices, 10 edges>

3.3-2 DigraphImmutableCopyIfImmutable
‣ DigraphImmutableCopyIfImmutable( digraph )( operation )
‣ DigraphImmutableCopyIfMutable( digraph )( operation )
‣ DigraphMutableCopyIfMutable( digraph )( operation )
‣ DigraphMutableCopyIfImmutable( digraph )( operation )

Returns: A digraph.

Each of these operations returns either the original argument digraph, or a new copy of digraph of the appropriate mutability, according to the mutability of digraph.

gap> C := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> D := DigraphImmutableCopyIfImmutable(C);
<immutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
false
gap> C = D;
true
gap> D := DigraphImmutableCopyIfMutable(C);
<immutable cycle digraph with 10 vertices>
gap> IsIdenticalObj(C, D);
true
gap> C = D;
true
gap> D := DigraphMutableCopyIfMutable(C);
<immutable cycle digraph with 10 vertices>
gap> IsMutableDigraph(D);
false
gap> D := DigraphMutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsMutableDigraph(D);
true
gap> C := CycleDigraph(IsMutableDigraph, 10);
<mutable digraph with 10 vertices, 10 edges>
gap> D := DigraphImmutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
true
gap> C = D;
true
gap> D := DigraphImmutableCopyIfMutable(C);
<immutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
false
gap> C = D;
true
gap> D := DigraphMutableCopyIfMutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsMutableDigraph(D);
true
gap> D := DigraphMutableCopyIfImmutable(C);
<mutable digraph with 10 vertices, 10 edges>
gap> IsIdenticalObj(C, D);
true
gap> IsMutableDigraph(D);
true

3.3-3 InducedSubdigraph
‣ InducedSubdigraph( digraph, verts )( operation )

Returns: A digraph.

If digraph is a digraph, and verts is a subset of the vertices of digraph, then this operation returns a digraph constructed from digraph by retaining precisely those vertices in verts, and those edges whose source and range vertices are both contained in verts.

The vertices of the induced subdigraph are [1..Length(verts)] but the original vertex labels can be accessed via DigraphVertexLabels (5.1-12).

If digraph belongs to IsMutableDigraph (3.1-2), then digraph is modified in place. If digraph belongs to IsImmutableDigraph (3.1-3), a new immutable digraph containing the appropriate vertices and edges is returned.

gap> D := Digraph([[1, 1, 2, 3, 4, 4], [1, 3, 4], [3, 1], [1, 1]]);
<immutable multidigraph with 4 vertices, 13 edges>
gap> InducedSubdigraph(D, [1, 3, 4]);
<immutable multidigraph with 3 vertices, 9 edges>
gap> DigraphVertices(last);
[ 1 .. 3 ]
gap> D := DigraphMutableCopy(D);
<mutable multidigraph with 4 vertices, 13 edges>
gap> new := InducedSubdigraph(D, [1, 3, 4]);
<mutable multidigraph with 3 vertices, 9 edges>
gap> D = new;
true

3.3-4 ReducedDigraph
‣ ReducedDigraph( digraph )( operation )
‣ ReducedDigraphAttr( digraph )( attribute )

Returns: A digraph.

This function returns a digraph isomorphic to the subdigraph of digraph induced by the set of non-isolated vertices, i.e. the set of those vertices of digraph which are the source or range of some edge in digraph. See InducedSubdigraph (3.3-3).

The ordering of the remaining vertices of digraph is preserved, as are the labels of the remaining vertices and edges; see DigraphVertexLabels (5.1-12) and DigraphEdgeLabels (5.1-14). This can allow one to match a vertex in the reduced digraph to the corresponding vertex in digraph.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the isolated vertices of the mutable digraph digraph are removed in-place.

gap> D := Digraph([[1, 2], [], [], [1, 4], []]);
<immutable digraph with 5 vertices, 4 edges>
gap> R := ReducedDigraph(D);
<immutable digraph with 3 vertices, 4 edges>
gap> OutNeighbours(R);
[ [ 1, 2 ], [  ], [ 1, 3 ] ]
gap> DigraphEdges(D);
[ [ 1, 1 ], [ 1, 2 ], [ 4, 1 ], [ 4, 4 ] ]
gap> DigraphEdges(R);
[ [ 1, 1 ], [ 1, 2 ], [ 3, 1 ], [ 3, 3 ] ]
gap> DigraphVertexLabel(R, 3);
4
gap> DigraphVertexLabel(R, 2);
2
gap> D := Digraph(IsMutableDigraph, [[], [3], [2]]);
<mutable digraph with 3 vertices, 2 edges>
gap> ReducedDigraph(D);
<mutable digraph with 2 vertices, 2 edges>
gap> D;
<mutable digraph with 2 vertices, 2 edges>

3.3-5 MaximalSymmetricSubdigraph
‣ MaximalSymmetricSubdigraph( digraph )( operation )
‣ MaximalSymmetricSubdigraphAttr( digraph )( attribute )
‣ MaximalSymmetricSubdigraphWithoutLoops( digraph )( operation )
‣ MaximalSymmetricSubdigraphWithoutLoopsAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph, then MaximalSymmetricSubdigraph returns a symmetric digraph without multiple edges which has the same vertex set as digraph, and whose edge list is formed from digraph by ignoring the multiplicity of edges, and by ignoring edges [u,v] for which there does not exist an edge [v,u].

The digraph returned by MaximalSymmetricSubdigraphWithoutLoops is the same, except that loops are removed.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into such a digraph described above.

See IsSymmetricDigraph (6.2-14), IsMultiDigraph (6.2-11), and DigraphHasLoops (6.2-1) for more information.

gap> D := Digraph([[2, 2], [1, 3], [4], [3, 1]]);
<immutable multidigraph with 4 vertices, 7 edges>
gap> not IsSymmetricDigraph(D) and IsMultiDigraph(D);
true
gap> OutNeighbours(D);
[ [ 2, 2 ], [ 1, 3 ], [ 4 ], [ 3, 1 ] ]
gap> S := MaximalSymmetricSubdigraph(D);
<immutable symmetric digraph with 4 vertices, 4 edges>
gap> IsSymmetricDigraph(S) and not IsMultiDigraph(S);
true
gap> OutNeighbours(S);
[ [ 2 ], [ 1 ], [ 4 ], [ 3 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> MaximalSymmetricSubdigraph(D);
<mutable empty digraph with 3 vertices>
gap> D;
<mutable empty digraph with 3 vertices>

3.3-6 MaximalAntiSymmetricSubdigraph
‣ MaximalAntiSymmetricSubdigraph( digraph )( operation )
‣ MaximalAntiSymmetricSubdigraphAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph, then MaximalAntiSymmetricSubdigraph returns an anti-symmetric subdigraph of digraph formed by retaining the vertices of digraph, discarding any duplicate edges, and discarding any edge [i,j] of digraph where i > j and the reverse edge [j,i] is an edge of digraph. In other words, for every symmetric pair of edges [i,j] and [j,i] in digraph, where i and j are distinct, it discards the edge \([\max(i,j),\min(i,j)]\).

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place.

See IsAntisymmetricDigraph (6.2-2) for more information.

gap> D := Digraph([[2, 2], [1, 3], [4], [3, 1]]);
<immutable multidigraph with 4 vertices, 7 edges>
gap> not IsAntiSymmetricDigraph(D) and IsMultiDigraph(D);
true
gap> OutNeighbours(D);
[ [ 2, 2 ], [ 1, 3 ], [ 4 ], [ 3, 1 ] ]
gap> D := MaximalAntiSymmetricSubdigraph(D);
<immutable antisymmetric digraph with 4 vertices, 4 edges>
gap> IsAntiSymmetricDigraph(D) and not IsMultiDigraph(D);
true
gap> OutNeighbours(D);
[ [ 2 ], [ 3 ], [ 4 ], [ 1 ] ]
gap> D := Digraph(IsMutableDigraph, [[2], [1]]);
<mutable digraph with 2 vertices, 2 edges>
gap> MaximalAntiSymmetricSubdigraph(D);
<mutable digraph with 2 vertices, 1 edge>
gap> D;
<mutable digraph with 2 vertices, 1 edge>

3.3-7 UndirectedSpanningForest
‣ UndirectedSpanningForest( digraph )( operation )
‣ UndirectedSpanningForestAttr( digraph )( attribute )
‣ UndirectedSpanningTree( digraph )( operation )
‣ UndirectedSpanningTreeAttr( digraph )( attribute )

Returns: A digraph, or fail.

If digraph is a digraph with at least one vertex, then UndirectedSpanningForest returns an undirected spanning forest of digraph, otherwise this attribute returns fail. See IsUndirectedSpanningForest (4.1-2) for the definition of an undirected spanning forest.

If digraph is a digraph with at least one vertex and whose MaximalSymmetricSubdigraph (3.3-5) is connected (see IsConnectedDigraph (6.6-3)), then UndirectedSpanningTree returns an undirected spanning tree of digraph, otherwise this attribute returns fail. See IsUndirectedSpanningTree (4.1-2) for the definition of an undirected spanning tree.

If digraph is immutable, then an immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into an undirected spanning tree of digraph.

Note that for an immutable digraph that has known undirected spanning tree, the attribute UndirectedSpanningTree returns the same digraph as the attribute UndirectedSpanningForest.

gap> D := Digraph([[1, 2, 1, 3], [1], [4], [3, 4, 3]]);
<immutable multidigraph with 4 vertices, 9 edges>
gap> UndirectedSpanningTree(D);
fail
gap> forest := UndirectedSpanningForest(D);
<immutable undirected forest digraph with 4 vertices, 4 edges>
gap> OutNeighbours(forest);
[ [ 2 ], [ 1 ], [ 4 ], [ 3 ] ]
gap> IsUndirectedSpanningForest(D, forest);
true
gap> DigraphConnectedComponents(forest).comps;
[ [ 1, 2 ], [ 3, 4 ] ]
gap> DigraphConnectedComponents(MaximalSymmetricSubdigraph(D)).comps;
[ [ 1, 2 ], [ 3, 4 ] ]
gap> UndirectedSpanningForest(MaximalSymmetricSubdigraph(D))
> = forest;
true
gap> D := CompleteDigraph(4);
<immutable complete digraph with 4 vertices>
gap> tree := UndirectedSpanningTree(D);
<immutable undirected tree digraph with 4 vertices>
gap> IsUndirectedSpanningTree(D, tree);
true
gap> tree = UndirectedSpanningForest(D);
true
gap> UndirectedSpanningForest(EmptyDigraph(0));
fail
gap> D := PetersenGraph(IsMutableDigraph);
<mutable digraph with 10 vertices, 30 edges>
gap> UndirectedSpanningTree(D);
<mutable digraph with 10 vertices, 18 edges>
gap> D;
<mutable digraph with 10 vertices, 18 edges>

3.3-8 DigraphShortestPathSpanningTree
‣ DigraphShortestPathSpanningTree( digraph, v )( operation )

Returns: A digraph, or fail.

If v is a vertex in digraph and every other vertex of digraph is reachable from v, then this operation returns the shortest path spanning tree of digraph rooted at v. If there exist vertices in digraph (other than v) that are not reachable from v, then DigraphShortestPathSpanningTree returns fail. See IsReachable (5.4-19).

The shortest path spanning tree of digraph rooted at v is a subdigraph of digraph that is a directed tree, with unique source vertex v, and where for each other vertex u in digraph, the unique directed path from v to u in the tree is the lexicographically-least shortest directed path from v to u in digraph.

See IsDirectedTree (6.6-8), DigraphSources (5.1-9), and DigraphShortestPath (5.4-23).

If digraph belongs to IsMutableDigraph (3.1-2), then digraph is modified in place. If digraph belongs to IsImmutableDigraph (3.1-3), then the spanning tree is a new immutable digraph.

gap> D := Digraph([[1, 2], [3], [2, 4], [1], [2, 4]]);
<immutable digraph with 5 vertices, 8 edges>
gap> ForAll([2 .. 5], v -> IsReachable(D, 1, v));
false
gap> DigraphShortestPathSpanningTree(D, 1);
fail
gap> tree := DigraphShortestPathSpanningTree(D, 5);
<immutable directed tree digraph with 5 vertices>
gap> OutNeighbours(tree);
[ [  ], [ 3 ], [  ], [ 1 ], [ 2, 4 ] ]
gap> ForAll(DigraphVertices(D), v ->
> DigraphShortestPath(D, 5, v) = DigraphPath(tree, 5, v));
true

3.3-9 QuotientDigraph
‣ QuotientDigraph( digraph, p )( operation )

Returns: A digraph.

If digraph is a digraph, and p is a partition of the vertices of digraph, then this operation returns a digraph constructed by amalgamating all vertices of digraph which lie in the same part of p.

A partition of the vertices of digraph is a list of non-empty disjoint lists, such that the union of all the sub-lists is equal to vertex set of digraph. In particular, each vertex must appear in precisely one sub-list.

The vertices of digraph in part i of p will become vertex i in the quotient, and there exists some edge in digraph with source in part i and range in part j if and only if there is an edge from i to j in the quotient. In particular, this means that the quotient of a digraph has no multiple edges. which was a change introduced in version 1.0.0 of the Digraphs package.

If digraph belongs to IsMutableDigraph (3.1-2), then digraph is modified in place. If digraph belongs to IsImmutableDigraph (3.1-3), a new immutable digraph with the above properties is returned.

gap> D := Digraph([[2, 1], [4], [1], [1, 3, 4]]);
<immutable digraph with 4 vertices, 7 edges>
gap> DigraphVertices(D);
[ 1 .. 4 ]
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 1 ], [ 2, 4 ], [ 3, 1 ], [ 4, 1 ], [ 4, 3 ], 
  [ 4, 4 ] ]
gap> p := [[1], [2, 4], [3]];
[ [ 1 ], [ 2, 4 ], [ 3 ] ]
gap> quo := QuotientDigraph(D, p);
<immutable digraph with 3 vertices, 6 edges>
gap> DigraphVertices(quo);
[ 1 .. 3 ]
gap> DigraphEdges(quo);
[ [ 1, 1 ], [ 1, 2 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 3, 1 ] ]
gap> QuotientDigraph(EmptyDigraph(0), []);
<immutable empty digraph with 0 vertices>

3.3-10 DigraphReverse
‣ DigraphReverse( digraph )( operation )
‣ DigraphReverseAttr( digraph )( attribute )

Returns: A digraph.

The reverse of a digraph is the digraph formed by reversing the orientation of each of its edges, i.e. for every edge [i, j] of a digraph, the reverse contains the corresponding edge [j, i].

DigraphReverse returns the reverse of the digraph digraph. If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its reverse.

gap> D := Digraph([[3], [1, 3, 5], [1], [1, 2, 4], [2, 3, 5]]);
<immutable digraph with 5 vertices, 11 edges>
gap> DigraphReverse(D);
<immutable digraph with 5 vertices, 11 edges>
gap> OutNeighbours(last);
[ [ 2, 3, 4 ], [ 4, 5 ], [ 1, 2, 5 ], [ 4 ], [ 2, 5 ] ]
gap> D := Digraph([[2, 4], [1], [4], [3, 4]]);
<immutable digraph with 4 vertices, 6 edges>
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 4 ], [ 2, 1 ], [ 3, 4 ], [ 4, 3 ], [ 4, 4 ] ]
gap> DigraphEdges(DigraphReverse(D));
[ [ 1, 2 ], [ 2, 1 ], [ 3, 4 ], [ 4, 1 ], [ 4, 3 ], [ 4, 4 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> OutNeighbours(D);
[ [ 2 ], [ 3 ], [ 1 ] ]
gap> DigraphReverse(D);
<mutable digraph with 3 vertices, 3 edges>
gap> OutNeighbours(D);
[ [ 3 ], [ 1 ], [ 2 ] ]

3.3-11 DigraphDual
‣ DigraphDual( digraph )( operation )
‣ DigraphDualAttr( digraph )( attribute )

Returns: A digraph.

The dual of digraph has the same vertices as digraph, and there is an edge in the dual from i to j whenever there is no edge from i to j in digraph. The dual is sometimes called the complement.

DigraphDual returns the dual of the digraph digraph. If digraph is an immutable digraph, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its dual.

gap> D := Digraph([[2, 3], [], [4, 6], [5], [],
> [7, 8, 9], [], [], []]);
<immutable digraph with 9 vertices, 8 edges>
gap> DigraphDual(D);
<immutable digraph with 9 vertices, 73 edges>
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> DigraphDual(D);
<mutable digraph with 3 vertices, 6 edges>
gap> D;
<mutable digraph with 3 vertices, 6 edges>

3.3-12 DigraphSymmetricClosure
‣ DigraphSymmetricClosure( digraph )( operation )
‣ DigraphSymmetricClosureAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph, then this attribute gives the minimal symmetric digraph which has the same vertices and contains all the edges of digraph.

A digraph is symmetric if its adjacency matrix AdjacencyMatrix (5.2-1) is symmetric. For a digraph with multiple edges this means that there are the same number of edges from a vertex u to a vertex v as there are from v to u; see IsSymmetricDigraph (6.2-14).

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its symmetric closure.

gap> D := Digraph([[1, 2, 3], [2, 4], [1], [3, 4]]);
<immutable digraph with 4 vertices, 8 edges>
gap> D := DigraphSymmetricClosure(D);
<immutable symmetric digraph with 4 vertices, 11 edges>
gap> IsSymmetricDigraph(D);
true
gap> List(OutNeighbours(D), AsSet);
[ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 4 ], [ 2, 3, 4 ] ]
gap> D := Digraph([[2, 2], [1]]);
<immutable multidigraph with 2 vertices, 3 edges>
gap> D := DigraphSymmetricClosure(D);
<immutable symmetric multidigraph with 2 vertices, 4 edges>
gap> OutNeighbours(D);
[ [ 2, 2 ], [ 1, 1 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> DigraphSymmetricClosure(D);
<mutable digraph with 3 vertices, 6 edges>
gap> D;
<mutable digraph with 3 vertices, 6 edges>

3.3-13 DigraphTransitiveClosure
‣ DigraphTransitiveClosure( digraph )( operation )
‣ DigraphTransitiveClosureAttr( digraph )( attribute )
‣ DigraphReflexiveTransitiveClosure( digraph )( operation )
‣ DigraphReflexiveTransitiveClosureAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph with no multiple edges, then these attributes return the (reflexive) transitive closure of digraph.

A digraph is reflexive if it has a loop at every vertex, and it is transitive if whenever [i,j] and [j,k] are edges of digraph, [i,k] is also an edge. The (reflexive) transitive closure of a digraph digraph is the least (reflexive and) transitive digraph containing digraph.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its (reflexive) transitive closure.

Let \(n\) be the number of vertices of digraph, and let \(m\) be the number of edges. For an arbitrary digraph, these attributes will use a version of the Floyd-Warshall algorithm, with complexity \(O(n^3)\). However, for a topologically sortable digraph [see DigraphTopologicalSort (5.1-10)], these attributes will use methods with complexity \(O(m + n + m \cdot n)\) when this is faster.

gap> D := DigraphFromDiSparse6String(".H`eOWR`Ul^");
<immutable digraph with 9 vertices, 8 edges>
gap> IsReflexiveDigraph(D) or IsTransitiveDigraph(D);
false
gap> OutNeighbours(D);
[ [ 4, 6 ], [ 1, 3 ], [  ], [ 5 ], [  ], [ 7, 8, 9 ], [  ], [  ], 
  [  ] ]
gap> T := DigraphTransitiveClosure(D);
<immutable transitive digraph with 9 vertices, 18 edges>
gap> OutNeighbours(T);
[ [ 4, 6, 5, 7, 8, 9 ], [ 1, 3, 4, 5, 6, 7, 8, 9 ], [  ], [ 5 ], 
  [  ], [ 7, 8, 9 ], [  ], [  ], [  ] ]
gap> RT := DigraphReflexiveTransitiveClosure(D);
<immutable preorder digraph with 9 vertices, 27 edges>
gap> OutNeighbours(RT);
[ [ 4, 6, 5, 7, 8, 9, 1 ], [ 1, 3, 4, 5, 6, 7, 8, 9, 2 ], [ 3 ], 
  [ 5, 4 ], [ 5 ], [ 7, 8, 9, 6 ], [ 7 ], [ 8 ], [ 9 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> DigraphReflexiveTransitiveClosure(D);
<mutable digraph with 3 vertices, 9 edges>
gap> D;
<mutable digraph with 3 vertices, 9 edges>

3.3-14 DigraphTransitiveReduction
‣ DigraphTransitiveReduction( digraph )( operation )
‣ DigraphTransitiveReductionAttr( digraph )( attribute )
‣ DigraphReflexiveTransitiveReduction( digraph )( operation )
‣ DigraphReflexiveTransitiveReductionAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a topologically sortable digraph [see DigraphTopologicalSort (5.1-10)] with no multiple edges, then these operations return the (reflexive) transitive reduction of digraph.

The (reflexive) transitive reduction of such a digraph is the unique least subgraph such that the (reflexive) transitive closure of the subgraph is equal to the (reflexive) transitive closure of digraph [see DigraphReflexiveTransitiveClosure (3.3-13)]. In order words, it is the least subgraph of digraph which retains the same reachability as digraph.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its (reflexive) transitive reduction.

Let \(n\) be the number of vertices of an arbitrary digraph, and let \(m\) be the number of edges. Then these operations use methods with complexity \(O(m + n + m \cdot n)\).

gap> D := Digraph([[1, 2, 3], [3], [3]]);;
gap> DigraphHasLoops(D);
true
gap> D1 := DigraphReflexiveTransitiveReduction(D);
<immutable digraph with 3 vertices, 2 edges>
gap> DigraphHasLoops(D1);
false
gap> OutNeighbours(D1);
[ [ 2 ], [ 3 ], [  ] ]
gap> D2 := DigraphTransitiveReduction(D);
<immutable digraph with 3 vertices, 4 edges>
gap> DigraphHasLoops(D2);
true
gap> OutNeighbours(D2);
[ [ 2, 1 ], [ 3 ], [ 3 ] ]
gap> DigraphReflexiveTransitiveClosure(D)
>  = DigraphReflexiveTransitiveClosure(D1);
true
gap> DigraphTransitiveClosure(D)
>  = DigraphTransitiveClosure(D2);
true
gap> D := Digraph(IsMutableDigraph, [[1], [1], [1, 2, 3]]);
<mutable digraph with 3 vertices, 5 edges>
gap> DigraphReflexiveTransitiveReduction(D);
<mutable digraph with 3 vertices, 2 edges>
gap> D;
<mutable digraph with 3 vertices, 2 edges>

3.3-15 DigraphAddVertex
‣ DigraphAddVertex( digraph[, label] )( operation )

Returns: A digraph.

The operation returns a digraph constructed from digraph by adding a single new vertex, and no new edges.

If the optional second argument label is a GAP object, then the new vertex will be labelled label.

If digraph belongs to IsMutableDigraph (3.1-2), then the vertex is added directly to digraph. If digraph belongs to IsImmutableDigraph (3.1-3), an immutable copy of digraph with the additional vertex is returned.

gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> new := DigraphAddVertex(D);
<immutable digraph with 4 vertices, 6 edges>
gap> D = new;
false
gap> DigraphVertices(new);
[ 1 .. 4 ]
gap> new := DigraphAddVertex(D, Group([(1, 2)]));
<immutable digraph with 4 vertices, 6 edges>
gap> DigraphVertexLabels(new);
[ 1, 2, 3, Group([ (1,2) ]) ]
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 2, 3);
<mutable digraph with 5 vertices, 12 edges>
gap> new := DigraphAddVertex(D);
<mutable digraph with 6 vertices, 12 edges>
gap> D = new;
true

3.3-16 DigraphAddVertices
‣ DigraphAddVertices( digraph, m )( operation )
‣ DigraphAddVertices( digraph, labels )( operation )

Returns: A digraph.

For a non-negative integer m, this operation returns a digraph constructed from digraph by adding m new vertices.

Otherwise, if labels is a list consisting of k GAP objects, then this operation returns a digraph constructed from digraph by adding k new vertices, which are labelled according to this list.

If digraph belongs to IsMutableDigraph (3.1-2), then the vertices are added directly to digraph, which is changed in-place. If digraph belongs to IsImmutableDigraph (3.1-3), then digraph itself is returned if no vertices are added (i.e. m=0 or labels is empty), otherwise the result is a new immutable digraph.

gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> new := DigraphAddVertices(D, 3);
<immutable digraph with 6 vertices, 6 edges>
gap> DigraphVertices(new);
[ 1 .. 6 ]
gap> new := DigraphAddVertices(D, [Group([(1, 2)]), "d"]);
<immutable digraph with 5 vertices, 6 edges>
gap> DigraphVertexLabels(new);
[ 1, 2, 3, Group([ (1,2) ]), "d" ]
gap> DigraphAddVertices(D, 0) = D;
true
gap> D := CompleteBipartiteDigraph(IsMutableDigraph, 2, 3);
<mutable digraph with 5 vertices, 12 edges>
gap> new := DigraphAddVertices(D, 4);
<mutable digraph with 9 vertices, 12 edges>
gap> D = new;
true

3.3-17 DigraphAddEdge
‣ DigraphAddEdge( digraph, edge )( operation )
‣ DigraphAddEdge( digraph, src, ran )( operation )

Returns: A digraph.

If edge is a pair of vertices of digraph, or src and ran are vertices of digraph, then this operation returns a digraph constructed from digraph by adding a new edge with source edge[1] [src] and range edge[2] [ran].

If digraph belongs to IsMutableDigraph (3.1-2), then the edge is added directly to digraph. If digraph belongs to IsImmutableDigraph (3.1-3), then an immutable copy of digraph with the additional edge is returned.

gap> D1 := Digraph([[2], [3], []]);
<immutable digraph with 3 vertices, 2 edges>
gap> DigraphEdges(D1);
[ [ 1, 2 ], [ 2, 3 ] ]
gap> D2 := DigraphAddEdge(D1, [3, 1]);
<immutable digraph with 3 vertices, 3 edges>
gap> DigraphEdges(D2);
[ [ 1, 2 ], [ 2, 3 ], [ 3, 1 ] ]
gap> D3 := DigraphAddEdge(D2, [2, 3]);
<immutable multidigraph with 3 vertices, 4 edges>
gap> DigraphEdges(D3);
[ [ 1, 2 ], [ 2, 3 ], [ 2, 3 ], [ 3, 1 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 4);
<mutable digraph with 4 vertices, 4 edges>
gap> new := DigraphAddEdge(D, [1, 3]);
<mutable digraph with 4 vertices, 5 edges>
gap> DigraphEdges(new);
[ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 3, 4 ], [ 4, 1 ] ]
gap> D = new;
true

3.3-18 DigraphAddEdgeOrbit
‣ DigraphAddEdgeOrbit( digraph, edge )( operation )

Returns: A new digraph.

This operation returns a new digraph with the same vertices and edges as digraph and with additional edges consisting of the orbit of the edge edge under the action of the DigraphGroup (7.2-10) of digraph. If edge is already an edge in digraph, then digraph is returned unchanged. The argument digraph must be an immutable digraph.

An edge is simply a pair of vertices of digraph.

gap> gr1 := CayleyDigraph(DihedralGroup(8));
<immutable digraph with 8 vertices, 24 edges>
gap> gr2 := DigraphAddEdgeOrbit(gr1, [1, 8]);
<immutable digraph with 8 vertices, 32 edges>
gap> DigraphEdges(gr1);
[ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 1 ], [ 2, 5 ], [ 2, 6 ], 
  [ 3, 8 ], [ 3, 4 ], [ 3, 7 ], [ 4, 6 ], [ 4, 7 ], [ 4, 1 ], 
  [ 5, 7 ], [ 5, 6 ], [ 5, 8 ], [ 6, 4 ], [ 6, 8 ], [ 6, 2 ], 
  [ 7, 5 ], [ 7, 1 ], [ 7, 3 ], [ 8, 3 ], [ 8, 2 ], [ 8, 5 ] ]
gap> DigraphEdges(gr2);
[ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 8 ], [ 2, 1 ], [ 2, 5 ], 
  [ 2, 6 ], [ 2, 7 ], [ 3, 8 ], [ 3, 4 ], [ 3, 7 ], [ 3, 6 ], 
  [ 4, 6 ], [ 4, 7 ], [ 4, 1 ], [ 4, 5 ], [ 5, 7 ], [ 5, 6 ], 
  [ 5, 8 ], [ 5, 4 ], [ 6, 4 ], [ 6, 8 ], [ 6, 2 ], [ 6, 3 ], 
  [ 7, 5 ], [ 7, 1 ], [ 7, 3 ], [ 7, 2 ], [ 8, 3 ], [ 8, 2 ], 
  [ 8, 5 ], [ 8, 1 ] ]
gap> gr3 := DigraphRemoveEdgeOrbit(gr2, [1, 8]);
<immutable digraph with 8 vertices, 24 edges>
gap> gr3 = gr1;
true

3.3-19 DigraphAddEdges
‣ DigraphAddEdges( digraph, edges )( operation )

Returns: A digraph.

If edges is a (possibly empty) list of pairs of vertices of digraph, then this operation returns a digraph constructed from digraph by adding the edges specified by edges. More precisely, for every edge in edges, a new edge will be added with source edge[1] and range edges[2].

If an edge is included in edges with multiplicity k, then it will be added k times. If digraph belongs to IsMutableDigraph (3.1-2), then the edges are added directly to digraph. If digraph belongs to IsImmutableDigraph (3.1-3), then the result is returned as an immutable digraph.

gap> func := function(n)
>  local source, range, i;
>  source := [];
>  range  := [];
>  for i in [1 .. n - 2] do
>    Add(source, i);
>    Add(range, i + 1);
>  od;
>  return Digraph(n, source, range);
> end;;
gap> D := func(1024);
<immutable digraph with 1024 vertices, 1022 edges>
gap> new := DigraphAddEdges(D,
> [[1023, 1024], [1, 1024], [1023, 1024], [1024, 1]]);
<immutable multidigraph with 1024 vertices, 1026 edges>
gap> D = new;
false
gap> D2 := DigraphMutableCopy(func(1024));
<mutable digraph with 1024 vertices, 1022 edges>
gap> new := DigraphAddEdges(D2,
> [[1023, 1024], [1, 1024], [1023, 1024], [1024, 1]]);
<mutable multidigraph with 1024 vertices, 1026 edges>
gap> D2 = new;
true

3.3-20 DigraphRemoveVertex
‣ DigraphRemoveVertex( digraph, v )( operation )

Returns: A digraph.

If v is a vertex of digraph, then this operation returns a digraph constructed from digraph by removing vertex v, along with any edge whose source or range vertex is v.

If digraph has n vertices, then the vertices of the returned digraph are [1..n-1], but the original labels can be accessed via DigraphVertexLabels (5.1-12).

If digraph belongs to IsMutableDigraph (3.1-2), then the vertex is removed directly from digraph. If digraph belongs to IsImmutableDigraph (3.1-3), an immutable copy of digraph without the vertex is returned.

gap> D := Digraph(["a", "b", "c"],
>                  ["a", "a", "b", "c", "c"],
>                  ["b", "c", "a", "a", "c"]);
<immutable digraph with 3 vertices, 5 edges>
gap> DigraphVertexLabels(D);
[ "a", "b", "c" ]
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 3 ], [ 2, 1 ], [ 3, 1 ], [ 3, 3 ] ]
gap> new := DigraphRemoveVertex(D, 2);
<immutable digraph with 2 vertices, 3 edges>
gap> DigraphVertexLabels(new);
[ "a", "c" ]
gap> D := CycleDigraph(IsMutableDigraph, 5);
<mutable digraph with 5 vertices, 5 edges>
gap> new := DigraphRemoveVertex(D, 1);
<mutable digraph with 4 vertices, 3 edges>
gap> DigraphVertexLabels(D);
[ 2, 3, 4, 5 ]
gap> D = new;
true

3.3-21 DigraphRemoveVertices
‣ DigraphRemoveVertices( digraph, verts )( operation )

Returns: A digraph.

If verts is a (possibly empty) duplicate-free list of vertices of digraph, then this operation returns a digraph constructed from digraph by removing every vertex in verts, along with any edge whose source or range vertex is in verts.

If digraph has n vertices, then the vertices of the new digraph are [1 .. n-Length(verts)], but the original labels can be accessed via DigraphVertexLabels (5.1-12).

If digraph belongs to IsMutableDigraph (3.1-2), then the vertices are removed directly from digraph. If digraph belongs to IsImmutableDigraph (3.1-3), an immutable copy of digraph without the vertices is returned.

gap> D := Digraph([[3], [1, 3, 5], [1], [1, 2, 4], [2, 3, 5]]);
<immutable digraph with 5 vertices, 11 edges>
gap> SetDigraphVertexLabels(D, ["a", "b", "c", "d", "e"]);
gap> new := DigraphRemoveVertices(D, [2, 4]);
<immutable digraph with 3 vertices, 4 edges>
gap> DigraphVertexLabels(new);
[ "a", "c", "e" ]
gap> D := CycleDigraph(IsMutableDigraph, 5);
<mutable digraph with 5 vertices, 5 edges>
gap> new := DigraphRemoveVertices(D, [1, 3]);
<mutable digraph with 3 vertices, 1 edge>
gap> DigraphVertexLabels(D);
[ 2, 4, 5 ]
gap> D = new;
true

3.3-22 DigraphRemoveEdge
‣ DigraphRemoveEdge( digraph, edge )( operation )
‣ DigraphRemoveEdge( digraph, src, ran )( operation )

Returns: A digraph.

If digraph is a digraph with no multiple edges and edge is a pair of vertices of digraph, or src and ran are vertices of digraph, then this operation returns a digraph constructed from digraph by removing the edge specified by edge or [src, ran].

If digraph belongs to IsMutableDigraph (3.1-2), then the edge is removed directly from digraph. If digraph belongs to IsImmutableDigraph (3.1-3), an immutable copy of digraph without the edge is returned.

Note that if digraph belongs to IsImmutableDigraph (3.1-3), then a new copy of digraph will be returned even if edge or [src, ran] does not define an edge of digraph.

gap> D := CycleDigraph(250000);
<immutable cycle digraph with 250000 vertices>
gap> D := DigraphRemoveEdge(D, [250000, 1]);
<immutable digraph with 250000 vertices, 249999 edges>
gap> new := DigraphRemoveEdge(D, [25000, 2]);;
gap> new = D;
true
gap> IsIdenticalObj(new, D);
false
gap> D := DigraphMutableCopy(D);;
gap> new := DigraphRemoveEdge(D, 2500, 2);;
gap> IsIdenticalObj(new, D);
true

3.3-23 DigraphRemoveEdgeOrbit
‣ DigraphRemoveEdgeOrbit( digraph, edge )( operation )

Returns: A new digraph.

This operation returns a new digraph with the same vertices as digraph and with the orbit of the edge edge (under the action of the DigraphGroup (7.2-10) of digraph) removed. If edge is not an edge in digraph, then digraph is returned unchanged. The argument digraph must be an immutable digraph.

An edge is simply a pair of vertices of digraph.

gap> gr1 := CayleyDigraph(DihedralGroup(8));
<immutable digraph with 8 vertices, 24 edges>
gap> gr2 := DigraphAddEdgeOrbit(gr1, [1, 8]);
<immutable digraph with 8 vertices, 32 edges>
gap> DigraphEdges(gr1);
[ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 1 ], [ 2, 5 ], [ 2, 6 ], 
  [ 3, 8 ], [ 3, 4 ], [ 3, 7 ], [ 4, 6 ], [ 4, 7 ], [ 4, 1 ], 
  [ 5, 7 ], [ 5, 6 ], [ 5, 8 ], [ 6, 4 ], [ 6, 8 ], [ 6, 2 ], 
  [ 7, 5 ], [ 7, 1 ], [ 7, 3 ], [ 8, 3 ], [ 8, 2 ], [ 8, 5 ] ]
gap> DigraphEdges(gr2);
[ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 8 ], [ 2, 1 ], [ 2, 5 ], 
  [ 2, 6 ], [ 2, 7 ], [ 3, 8 ], [ 3, 4 ], [ 3, 7 ], [ 3, 6 ], 
  [ 4, 6 ], [ 4, 7 ], [ 4, 1 ], [ 4, 5 ], [ 5, 7 ], [ 5, 6 ], 
  [ 5, 8 ], [ 5, 4 ], [ 6, 4 ], [ 6, 8 ], [ 6, 2 ], [ 6, 3 ], 
  [ 7, 5 ], [ 7, 1 ], [ 7, 3 ], [ 7, 2 ], [ 8, 3 ], [ 8, 2 ], 
  [ 8, 5 ], [ 8, 1 ] ]
gap> gr3 := DigraphRemoveEdgeOrbit(gr2, [1, 8]);
<immutable digraph with 8 vertices, 24 edges>
gap> gr3 = gr1;
true

3.3-24 DigraphRemoveEdges
‣ DigraphRemoveEdges( digraph, edges )( operation )

Returns: A digraph.

If one of the following holds:

then this operation returns a digraph constructed from digraph by removing all of the edges specified by edges (see DigraphRemoveEdge (3.3-22)).

If digraph belongs to IsMutableDigraph (3.1-2), then the edge is removed directly from digraph. If digraph belongs to IsImmutableDigraph (3.1-3), the edge is removed from an immutable copy of digraph and this new digraph is returned.

Note that if edges is empty, then this operation will always return digraph rather than a copy. Also, if any element of edges is invalid (i.e. does not define an edge of digraph) then that element will simply be ignored.

gap> D := CycleDigraph(250000);
<immutable cycle digraph with 250000 vertices>
gap> D := DigraphRemoveEdges(D, [[250000, 1]]);
<immutable digraph with 250000 vertices, 249999 edges>
gap> D := DigraphMutableCopy(D);
<mutable digraph with 250000 vertices, 249999 edges>
gap> new := DigraphRemoveEdges(D, [[1, 2], [2, 3], [3, 100]]);
<mutable digraph with 250000 vertices, 249997 edges>
gap> new = D;
true

3.3-25 DigraphRemoveLoops
‣ DigraphRemoveLoops( digraph )( operation )
‣ DigraphRemoveLoopsAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph, then this operation returns a digraph constructed from digraph by removing every loop. A loop is an edge with equal source and range.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the loops are removed from the mutable digraph digraph in-place.

gap> D := Digraph([[1, 2, 4], [1, 4], [3, 4], [1, 4, 5], [1, 5]]);
<immutable digraph with 5 vertices, 12 edges>
gap> DigraphRemoveLoops(D);
<immutable digraph with 5 vertices, 8 edges>
gap> D := Digraph(IsMutableDigraph, [[1, 2], [1]]);
<mutable digraph with 2 vertices, 3 edges>
gap> DigraphRemoveLoops(D);
<mutable digraph with 2 vertices, 2 edges>
gap> D;
<mutable digraph with 2 vertices, 2 edges>

3.3-26 DigraphRemoveAllMultipleEdges
‣ DigraphRemoveAllMultipleEdges( digraph )( operation )
‣ DigraphRemoveAllMultipleEdgesAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a digraph, then this operation returns a digraph constructed from digraph by removing all multiple edges. The result is the largest subdigraph of digraph which does not contain multiple edges.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the multiple edges of the mutable digraph digraph are removed in-place.

gap> D1 := Digraph([[1, 2, 3, 2], [1, 1, 3], [2, 2, 2]]);
<immutable multidigraph with 3 vertices, 10 edges>
gap> D2 := DigraphRemoveAllMultipleEdges(D1);
<immutable digraph with 3 vertices, 6 edges>
gap> OutNeighbours(D2);
[ [ 1, 2, 3 ], [ 1, 3 ], [ 2 ] ]
gap> D := Digraph(IsMutableDigraph, [[2, 2], [1]]);
<mutable multidigraph with 2 vertices, 3 edges>
gap> DigraphRemoveAllMultipleEdges(D);
<mutable digraph with 2 vertices, 2 edges>
gap> D;
<mutable digraph with 2 vertices, 2 edges>

3.3-27 DigraphContractEdge
‣ DigraphContractEdge( digraph, edge )( operation )
‣ DigraphContractEdge( digraph, src, ran )( operation )

Returns: A digraph.

If edge is a pair of vertices of digraph, or src and ran are vertices of digraph, where ran <> src, then then this operation merges the two vertices of the edge given into one. Edges incident to src and ran will now be incident to v, the new vertex, with their direction preserved.

A new digraph constructed from digraph is returned, unless digraph belongs to IsMutableDigraph (3.1-2); in this case changes are made directly to digraph, which is then returned. The digraph must not belong to IsMultiDigraph (6.2-11).

The labels of any remaining edges will be preserved.

Assigned vertex labels for src and ran are combined into a list, and assigned to the new vertex v.

If an edge [src, src] or [ran, ran] exists, a singular edge [v, v] is created. If edge [ran, src] exists, this is also removed.

gap> D := DigraphByEdges([[1, 2], [2, 1]]);
<immutable digraph with 2 vertices, 2 edges>
gap> D2 := DigraphContractEdge(D, 1, 2);
<immutable empty digraph with 1 vertex>
gap> DigraphEdges(D2);
[  ]
gap> D := DigraphByEdges(IsMutableDigraph, [[1, 2], [2, 3], [3, 4]]);
<mutable digraph with 4 vertices, 3 edges>
gap> DigraphVertexLabels(D);;  # setting vertex labels
gap> DigraphContractEdge(D, [2, 3]);
<mutable digraph with 3 vertices, 2 edges>
gap> DigraphEdges(D);
[ [ 1, 3 ], [ 3, 2 ] ]
gap> DigraphVertexLabels(D);
[ 1, 4, [ 2, 3 ] ]

3.3-28 DigraphReverseEdges
‣ DigraphReverseEdges( digraph, edges )( operation )
‣ DigraphReverseEdge( digraph, edge )( operation )
‣ DigraphReverseEdge( digraph, src, ran )( operation )

Returns: A digraph.

If digraph is a digraph without multiple edges, and edges is a list of pairs of vertices of digraph (the entries of each pair corresponding to the source and the range of an edge, respectively), then DigraphReverseEdges returns a digraph constructed from digraph by reversing the orientation of every edge specified by edges. If only one edge is to be reversed, then DigraphReverseEdge can be used instead. In this case, the second argument should just be a single vertex-pair, or the second and third arguments should be the source and range of an edge respectively.

Note that even though digraph cannot have multiple edges, the output may have multiple edges.

If digraph belongs to IsMutableDigraph (3.1-2), then the edges are reversed in digraph. If digraph belongs to IsImmutableDigraph (3.1-3), an immutable copy of digraph with the specified edges reversed is returned.

gap> D := DigraphFromDiSparse6String(".Tg?i@s?t_e?_qEsC");
<immutable digraph with 21 vertices, 8 edges>
gap> DigraphEdges(D);
[ [ 1, 2 ], [ 1, 7 ], [ 1, 8 ], [ 5, 21 ], [ 7, 19 ], [ 9, 1 ], 
  [ 11, 2 ], [ 21, 1 ] ]
gap> new := DigraphReverseEdge(D, [7, 19]);
<immutable digraph with 21 vertices, 8 edges>
gap> DigraphEdges(new);
[ [ 1, 2 ], [ 1, 7 ], [ 1, 8 ], [ 5, 21 ], [ 9, 1 ], [ 11, 2 ], 
  [ 19, 7 ], [ 21, 1 ] ]
gap> D2 := DigraphMutableCopy(new);;
gap> new := DigraphReverseEdges(D2, [[19, 7]]);;
gap> D2 = new;
true
gap> D = new;
true

3.3-29 DigraphDisjointUnion
‣ DigraphDisjointUnion( D1, D2, ... )( function )
‣ DigraphDisjointUnion( list )( function )

Returns: A digraph.

In the first form, if D1, D2, etc. are digraphs, then DigraphDisjointUnion returns their disjoint union. In the second form, if list is a non-empty list of digraphs, then DigraphDisjointUnion returns the disjoint union of the digraphs contained in the list.

For a disjoint union of digraphs, the vertex set is the disjoint union of the vertex sets, and the edge list is the disjoint union of the edge lists.

More specifically, for a collection of digraphs D1, D2, ..., the disjoint union with have DigraphNrVertices(D1) + DigraphNrVertices(D2) + ... vertices. The edges of D1 will remain unchanged, whilst the edges of the ith digraph, D[i], will be changed so that they belong to the vertices of the disjoint union corresponding to D[i]. In particular, the edges of D[i] will have their source and range increased by DigraphNrVertices(D1) + ... + DigraphNrVertices(D[i-1]).

Note that previously set DigraphVertexLabels (5.1-12) will be lost.

If the first digraph D1 [list[1]] belongs to IsMutableDigraph (3.1-2), then D1 [list[1]] is modified in place to contain the appropriate vertices and edges. If digraph belongs to IsImmutableDigraph (3.1-3), a new immutable digraph containing the appropriate vertices and edges is returned.

gap> D1 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> OutNeighbours(D1);
[ [ 2 ], [ 3 ], [ 1 ] ]
gap> D2 := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> OutNeighbours(D2);
[ [ 2, 3 ], [ 1, 3 ], [ 1, 2 ] ]
gap> union := DigraphDisjointUnion(D1, D2);
<immutable digraph with 6 vertices, 9 edges>
gap> OutNeighbours(union);
[ [ 2 ], [ 3 ], [ 1 ], [ 5, 6 ], [ 4, 6 ], [ 4, 5 ] ]

3.3-30 DigraphEdgeUnion
‣ DigraphEdgeUnion( D1, D2, ... )( function )
‣ DigraphEdgeUnion( list )( function )

Returns: A digraph.

In the first form, if D1, D2, etc. are digraphs, then DigraphEdgeUnion returns their edge union. In the second form, if list is a non-empty list of digraphs, then DigraphEdgeUnion returns the edge union of the digraphs contained in the list.

The vertex set of the edge union of a collection of digraphs is the union of the vertex sets, whilst the edge list of the edge union is the concatenation of the edge lists. The number of vertices of the edge union is equal to the maximum number of vertices of one of the digraphs, whilst the number of edges of the edge union will equal the sum of the number of edges of each digraph.

Note that previously set DigraphVertexLabels (5.1-12) will be lost.

If the first digraph D1 [list[1]] belongs to IsMutableDigraph (3.1-2), then D1 [list[1]] is modified in place to contain the appropriate vertices and edges. If digraph belongs to IsImmutableDigraph (3.1-3), a new immutable digraph containing the appropriate vertices and edges is returned.

gap> D := CycleDigraph(10);
<immutable cycle digraph with 10 vertices>
gap> DigraphEdgeUnion(D, D);
<immutable multidigraph with 10 vertices, 20 edges>
gap> D1 := Digraph([[2], [1]]);
<immutable digraph with 2 vertices, 2 edges>
gap> D2 := Digraph([[2, 3], [2], [1]]);
<immutable digraph with 3 vertices, 4 edges>
gap> union := DigraphEdgeUnion(D1, D2);
<immutable multidigraph with 3 vertices, 6 edges>
gap> OutNeighbours(union);
[ [ 2, 2, 3 ], [ 1, 2 ], [ 1 ] ]
gap> union = DigraphByEdges(
> Concatenation(DigraphEdges(D1), DigraphEdges(D2)));
true

3.3-31 DigraphJoin
‣ DigraphJoin( D1, D2, ... )( function )
‣ DigraphJoin( list )( function )

Returns: A digraph.

In the first form, if D1, D2, etc. are digraphs, then DigraphJoin returns their join. In the second form, if list is a non-empty list of digraphs, then DigraphJoin returns the join of the digraphs contained in the list.

The join of a collection of digraphs D1, D2, ... is formed by first taking the DigraphDisjointUnion (3.3-29) of the collection. In the disjoint union, if \(i \neq j\) then there are no edges between vertices corresponding to digraphs D[i] and D[j] in the collection; the join is created by including all such edges.

For example, the join of two empty digraphs is a complete bipartite digraph.

Note that previously set DigraphVertexLabels (5.1-12) will be lost.

If the first digraph D1 [list[1]] belongs to IsMutableDigraph (3.1-2), then D1 [list[1]] is modified in place to contain the appropriate vertices and edges. If digraph belongs to IsImmutableDigraph (3.1-3), a new immutable digraph containing the appropriate vertices and edges is returned.

gap> D := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
gap> IsCompleteDigraph(DigraphJoin(D, D));
true
gap> D2 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> DigraphJoin(D, D2);
<immutable digraph with 6 vertices, 27 edges>

3.3-32 DigraphCartesianProduct
‣ DigraphCartesianProduct( gr1, gr2, ... )( function )
‣ DigraphCartesianProduct( list )( function )

Returns: A digraph.

In the first form, if gr1, gr2, etc. are digraphs, then DigraphCartesianProduct returns a digraph isomorphic to their Cartesian product.

In the second form, if list is a non-empty list of digraphs, then DigraphCartesianProduct returns a digraph isomorphic to the Cartesian product of the digraphs contained in the list.

Mathematically, the Cartesian product of two digraphs G, H is a digraph with vertex set Cartesian(DigraphVertices(G), DigraphVertices(H)) such that there is an edge from [u, u'] to [v, v'] iff u = v and there is an edge from u' to v' in H or u' = v' and there is an edge from u to v in G.

Due to technical reasons, the digraph D returned by DigraphCartesianProduct has vertex set [1 .. DigraphNrVertices(G)*DigraphNrVertices(H)] instead, and the exact method of encoding pairs of vertices into integers is implementation specific. The original vertex pair can be somewhat regained by using DigraphCartesianProductProjections (3.3-39). In addition, DigraphVertexLabels (5.1-12) are preserved: if vertex pair [u,u'] was encoded as i then the vertex label of i will be the pair of vertex labels of u and u' i.e. DigraphVertexLabel(D,i) = [DigraphVertexLabel(G,u), DigraphVertexLabel(H,u')].

As the Cartesian product is associative, the Cartesian product of a collection of digraphs gr1, gr2, ... is computed in the obvious fashion.

gap> gr := ChainDigraph(4);
<immutable chain digraph with 4 vertices>
gap> gr2 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> gr3 := DigraphCartesianProduct(gr, gr2);
<immutable digraph with 12 vertices, 21 edges>
gap> IsIsomorphicDigraph(gr3, 
> Digraph([[2, 5], [3, 6], [4, 7], [8], 
>          [6, 9], [7, 10], [8, 11], [12],
>          [10, 1], [11, 2], [12, 3], [4]]));
true

3.3-33 DigraphDirectProduct
‣ DigraphDirectProduct( gr1, gr2, ... )( function )
‣ DigraphDirectProduct( list )( function )

Returns: A digraph.

In the first form, if gr1, gr2, etc. are digraphs, then DigraphDirectProduct returns a digraph isomorphic to their direct product.

In the second form, if list is a non-empty list of digraphs, then DigraphDirectProduct returns a digraph isomorphic to the direct product of the digraphs contained in the list.

Mathematically, the direct product of two digraphs G, H is a digraph with vertex set Cartesian(DigraphVertices(G), DigraphVertices(H)) such that there is an edge from [u, u'] to [v, v'] iff there is an edge from u to v in G and an edge from u' to v' in H.

Due to technical reasons, the digraph D returned by DigraphDirectProduct has vertex set [1 .. DigraphNrVertices(G)*DigraphNrVertices(H)] instead, and the exact method of encoding pairs of vertices into integers is implementation specific. The original vertex pair can be somewhat regained by using DigraphDirectProductProjections (3.3-40). In addition DigraphVertexLabels (5.1-12) are preserved: if vertex pair [u,u'] was encoded as i then the vertex label of i will be the pair of vertex labels of u and u' i.e. DigraphVertexLabel(D,i) = [DigraphVertexLabel(G,u), DigraphVertexLabel(H,u')].

As the direct product is associative, the direct product of a collection of digraphs gr1, gr2, ... is computed in the obvious fashion.

gap> gr := ChainDigraph(4);
<immutable chain digraph with 4 vertices>
gap> gr2 := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> gr3 := DigraphDirectProduct(gr, gr2);
<immutable digraph with 12 vertices, 9 edges>
gap> IsIsomorphicDigraph(gr3, 
> Digraph([[6], [7], [8], [], 
>          [10], [11], [12], [],
>          [2], [3], [4], []]));
true

3.3-34 ConormalProduct
‣ ConormalProduct( D1, D2 )( operation )

Returns: A digraph.

If D1 and D2 are digraphs without multiple edges, then ConormalProduct calculates the co-normal product digraph (CNPD) of D1 and D2. CNPD has vertex set V1 x V2 where V1 is the vertex set of D1 and V2 is the vertex set of D2 (a vertex [a, b] has label (a - 1) * |V2| + b in the output). There is an edge from [a, b] to [c, d] when at least one of the following two conditions are satisfied:

gap> ConormalProduct(DigraphSymmetricClosure(CycleDigraph(7)),
> DigraphSymmetricClosure(CycleDigraph(4)));
<immutable digraph with 28 vertices, 504 edges>
gap> ConormalProduct(NullDigraph(0), CompleteDigraph(10));
<immutable empty digraph with 0 vertices>

3.3-35 HomomorphicProduct
‣ HomomorphicProduct( D1, D2 )( operation )

Returns: A digraph.

If D1 and D2 are digraphs without multiple edges, then HomomorphicProduct calculates the homomorphic product digraph (HPD) of D1 and D2. HPD has vertex set V1 x V2 where V1 is the vertex set of D1 and V2 is the vertex set of D2 (a vertex [a, b] has label (a - 1) * |V2| + b in the output). There is an edge from [a, b] to [c, d] when at least one of the following two conditions are satisfied:

gap> HomomorphicProduct(PetersenGraph(),
> DigraphSymmetricClosure(ChainDigraph(4)));
<immutable digraph with 40 vertices, 460 edges>
gap> D1 := Digraph([[2], [1, 3, 4], [2, 5], [2, 5], [3, 4]]);
<immutable digraph with 5 vertices, 10 edges>
gap> D2 := Digraph([[2], [1, 3], [2, 4], [3]]);
<immutable digraph with 4 vertices, 6 edges>
gap> HomomorphicProduct(D1, D2);
<immutable digraph with 20 vertices, 180 edges>

3.3-36 LexicographicProduct
‣ LexicographicProduct( D1, D2 )( operation )

Returns: A digraph.

If D1 and D2 are digraphs without multiple edges, then LexicographicProduct calculates the lexicographic product digraph (LPD) of D1 and D2. LPD has vertex set V1 x V2 where V1 is the vertex set of D1 and V2 is the vertex set of D2 (a vertex [a, b] has label (a - 1) * |V2| + b in the output). There is an edge from [a, b] to [c, d] when at least one of the following two conditions are satisfied:

gap> LexicographicProduct(DigraphSymmetricClosure(CycleDigraph(3)),
> DigraphSymmetricClosure(ChainDigraph(2)));
<immutable digraph with 6 vertices, 30 edges>
gap> OutNeighbours(last);
[ [ 2, 3, 4, 5, 6 ], [ 1, 3, 4, 5, 6 ], [ 1, 2, 4, 5, 6 ], 
  [ 1, 2, 3, 5, 6 ], [ 1, 2, 3, 4, 6 ], [ 1, 2, 3, 4, 5 ] ]
gap> LexicographicProduct(NullDigraph(0), CompleteDigraph(10));
<immutable empty digraph with 0 vertices>

3.3-37 ModularProduct
‣ ModularProduct( D1, D2 )( operation )

Returns: A digraph.

If D1 and D2 are digraphs without multiple edges, then ModularProduct calculates the modular product digraph (MPD) of D1 and D2. MPD has vertex set V1 x V2 where V1 is the vertex set of D1 and V2 is the vertex set of D2 (a vertex [a, b] has label (a - 1) * |V2| + b in the output). There is an edge from [a, b] to [c, d] precisely when the following two conditions are satisfied:

Notably, the complete (with loops) subdigraphs of MPD are precisely the partial isomorphisms from D1 to D2.

gap> ModularProduct(Digraph([[1], [1, 2]]), Digraph([[], [2]]));
<immutable digraph with 4 vertices, 4 edges>
gap> OutNeighbours(last);
[ [ 4 ], [ 2, 3 ], [  ], [ 4 ] ]
gap> ModularProduct(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
<immutable digraph with 50 vertices, 950 edges>
gap> ModularProduct(NullDigraph(0), CompleteDigraph(10));
<immutable empty digraph with 0 vertices>

3.3-38 StrongProduct
‣ StrongProduct( D1, D2 )( operation )

Returns: A digraph.

If D1 and D2 are digraphs without multiple edges, then StrongProduct calculates the strong product digraph (SPD) of D1 and D2. SPD has vertex set V1 x V2 where V1 is the vertex set of D1 and V2 is the vertex set of D2 (a vertex [a, b] has label (a - 1) * |V2| + b in the output). There is an edge from [a, b] to [c, d] when at least one of the following three conditions are satisfied:

The SPD of two paths of lengths m and n is also the king's graph for an m by n board.

gap> D1 := Digraph([[2], [1, 3, 4], [2, 5], [2, 5], [3, 4]]);
<immutable digraph with 5 vertices, 10 edges>
gap> D2 := Digraph([[2], [1, 3, 4], [2], [2]]);
<immutable digraph with 4 vertices, 6 edges>
gap> StrongProduct(D1, D2);
<immutable digraph with 20 vertices, 130 edges>
gap> StrongProduct(DigraphSymmetricClosure(ChainDigraph(3)),
> DigraphSymmetricClosure(ChainDigraph(4)));
<immutable digraph with 12 vertices, 58 edges>

3.3-39 DigraphCartesianProductProjections
‣ DigraphCartesianProductProjections( digraph )( attribute )

Returns: A list of transformations.

If digraph is a Cartesian product digraph, digraph = DigraphCartesianProduct(gr_1, gr_2, ... ), then DigraphCartesianProductProjections returns a list proj such that proj[i] is the projection onto the i-th coordinate of the product.

A projection is an idempotent endomorphism of digraph. If gr1, gr2, ... are all loopless digraphs, then the induced subdigraph of digraph on the image of proj[i] is isomorphic to gr_i.

Currently this attribute is only set upon creating an immutable digraph via DigraphCartesianProduct and there is no way of calculating it for other digraphs.

For more information see DigraphCartesianProduct (3.3-32)

gap> D := DigraphCartesianProduct(ChainDigraph(3), CycleDigraph(4),
> Digraph([[2], [2]]));;
gap> HasDigraphCartesianProductProjections(D);
true
gap> proj := DigraphCartesianProductProjections(D);; Length(proj);
3
gap> IsIdempotent(proj[2]);
true
gap> RankOfTransformation(proj[3]);
2
gap> S := ImageSetOfTransformation(proj[2]);;
gap> IsIsomorphicDigraph(CycleDigraph(4), InducedSubdigraph(D, S));
true

3.3-40 DigraphDirectProductProjections
‣ DigraphDirectProductProjections( digraph )( attribute )

Returns: A list of transformations.

If digraph is a direct product digraph, digraph = DigraphDirectProduct(gr_1, gr_2, ... ), then DigraphDirectProductProjections returns a list proj such that proj[i] is the projection onto the i-th coordinate of the product.

A projection is an idempotent endomorphism of digraph. If gr1, gr2, ... are all loopless digraphs, then the image of digraph under proj[i] is isomorphic to gr_i.

Currently this attribute is only set upon creating an immutable digraph via DigraphDirectProduct and there is no way of calculating it for other digraphs.

For more information, see DigraphDirectProduct (3.3-33)

gap> D := DigraphDirectProduct(ChainDigraph(3), CycleDigraph(4),
> Digraph([[2], [2]]));;
gap> HasDigraphDirectProductProjections(D);
true
gap> proj := DigraphDirectProductProjections(D);; Length(proj);
3
gap> IsIdempotent(proj[2]);
true
gap> RankOfTransformation(proj[3]);
2
gap> P := DigraphRemoveAllMultipleEdges(
> ReducedDigraph(OnDigraphs(D, proj[2])));; 
gap> IsIsomorphicDigraph(CycleDigraph(4), P);
true

3.3-41 LineDigraph
‣ LineDigraph( digraph )( operation )
‣ EdgeDigraph( digraph )( operation )

Returns: A digraph.

Given a digraph digraph, the operation returns the digraph obtained by associating a vertex with each edge of digraph, and creating an edge from a vertex v to a vertex u if and only if the terminal vertex of the edge associated with v is the start vertex of the edge associated with u.

Note that the returned digraph is always a new immutable digraph, and the argument digraph is never modified.

gap> LineDigraph(CompleteDigraph(3));
<immutable digraph with 6 vertices, 12 edges>
gap> LineDigraph(ChainDigraph(3));
<immutable digraph with 2 vertices, 1 edge>

3.3-42 LineUndirectedDigraph
‣ LineUndirectedDigraph( digraph )( operation )
‣ EdgeUndirectedDigraph( digraph )( operation )

Returns: A digraph.

Given a symmetric digraph digraph, the operation returns the symmetric digraph obtained by associating a vertex with each edge of digraph, ignoring directions and multiplicities, and adding an edge between two vertices if and only if the corresponding edges have a vertex in common.

Note that the returned digraph is always a new immutable digraph, and the argument digraph is never modified.

gap> LineUndirectedDigraph(CompleteDigraph(3));
<immutable digraph with 3 vertices, 6 edges>
gap> LineUndirectedDigraph(DigraphSymmetricClosure(ChainDigraph(3)));
<immutable digraph with 2 vertices, 2 edges>

3.3-43 DoubleDigraph
‣ DoubleDigraph( digraph )( operation )

Returns: A digraph.

Let digraph be a digraph with vertex set V. This function returns the double digraph of digraph. The vertex set of the double digraph is the original vertex set together with a duplicate. The edges are [u_1, v_2] and [u_2, v_1] if and only if [u, v] is an edge in digraph, together with the original edges and their duplicates.

If digraph is mutable, then digraph is modified in-place. If digraph is immutable, then a new immutable digraph constructed as described above is returned.

gap> gamma := Digraph([[2], [3], [1]]);
<immutable digraph with 3 vertices, 3 edges>
gap> DoubleDigraph(gamma);
<immutable digraph with 6 vertices, 12 edges>

3.3-44 BipartiteDoubleDigraph
‣ BipartiteDoubleDigraph( digraph )( operation )

Returns: A digraph.

Let digraph be a digraph with vertex set V. This function returns the bipartite double digraph of digraph. The vertex set of the double digraph is the original vertex set together with a duplicate. The edges are [u_1, v_2] and [u_2, v_1] if and only if [u, v] is an edge in digraph. The resulting graph is bipartite, since the original edges are not included in the resulting digraph.

If digraph is mutable, then digraph is modified in-place. If digraph is immutable, then a new immutable digraph constructed as described above is returned.

gap> gamma := Digraph([[2], [3], [1]]);
<immutable digraph with 3 vertices, 3 edges>
gap> BipartiteDoubleDigraph(gamma);
<immutable digraph with 6 vertices, 6 edges>

3.3-45 DigraphAddAllLoops
‣ DigraphAddAllLoops( digraph )( operation )
‣ DigraphAddAllLoopsAttr( digraph )( attribute )

Returns: A digraph.

For a digraph digraph this operation returns a new digraph constructed from digraph, such that a loop is added for every vertex which did not have a loop in digraph.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the loops are added to the loopless vertices of the mutable digraph digraph in-place.

gap> D := EmptyDigraph(13);
<immutable empty digraph with 13 vertices>
gap> D := DigraphAddAllLoops(D);
<immutable reflexive digraph with 13 vertices, 13 edges>
gap> OutNeighbours(D);
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ], [ 7 ], [ 8 ], [ 9 ], 
  [ 10 ], [ 11 ], [ 12 ], [ 13 ] ]
gap> D := Digraph([[1, 2, 3], [1, 3], [1]]);
<immutable digraph with 3 vertices, 6 edges>
gap> D := DigraphAddAllLoops(D);
<immutable reflexive digraph with 3 vertices, 8 edges>
gap> OutNeighbours(D);
[ [ 1, 2, 3 ], [ 1, 3, 2 ], [ 1, 3 ] ]
gap> D := CycleDigraph(IsMutableDigraph, 3);
<mutable digraph with 3 vertices, 3 edges>
gap> DigraphAddAllLoops(D);
<mutable digraph with 3 vertices, 6 edges>
gap> D;
<mutable digraph with 3 vertices, 6 edges>

3.3-46 DistanceDigraph
‣ DistanceDigraph( digraph, i )( operation )
‣ DistanceDigraph( digraph, list )( operation )

Returns: A digraph.

The first argument is a digraph, the second argument is a non-negative integer or a list of positive integers. This operation returns a digraph on the same set of vertices as digraph, with two vertices being adjacent if and only if the distance between them in digraph equals i or is a number in list. See DigraphShortestDistance (5.4-2).

If digraph is mutable, then digraph is modified in-place. If digraph is immutable, then a new immutable digraph constructed as described above is returned.

gap> digraph := DigraphFromSparse6String(
> ":]n?AL`BC_DEbEF`GIaGHdIJeGKcKL_@McDHfILaBJfHMjKM");
<immutable symmetric digraph with 30 vertices, 90 edges>
gap> DistanceDigraph(digraph, 1);
<immutable digraph with 30 vertices, 90 edges>
gap> DistanceDigraph(digraph, [1, 2]);
<immutable digraph with 30 vertices, 270 edges>

3.3-47 DigraphClosure
‣ DigraphClosure( digraph, k )( operation )

Returns: A digraph.

Given a symmetric loopless digraph with no multiple edges digraph, the k-closure of digraph is defined to be the unique smallest symmetric loopless digraph C with no multiple edges on the vertices of digraph that contains all the edges of digraph and satisfies the property that the sum of the degrees of every two non-adjacenct vertices in C is less than k. See IsSymmetricDigraph (6.2-14), DigraphHasLoops (6.2-1), IsMultiDigraph (6.2-11), and OutDegreeOfVertex (5.2-10).

The operation DigraphClosure returns the k-closure of digraph.

gap> D := CompleteDigraph(6);
<immutable complete digraph with 6 vertices>
gap> D := DigraphRemoveEdges(D, [[1, 2], [2, 1]]);
<immutable digraph with 6 vertices, 28 edges>
gap> closure := DigraphClosure(D, 6);
<immutable digraph with 6 vertices, 30 edges>
gap> IsCompleteDigraph(closure);
true

3.3-48 DigraphMycielskian
‣ DigraphMycielskian( digraph )( operation )
‣ DigraphMycielskianAttr( digraph )( attribute )

Returns: A digraph.

If digraph is a symmetric digraph, then DigraphMycielskian returns the Mycielskian of digraph.

The Mycielskian of a symmetric digraph is a larger symmetric digraph constructed from it, which has a larger chromatic number. For further information, see https://en.wikipedia.org/wiki/Mycielskian.

If digraph is immutable, then a new immutable digraph is returned. Otherwise, the mutable digraph digraph is changed in-place into its Mycielskian.

gap> D := CycleDigraph(2);
<immutable cycle digraph with 2 vertices>
gap> ChromaticNumber(D);
2
gap> D := DigraphMycielskian(D);
<immutable digraph with 5 vertices, 10 edges>
gap> ChromaticNumber(D);
3
gap> D := DigraphMycielskian(D);
<immutable digraph with 11 vertices, 40 edges>
gap> ChromaticNumber(D);
4
gap> D := CompleteBipartiteDigraph(IsMutable, 2, 3);
<mutable digraph with 5 vertices, 12 edges>
gap> DigraphMycielskian(D);
<mutable digraph with 11 vertices, 46 edges>
gap> D;
<mutable digraph with 11 vertices, 46 edges>

3.4 Random digraphs

3.4-1 RandomDigraph
‣ RandomDigraph( [filt, ]n[, p] )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

The other implemented filters are as follows: IsConnectedDigraph (6.6-3), IsSymmetricDigraph (6.2-14), IsAcyclicDigraph (6.6-1), IsEulerianDigraph (6.6-10), IsHamiltonianDigraph (6.6-11).

For IsConnectedDigraph (6.6-3), a random tree is first created independent of the value of p, guaranteeing connectivity (with \(\textit{n}-1\) edges), and then edges are added between the remaining pairs of vertices with probability approximately p.

For IsHamiltonianDigraph (6.6-11), a random Hamiltonian cycle is first created independent of the value of p (with n edges), and then edges are added between the remaining pairs of vertices with probability approximately p.

For IsEulerianDigraph (6.6-10), a random Eulerian cycle is created where p influences how long the cycle will be. The cycle grows by randomly considering edges that extend the cycle, and adding an edge with probability approximately p. The cycle stops when we get back to the start vertex and have no more edges left to consider from it that extend the cycle further (any possible edge from the start vertex has either been added to the cycle, or rejected, leaving no more edges to consider). Thus \(\textit{p} = 1\) does not necessarily guarantee a complete digraph. Instead, it guarantees that all edges considered up to the point where the cycle stops, are added.

For IsAcyclicDigraph (6.6-1) and IsSymmetricDigraph (6.2-14), edges are added between any pairs of vertices with probability approximately p.

If n is a positive integer, then this function returns a random digraph with n vertices and without multiple edges. The result may or may not have loops. If using IsAcyclicDigraph (6.6-1), the resulting graph will not have any loops by definition.

If the optional second argument p is a float with value \(0 \leq \) p \( \leq 1\), then an edge will exist between each pair of vertices with probability approximately p. If p is not specified, then a random probability will be assumed (chosen with uniform probability).

gap> RandomDigraph(1000);
<immutable digraph with 1000 vertices, 364444 edges>
gap> RandomDigraph(10000, 0.023);
<immutable digraph with 10000 vertices, 2300438 edges>
gap> RandomDigraph(IsMutableDigraph, 1000, 1 / 2);
<mutable digraph with 1000 vertices, 499739 edges>
gap> RandomDigraph(IsConnectedDigraph, 1000, 0.75);
<immutable digraph with 1000 vertices, 750265 edges>
gap> RandomDigraph(IsSymmetricDigraph, 1000);
<immutable digraph with 1000 vertices, 329690 edges>
gap> RandomDigraph(IsAcyclicDigraph, 1000, 0.25);
<immutable digraph with 1000 vertices, 125070 edges>
gap> RandomDigraph(IsHamiltonianDigraph, 1000, 0.5);
<immutable digraph with 1000 vertices, 500327 edges>
gap> RandomDigraph(IsEulerianDigraph, 1000, 0.5);
<immutable digraph with 1000 vertices, 433869 edges>

3.4-2 RandomMultiDigraph
‣ RandomMultiDigraph( n[, m] )( operation )

Returns: A digraph.

If n is a positive integer, then this function returns a random digraph with n vertices. If the optional second argument m is a positive integer, then the digraph will have m edges. If m is not specified, then the number of edges will be chosen randomly (with uniform probability) from the range [1 .. \({n \choose 2}\)].

The method used by this function chooses each edge from the set of all possible edges with uniform probability. No effort is made to avoid creating multiple edges, so it is possible (but not guaranteed) that the result will have multiple edges. The result may or may not have loops.

gap> RandomMultiDigraph(1000);
<immutable multidigraph with 1000 vertices, 216659 edges>
gap> RandomMultiDigraph(1000, 950);
<immutable multidigraph with 1000 vertices, 950 edges>

3.4-3 RandomTournament
‣ RandomTournament( [filt, ]n )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

If n is a non-negative integer, this function returns a random tournament with n vertices. See IsTournament (6.2-15).

gap> RandomTournament(10);
<immutable tournament with 10 vertices>
gap> RandomTournament(IsMutableDigraph, 10);
<mutable digraph with 1000 vertices, 500601 edges>

3.4-4 RandomLattice
‣ RandomLattice( n )( operation )

Returns: A digraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

If n is a positive integer, this function return a random lattice with m vertices, where it is guaranteed that m is between n and 2 * n. See IsLatticeDigraph (6.4-3).

gap> RandomLattice(10);
<immutable lattice digraph with 10 vertices, 39 edges>
gap> RandomLattice(IsMutableDigraph, 10);
<mutable digraph with 12 vertices, 52 edges>

3.5 Standard examples

3.5-1 AndrasfaiGraph
‣ AndrasfaiGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer greater than 0, then this operation returns the nth Andrasfai graph. The Andrasfai graph is a circulant graph with 3n - 1 vertices. The indices of the Andrasfai graph are given by the numbers between 1 and 3n - 1 that are congruent to 1 mod 3 (that is, for each index \(j\), vertex \(i\) is adjacent to the \(i + j\)th and \(i - j\) vertices). The graph has 6(3n - 1) edges. The graph is triangle free.

As a circulant graph, the Andrasfai graph is biconnected, cyclic, Hamiltonian, regular, and vertex transitive.

See https://mathworld.wolfram.com/AndrasfaiGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := AndrasfaiGraph(4);
<immutable Hamiltonian biconnected vertex-transitive symmetric digraph\
 with 11 vertices, 44 edges>
gap> IsBiconnectedDigraph(D);
true
gap> IsIsomorphicDigraph(D, CirculantGraph(11, [1, 4, 7, 10]));
true

3.5-2 BananaTree
‣ BananaTree( [filt, ]n, k )( operation )

Returns: A digraph

If n and k are positive integers with k greater than \(1\), then this operation returns the banana tree with parameters n and k, as defined below.

From https://mathworld.wolfram.com/BananaTree.html:

"An (n,k)-banana tree, as defined by Chen et al. (1997), is a graph obtained by connecting one leaf of each of n copies of an k-star graph with a single root vertex that is distinct from all the stars."

Specifically, in the resulting digraph, vertex 1 is the 'root', and for each m in [1 .. k], the mth star is on the vertices [((m - 1) * n) + 2 .. (m * n) + 1], with the first of these being the 'centre' of the star, and the second being the 'leaf' adjacent 1.

See also StarGraph (3.5-43) and IsUndirectedTree (6.6-9).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := BananaTree(2, 4);
<immutable undirected tree digraph with 9 vertices>
gap> D := BananaTree(3, 3);
<immutable undirected tree digraph with 10 vertices>
gap> D := BananaTree(5, 2);
<immutable undirected tree digraph with 11 vertices>
gap> D := BananaTree(3, 4);
<immutable undirected tree digraph with 13 vertices>

3.5-3 BinaryTree
‣ BinaryTree( [filt, ]m )( operation )

Returns: A digraph.

This function returns a binary tree of depth m with 2 ^ m - 1 vertices. All edges are directed towards the root of the tree, which is vertex 1.

Note that BinaryTree(m) is the induced subdigraph of BinaryTree(m+1) on the vertices [1..2^(m-1)].

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> BinaryTree(1);
<immutable empty digraph with 1 vertex>
gap> BinaryTree(8);
<immutable digraph with 255 vertices, 254 edges>
gap> BinaryTree(IsMutableDigraph, 8);
<mutable digraph with 255 vertices, 254 edges>

3.5-4 BinomialTreeGraph
‣ BinomialTreeGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer then this operation returns the nth binomial tree graph. The binomial tree graph has n vertices and n-1 undirected edges. The vertices of the binomial tree graph are the numbers from 1 to n in binary representation, with a vertex v having as a direct parent the vertex with binary representation the same as v but with the lowest 1-bit cleared. For example, the vertex \(011\) has parent \(010\), and the vertex \(010\) has parent \(000\).

The binomial tree graph is an undirected tree, and is symmetric as a digraph.

See https://metacpan.org/pod/Graph::Maker::BinomialTree for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := BinomialTreeGraph(9);
<immutable undirected tree digraph with 9 vertices>

3.5-5 BishopsGraph
‣ BishopsGraph( [filt, ][color, ]m, n )( operation )
‣ BishopGraph( [filt, ][color, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the bishop's graph of an m by n chessboard, as a symmetric digraph.

A bishop's graph represents all possible moves of the bishop chess piece across a chessboard. An m by n chessboard is a grid of m columns ("files") and n rows ("ranks") that intersect in squares. Orthogonally adjacent squares are alternately colored light and dark, with the square in the first rank and file being dark.

The m * n vertices of the bishop's graph can be placed onto the m * n squares of an m by n chessboard, such that two vertices are adjacent in the digraph if and only if a bishop can move between the corresponding squares in a single turn. A legal bishop's move is defined as any move which moves the bishop piece to a diagonally adjacent square or to a square which can be reached through a series of diagonally adjacent squares, with all of these small moves being in the same direction.

The chosen correspondence between vertices and chess squares is given by DigraphVertexLabels (5.1-12). In more detail, the vertices of the digraph are labelled by elements of the Cartesian product [1..m] x [1..n], where the first entry indexes the column (file) of the square in the chessboard, and the second entry indexes the row (rank) of the square. (Note that the files are traditionally indexed by the lowercase letters of the alphabet). The vertices are sorted in ascending order, first by row (second component) and then column (first component). If the optional second argument color is present, then this should be one of the strings "dark", "light", or "both". The default is "both". A bishop on a light square can only move to light squares, and a bishop on a dark square can only move to dark squares. This optional argument controls which bishops are represented in the resulting digraph. If color is "both", then the resulting digraph will show all the vertices of an m by n chessboard, and will be disconnected (unless m = n = 1). Otherwise, BishopsGraph returns the induced subdigraph of this on the vertices that correspond to either the dark squares or the light squares, according to the value of color.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> BishopsGraph(8, 8);
<immutable symmetric digraph with 64 vertices, 560 edges>
gap> D := BishopsGraph("dark", 3, 5);
<immutable connected symmetric digraph with 8 vertices, 24 edges>
gap> IsConnectedDigraph(D);       
true
gap> BishopsGraph("light", 4, 4);
<immutable connected symmetric digraph with 8 vertices, 28 edges>
gap> D := BishopsGraph("both", 1, 5);
<immutable empty digraph with 5 vertices>

3.5-6 BondyGraph
‣ BondyGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a non-negative integer then this operation returns the nth Bondy graph. The Bondy graphs are a family of hypohamiltonian graphs: a graph which is not Hamiltonian itself but the removal of any vertex produces a Hamiltonian graph. The Bondy graphs are the (3(2n + 1) + 2, 2)-th Generalised Petersen graphs, and have 12n + 10 vertices and 15 + 18n undirected edges.

See https://mathworld.wolfram.com/HypohamiltonianGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := BondyGraph(1);
<immutable symmetric digraph with 22 vertices, 66 edges>
gap> IsHamiltonianDigraph(D);
false
gap> G := List([1 .. 22], x -> DigraphRemoveVertex(D, x));;
gap> ForAll(G, IsHamiltonianDigraph);
true

3.5-7 BookGraph
‣ BookGraph( [filt, ]m )( operation )

Returns: A digraph.

The book graph is the Cartesian product of a complete digraph with two vertices (as the "book spine") and the \(\textit{m}+1\) star graph (as the "pages"). For more details on the book graph please refer to https://mathworld.wolfram.com/BookGraph.html.

See DigraphCartesianProduct (3.3-32), CompleteDigraph (3.5-11), and StarGraph (3.5-43).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> BookGraph(1);
<immutable bipartite symmetric digraph with bicomponent sizes 2 and 2>
gap> BookGraph(2);
<immutable bipartite symmetric digraph with bicomponent sizes 3 and 3>
gap> BookGraph(IsMutable, 12);
<mutable digraph with 26 vertices, 74 edges>
gap> BookGraph(7);
<immutable bipartite symmetric digraph with bicomponent sizes 8 and 8>
gap> IsSymmetricDigraph(BookGraph(24));
true
gap> IsBipartiteDigraph(BookGraph(24));
true

3.5-8 StackedBookGraph
‣ StackedBookGraph( [filt, ]m, n )( operation )

Returns: A digraph.

The stacked book graph is the Cartesian product of the symmetric closure of the chain digraph with n vertices (as the "book spine") and the \(\textit{m}+1\) star graph (as the "pages"). For more details on the stacked book graph please refer to https://mathworld.wolfram.com/StackedBookGraph.html.

See DigraphCartesianProduct (3.3-32), DigraphSymmetricClosure (3.3-12), ChainDigraph (3.5-9), and StarGraph (3.5-43).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> StackedBookGraph(1, 1);
<immutable bipartite symmetric digraph with bicomponent sizes 1 and 1>
gap> StackedBookGraph(1, 2);
<immutable bipartite symmetric digraph with bicomponent sizes 2 and 2>
gap> StackedBookGraph(3, 4);
<immutable bipartite symmetric digraph with bicomponent sizes 8 and 8>
gap> StackedBookGraph(IsMutable, 12, 5);
<mutable digraph with 65 vertices, 224 edges>
gap> StackedBookGraph(5, 5);
<immutable bipartite symmetric digraph with bicomponent sizes 13 and 1\
7>
gap> IsSymmetricDigraph(StackedBookGraph(24, 8));
true
gap> IsBipartiteDigraph(StackedBookGraph(24, 8));
true

3.5-9 ChainDigraph
‣ ChainDigraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer, this function returns a chain with n vertices and n - 1 edges. Specifically, for each vertex i (with i < n), there is a directed edge with source i and range i + 1.

The DigraphReflexiveTransitiveClosure (3.3-13) of a chain represents a total order.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> ChainDigraph(42);
<immutable chain digraph with 42 vertices>
gap> ChainDigraph(IsMutableDigraph, 10);
<mutable digraph with 10 vertices, 9 edges>

3.5-10 CirculantGraph
‣ CirculantGraph( [filt, ]n, par )( operation )

Returns: A digraph.

If n is an integer greater than 1, and par is a list of integers that are contained in [1..n] then this operation returns a circulant graph. The circulant graph is a graph on n vertices, where for each element \(j\) of par, the \(i\)th vertex is adjacent to the \((i + j)\)th and \((i - j)\)th vertices.

If par is \([1]\), then the graph is the nth cyclic graph. If par is [1,2,...,Int(n/2)], then the graph is the complete graph on n vertices. If n is at least 4 and par is [1,n] then the graph is the nth Mobius ladder graph.

A circulant graph is biconnected, cyclic, Hamiltonian, regular, and vertex transitive.

See https://mathworld.wolfram.com/CirculantGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := CirculantGraph(6, [1, 2, 3]);
<immutable Hamiltonian biconnected vertex-transitive symmetric digraph\
 with 6 vertices, 30 edges>
gap> IsIsomorphicDigraph(D, CompleteDigraph(6));
true

3.5-11 CompleteDigraph
‣ CompleteDigraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a non-negative integer, this function returns the complete digraph with n vertices. See IsCompleteDigraph (6.2-5).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> CompleteDigraph(20);
<immutable complete digraph with 20 vertices>
gap> CompleteDigraph(IsMutableDigraph, 10);
<mutable digraph with 10 vertices, 90 edges>

3.5-12 CompleteBipartiteDigraph
‣ CompleteBipartiteDigraph( [filt, ]m, n )( operation )

Returns: A digraph.

A complete bipartite digraph is a digraph whose vertices can be partitioned into two non-empty vertex sets, such there exists a unique edge with source i and range j if and only if i and j lie in different vertex sets.

If m and n are positive integers, this function returns the complete bipartite digraph with vertex sets of sizes m (containing the vertices [1 .. m]) and n (containing the vertices [m + 1 .. m + n]).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> CompleteBipartiteDigraph(2, 3);
<immutable complete bipartite digraph with bicomponent sizes 2 and 3>
gap> CompleteBipartiteDigraph(IsMutableDigraph, 3, 2);
<mutable digraph with 5 vertices, 12 edges>

3.5-13 CompleteMultipartiteDigraph
‣ CompleteMultipartiteDigraph( [filt, ]orders )( operation )

Returns: A digraph.

For a list orders of n positive integers, this function returns the digraph containing n independent sets of vertices of orders [l[1] .. l[n]]. Moreover, each vertex is adjacent to every other not contained in the same independent set.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> CompleteMultipartiteDigraph([5, 4, 2]);
<immutable complete multipartite digraph with 11 vertices, 76 edges>
gap> CompleteMultipartiteDigraph(IsMutableDigraph, [5, 4, 2]);
<mutable digraph with 11 vertices, 76 edges>

3.5-14 CycleDigraph
‣ CycleDigraph( [filt, ]n )( operation )
‣ DigraphCycle( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer, then these functions return a cycle digraph with n vertices and n edges. Specifically, for each vertex i (with i < n), there is a directed edge with source i and range i + 1. In addition, there is an edge with source n and range 1.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> CycleDigraph(1);
<immutable digraph with 1 vertex, 1 edge>
gap> CycleDigraph(123);
<immutable cycle digraph with 123 vertices>
gap> CycleDigraph(IsMutableDigraph, 10);
<mutable digraph with 10 vertices, 10 edges>
gap> DigraphCycle(4) = CycleDigraph(4);
true

3.5-15 CycleGraph
‣ CycleGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer greater than 2 then this operation returns the nth cycle graph, consisting of the cycle on n vertices. The cycle graph, unlike the cycle digraph, is symmetric. The cycle graph has n vertices and n undirected edges. The cycle graph is simple so the non-simple graphs with a single vertex and single loop and with two vertices and two edges between them are excluded.

See https://mathworld.wolfram.com/CycleGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := CycleGraph(7);
<immutable symmetric digraph with 7 vertices, 14 edges>

3.5-16 EmptyDigraph
‣ EmptyDigraph( [filt, ]n )( operation )
‣ NullDigraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a non-negative integer, this function returns the empty or null digraph with n vertices. An empty digraph is one with no edges.

NullDigraph is a synonym for EmptyDigraph.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> EmptyDigraph(20);
<immutable empty digraph with 20 vertices>
gap> NullDigraph(10);
<immutable empty digraph with 10 vertices>
gap> EmptyDigraph(IsMutableDigraph, 10);
<mutable empty digraph with 10 vertices>

3.5-17 GearGraph
‣ GearGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 3, then this operation returns the gear graph with 2n + 1 vertices and 3n undirected edges. The nth gear graph is the 2th cycle graph with one additional central vertex, to which every other vertex of the cycle is connected. The gear graph is a symmetric digraph. A gear graph is a Matchstick graph, that is it is simple with a planar graph embedding, and is a unit-distance graph (that is, it can be embedded into the Euclidean plane with vertices being distinct points and edges having length 1).

See https://mathworld.wolfram.com/GearGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := GearGraph(4);
<immutable symmetric digraph with 9 vertices, 24 edges>
gap> ChromaticNumber(D);
2
gap> IsVertexTransitive(D);
false

3.5-18 HaarGraph
‣ HaarGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer then this operation returns the Haar graph \(H(\textit{n})\).

The number of vertices in the Haar graph \(H(\textit{n})\) is equal to twice \(m\), where \(m\) is the number of digits required to represent n in binary. These vertices are arranged into bicomponents [1..m] and [m+1..2*m]. Vertices \(i\) and \(j\) in different bicomponents are adjacent by a symmetric pair of edges if and only if the binary representation of n has a 1 in position (\(j-i\) modulo \(m\)) + 1 from the left.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> HaarGraph(3);
<immutable bipartite vertex-transitive symmetric digraph with bicompon\
ent sizes 2 and 2>
gap> D := HaarGraph(16);
<immutable bipartite vertex-transitive symmetric digraph with bicompon\
ent sizes 5 and 5>

3.5-19 HalvedCubeGraph
‣ HalvedCubeGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 1, then this operation returns the nth halved cube graph, the graph of the n- demihypercube. The vertices of the graph are those of the nth- hypercube, with two vertices adjacent if and only if they are at distance 1 or 2 from each other. Equivalent constructions are as the second graph power of the n-1th hypercube graph, or as with vertices labelled as the binary numbers where two vertices are adjacent if they differ in a single bit, or with vertices labelled with the subset of binary numbers with even Hamming weight, with edges connecting vertices with Hamming distance exactly 2. The Halved Cube graph is distance regular and contains a Hamiltonian cycle.

See https://mathworld.wolfram.com/HalvedCubeGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := HalvedCubeGraph(3);
<immutable Hamiltonian connected symmetric digraph with 4 vertices, 12\
 edges>
gap> IsDistanceRegularDigraph(D);
true
gap> IsHamiltonianDigraph(D);
true

3.5-20 HanoiGraph
‣ HanoiGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is positive integer then this operation returns the nth Hanoi graph. The Hanoi graph's vertices represent the possible states of the 'Tower of Hanoi' puzzle on three 'towers', while its edges represent possible moves. The Hanoi graph has 3^n vertices, and 3 * (3^n - 1) / 2 undirected edges.

The Hanoi graph is Hamiltonian. The graph superficially resembles the Sierpinski triangle. The graph is also a 'penny graph' - a graph whose vertices can be considered to be non-overlapping unit circles on a flat surface, with two vertices adjacent only if the unit circles touch at a single point. Thus the Hanoi graph is planar.

See https://mathworld.wolfram.com/HanoiGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := HanoiGraph(5);
<immutable Hamiltonian connected symmetric digraph with 243 vertices, \
726 edges>
gap> IsPlanarDigraph(D);
true

3.5-21 HelmGraph
‣ HelmGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 3, then this operation returns the nth helm graph. The helm graph is the n-1th wheel graph with, for each external vertex of the 'wheel', adjoining a new vertex incident only to the first vertex. That is, the graph looks similar to a ship's helm.

See https://mathworld.wolfram.com/WheelGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := HelmGraph(4);
<immutable symmetric digraph with 9 vertices, 24 edges>

3.5-22 HypercubeGraph
‣ HypercubeGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a non-negative integer, then this operation returns the nth hypercube graph. The graph has 2^n vertices and 2^(n-1)n edges. It is formed from the vertices and edges of the n-dimensional hypercube. Alternatively, the graph can be constructed by labelling each vertex with the binary numbers, with two vertices adjacent if they have Hamming distance exactly one. The hypercube graphs are Hamiltonian, distance-transitive and therefore distance-regular, and bipartite.

See https://mathworld.wolfram.com/HypercubeGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := HypercubeGraph(5);
<immutable Hamiltonian connected bipartite symmetric digraph with bico\
mponent sizes 16 and 16>

3.5-23 JohnsonDigraph
‣ JohnsonDigraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n and k are non-negative integers, then this operation returns a symmetric digraph which corresponds to the undirected Johnson graph \(J(n, k)\).

The Johnson graph \(J(n, k)\) has vertices given by all the k-subsets of the range [1 .. n], and two vertices are connected by an edge if and only if their intersection has size \(\textit{k} - 1\).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> gr := JohnsonDigraph(3, 1);
<immutable symmetric digraph with 3 vertices, 6 edges>
gap> OutNeighbours(gr);
[ [ 2, 3 ], [ 1, 3 ], [ 1, 2 ] ]
gap> gr := JohnsonDigraph(4, 2);
<immutable symmetric digraph with 6 vertices, 24 edges>
gap> OutNeighbours(gr);
[ [ 2, 3, 4, 5 ], [ 1, 3, 4, 6 ], [ 1, 2, 5, 6 ], [ 1, 2, 5, 6 ], 
  [ 1, 3, 4, 6 ], [ 2, 3, 4, 5 ] ]
gap> JohnsonDigraph(1, 0);
<immutable empty digraph with 1 vertex>
gap> JohnsonDigraph(IsMutableDigraph, 1, 0);
<mutable empty digraph with 1 vertex>

3.5-24 KellerGraph
‣ KellerGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a nonnegative integer then this operation returns the nth or n-dimensional Keller graph. The graph has vertices given by the n-tuples on the set \([0, 1, 2, 3]\). Two vertices are adjacent if their respective tuples are such that they differ in at least two coordinates and in at least one coordinate the difference between the two is 2 mod 4. The Keller graph has 4^n vertices.

The Keller graphs were constructed with the intention of finding counterexamples to Keller's conjecture (https://mathworld.wolfram.com/KellersConjecture.html), and has been used since for testing maximum clique algorithms.

If n is 1 then the graph is empty, for n greater than 1 the chromatic number of the Keller graph is 2^n and the graph is Hamiltonian.

See https://mathworld.wolfram.com/KellerGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := KellerGraph(3);
<immutable Hamiltonian connected symmetric digraph with 64 vertices, 2\
176 edges>
gap> ChromaticNumber(D);
8

3.5-25 KingsGraph
‣ KingsGraph( [filt, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the king's graph of an m by n chessboard, as a symmetric digraph.

The king's graph represents all possible moves of the king chess piece across a chessboard. An m by n chessboard is a grid of m columns ("files") and n rows ("ranks") that intersect in squares. Orthogonally adjacent squares are alternately colored light and dark, with the square in the first rank and file being dark.

The king can move only to any orthogonally or diagonally adjacent square. Thus the m * n vertices of the king's graph can be placed onto the m * n squares of an m by n chessboard, such that two vertices are adjacent in the digraph if and only if the corresponding squares are orthogonally or diagonally adjacent on the chessboard.

The chosen correspondence between vertices and chess squares is given by DigraphVertexLabels (5.1-12). In more detail, the vertices of the digraph are labelled by elements of the Cartesian product [1..m] x [1..n], where the first entry indexes the column (file) of the square in the chessboard, and the second entry indexes the row (rank) of the square. (Note that the files are traditionally indexed by the lowercase letters of the alphabet). The vertices are sorted in ascending order, first by row (second component) and then column (first component). See Wikipedia for further information. See also SquareGridGraph (3.5-41), TriangularGridGraph (3.5-42), and StrongProduct (3.3-38).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> KingsGraph(8, 8);
<immutable connected symmetric digraph with 64 vertices, 420 edges>
gap> D := KingsGraph(IsMutable, 2, 7);
<mutable digraph with 14 vertices, 62 edges>
gap> IsPlanarDigraph(D);
true
gap> D := KingsGraph(3, 3);
<immutable connected symmetric digraph with 9 vertices, 40 edges>
gap> OutNeighbors(D);
[ [ 2, 4, 5 ], [ 1, 3, 5, 4, 6 ], [ 2, 6, 5 ], [ 5, 1, 7, 2, 8 ], 
  [ 4, 6, 2, 8, 3, 7, 1, 9 ], [ 5, 3, 9, 8, 2 ], [ 8, 4, 5 ], 
  [ 7, 9, 5, 6, 4 ], [ 8, 6, 5 ] ]
gap> IsSubdigraph(QueensGraph(3, 4), KingsGraph(3, 4));
true

3.5-26 KneserGraph
‣ KneserGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n and k are integers greater than 0, with k less than n, then this operation returns the (n,k)-th Kneser graph. The Kneser graph's vertices correspond to the k- element subsets of a set of n elements, with two vertices being adjacent if and only if the subsets are disjoint. The graph has Binomial(n, k) vertices and Binomial(n, k) * Binomial(n - k, k) edges. Kneser graphs are regular, edge transitive, and vertex transitive. If k is 1, then the graph is the complete graph on n vertices. If (n, k) is (2m-1, n-1), then the graph is the mth Odd graph. The Petersen graph is the \((5, 2)\)th Kneser graph.

If n >= 2k then the graph's chromatic number is n - 2k + 2, and otherwise is 1. The Kneser graph contains a Hamiltonian cycle if n >= ((3 + 5 ^ 0.5) / 2)k + 1. The graph has clique number equal to the floor of n / k.

See https://mathworld.wolfram.com/KneserGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := KneserGraph(7, 3);
<immutable edge- and vertex-transitive symmetric digraph with 35 verti\
ces, 140 edges>
gap> IsRegularDigraph(D);
true
gap> ChromaticNumber(D);
3
gap> CliqueNumber(D);
2

3.5-27 KnightsGraph
‣ KnightsGraph( [filt, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the knight's graph of an m by n chessboard, as a symmetric digraph.

A knight's graph represents all possible moves of the knight chess piece across a chessboard. An m by n chessboard is a grid of m columns ("files") and n rows ("ranks") that intersect in squares. Orthogonally adjacent squares are alternately colored light and dark, with the square in the first rank and file being dark.

The m * n vertices of the knight's graph can be placed onto the m * n squares of an m by n chessboard, such that two vertices are adjacent in the digraph if and only if a knight can move between the corresponding squares in a single turn.

The chosen correspondence between vertices and chess squares is given by DigraphVertexLabels (5.1-12). In more detail, the vertices of the digraph are labelled by elements of the Cartesian product [1..m] x [1..n], where the first entry indexes the column (file) of the square in the chessboard, and the second entry indexes the row (rank) of the square. (Note that the files are traditionally indexed by the lowercase letters of the alphabet). The vertices are sorted in ascending order, first by row (second component) and then column (first component). See Wikipedia for further information.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := KnightsGraph(8, 8);
<immutable connected symmetric digraph with 64 vertices, 336 edges>
gap> IsConnectedDigraph(D);
true
gap> D := KnightsGraph(3, 3);
<immutable symmetric digraph with 9 vertices, 16 edges>
gap> IsConnectedDigraph(D);
false
gap> KnightsGraph(IsMutable, 3, 9);
<mutable digraph with 27 vertices, 88 edges>

3.5-28 LindgrenSousselierGraph
‣ LindgrenSousselierGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer greater than 0, then this operation returns the nth Lindgren-Sousselier graph, an infinite family of hyophamiltonian graphs - a graph that is non-Hamiltonian but removing any vector gives a Hamiltonian graph. The graph has 6n+4 vertices and 15 + 10(n-1) undirected edges. The first Lindgren-Sousselier graph is the Petersen graph, and is in fact the smallest hyophamiltonian graph.

See https://mathworld.wolfram.com/HypohamiltonianGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := LindgrenSousselierGraph(3);
<immutable symmetric digraph with 22 vertices, 70 edges>
gap> IsHamiltonianDigraph(D);
false
gap> IsHamiltonianDigraph(DigraphRemoveVertex(D, 1));
true
gap> IsIsomorphicDigraph(LindgrenSousselierGraph(1), PetersenGraph());
true

3.5-29 LollipopGraph
‣ LollipopGraph( [filt, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the (m,n)-lollipop graph. As defined at https://en.wikipedia.org/wiki/Lollipop_graph, this consists of a complete digraph on the vertices [1..m] (the 'head' of the lollipop), and the symmetric closure of a chain digraph on the remaining n vertices (the 'stick'), connected by a bridge (the edge [m, m+1] and its reverse).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := LollipopGraph(5, 3);
<immutable connected symmetric digraph with 8 vertices, 26 edges>
gap> CliqueNumber(D);
5
gap> DigraphUndirectedGirth(D);
3
gap> LollipopGraph(IsMutableDigraph, 3, 8);
<mutable digraph with 11 vertices, 22 edges>

3.5-30 MobiusLadderGraph
‣ MobiusLadderGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 4, then this operation returns the Mobius ladder graph that is obtained by introducing a 'twist' in the nth prism graph, similar to the construction of a Mobius strip. The Mobius ladder graph is isomorphic to the circulant graph Ci(2n, [1, n]). The Mobius ladders are cubic, symmetric, Hamiltonian, vertex-transitive, and graceful. They are also non-planar and apex, meaning removing a single vertex produces a planar graph.

See https://mathworld.wolfram.com/MoebiusLadder.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := MobiusLadderGraph(7);
<immutable symmetric digraph with 14 vertices, 42 edges>
gap> IsHamiltonianDigraph(D);
true
gap> IsVertexTransitive(D);
true
gap> IsPlanarDigraph(D);
false
gap> D2 := DigraphRemoveVertex(D, 1);
<immutable digraph with 13 vertices, 36 edges>
gap> IsPlanarDigraph(D2);
true

3.5-31 MycielskiGraph
‣ MycielskiGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer greater than 1, then this operation returns the nth Mycielski graph. The Mycielskian of a triangle-free graph is a construction that adds vertices and edges to produce a new graph that is still triangle-free but has a larger chromatic number. The Mycielski graphs are a series of graphs with this construction repeated, starting with the complete graph on two vertices. The graph has 3 * 2^(n-2) - 1 vertices, with the number of edges being (18 - 27 * 2 ^ n + 14 * 3 ^ n) / 36.

The Mycielski graph has chromatic number equal to n, clique number equal to \(2\), and is Hamiltonian. The graph is in fact the graph with chromatic number n with the least possible vertices.

See https://mathworld.wolfram.com/MycielskiGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := MycielskiGraph(4);
<immutable Hamiltonian connected symmetric digraph with 11 vertices, 4\
0 edges>
gap> ChromaticNumber(D);
4
gap> CliqueNumber(D);
2

3.5-32 OddGraph
‣ OddGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer greater than 0, then this operation returns the nth odd graph. The odd graph has vertices labelled with the n-1-subsets of a 2n-1-set, with two vertices adjacent if and only if their subsets are disjoint. The nth odd graph is the (2n-1, n-1)-th Kneser graph. The graph has Binomial(2n-1, n-1) vertices and n * Binomial(2n-1, n-1) / 2 edges.

The odd graph is regular and distance transitive (and therefore distance regular). They have chromatic number equal to 3, and all Odd graphs with n greater than 3 are Hamiltonian. They are also vertex and edge transitive.

See https://mathworld.wolfram.com/OddGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := OddGraph(4);
<immutable edge- and vertex-transitive symmetric digraph with 35 verti\
ces, 140 edges>
gap> IsIsomorphicDigraph(D, KneserGraph(7, 3));
true
gap> ChromaticNumber(D);
3

3.5-33 PathGraph
‣ PathGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a non-negative integer then this operation returns the nth path graph, consisting of the path on n vertices. This is the symmetric closure of the ChainDigraph (3.5-9). The path graph has n vertices and n-1 edges. The path graph is an undirected tree.

See https://mathworld.wolfram.com/PathGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := PathGraph(12);
<immutable undirected tree digraph with 12 vertices>

3.5-34 PermutationStarGraph
‣ PermutationStarGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n is an integer at greater than 0 and k is an integer greater than 1, and k less than or equal to n, then this operation returns the (n, k)-th permutation star graph. The vertices of the graph are given by the k-length ordered subsets of an n-set, with two vertices being adjacent if one is labelled p1 p2 p3 ... pi ... pk, and the other is either labelled pi p2 p3 ... p1 ... pk, or labelled x p2 p3 ... pi ... pk where x is in [1..n] and is not equal to p1. The graph has n! / (n - k)! vertices.

The permutation star graph is regular and vertex transitive. It has diameter 2k - 1 if k less than or equal to Int(n / 2), and diameter Int((n - 1) / 2) + k if k >= Int(n / 2) + 1.

See https://mathworld.wolfram.com/PermutationStarGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := PermutationStarGraph(6, 2);
<immutable vertex-transitive symmetric digraph with 30 vertices, 150 e\
dges>
gap> DigraphDiameter(D);
3

3.5-35 PetersenGraph
‣ PetersenGraph( [filt] )( operation )

Returns: A digraph.

From https://en.wikipedia.org/wiki/Petersen_graph:

"The Petersen graph is an undirected graph with 10 vertices and 15 edges. It is a small graph that serves as a useful example and counterexample for many problems in graph theory. The Petersen graph is named after Julius Petersen, who in 1898 constructed it to be the smallest bridgeless cubic graph with no three-edge-coloring."

See also GeneralisedPetersenGraph (3.5-36).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> ChromaticNumber(PetersenGraph());
3
gap> PetersenGraph(IsMutableDigraph);
<mutable digraph with 10 vertices, 30 edges>

3.5-36 GeneralisedPetersenGraph
‣ GeneralisedPetersenGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n is a positive integer and k is a non-negative integer less than n / 2, then this operation returns the generalised Petersen graph \(GPG(\textit{n}, k)\).

From https://en.wikipedia.org/wiki/Generalized_Petersen_graph:

"The generalized Petersen graphs are a family of cubic graphs formed by connecting the vertices of a regular polygon to the corresponding vertices of a star polygon. They include the Petersen graph and generalize one of the ways of constructing the Petersen graph. The generalized Petersen graph family was introduced in 1950 by H. S. M. Coxeter and was given its name in 1969 by Mark Watkins."

See also PetersenGraph (3.5-35).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> GeneralisedPetersenGraph(7, 2);
<immutable symmetric digraph with 14 vertices, 42 edges>
gap> GeneralisedPetersenGraph(40, 1);
<immutable symmetric digraph with 80 vertices, 240 edges>
gap> D := GeneralisedPetersenGraph(5, 2);
<immutable symmetric digraph with 10 vertices, 30 edges>
gap> IsIsomorphicDigraph(D, PetersenGraph());
true
gap> GeneralisedPetersenGraph(IsMutableDigraph, 9, 4);
<mutable digraph with 18 vertices, 54 edges>

3.5-37 PrismGraph
‣ PrismGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 3, then this operation returns the prism graph that is the skeleton of the n-prism. It has 2n vertices and 3n undirected edges. The prism graph is a symmetric digraph. The nth prism graph is isomorphic to the graph Cartesian product of the second path graph and the nth cycle graph, isomorphic to the generalised Petersen graph GP(n,1). If n is odd then the prism graph is isomorphic to the Circulant graph Ci(2n, [2,n]). The prism graph is Hamiltonian.

See https://mathworld.wolfram.com/PrismGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := PrismGraph(4);
<immutable symmetric digraph with 8 vertices, 24 edges>
gap> IsHamiltonianDigraph(D);
true
gap> D := PrismGraph(5);
<immutable symmetric digraph with 10 vertices, 30 edges>
gap> IsIsomorphicDigraph(D, CirculantGraph(10, [2, 5]));
true

3.5-38 StackedPrismGraph
‣ StackedPrismGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n is an integer at least 3 and k is a positive integer then this operation returns the (n,k)-th stacked prism graph. The graph is k concentric n-Cycle graphs connected by spokes. The stacked prism is the graph Cartesian product of the nth cycle graph and the kth path graph. The graph has nk vertices and n(2k - 1) undirected edges. If k is 1 then the graph is the nth cycle graph, if k is 2 then the graph is the prism graph.

See https://mathworld.wolfram.com/StackedPrismGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := StackedPrismGraph(5, 2);
<immutable symmetric digraph with 10 vertices, 30 edges>
gap> IsIsomorphicDigraph(D, PrismGraph(5));
true

3.5-39 QueensGraph
‣ QueensGraph( [filt, ]m, n )( operation )
‣ QueenGraph( [filt, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the queen's graph of an m by n chessboard, as a symmetric digraph.

The queen's graph represents all possible moves of the queen chess piece across a chessboard. An m by n chessboard is a grid of m columns ("files") and n rows ("ranks") that intersect in squares. Orthogonally adjacent squares are alternately colored light and dark, with the square in the first rank and file being dark.

The m * n vertices of the queen's graph can be placed onto the m * n squares of an m by n chessboard, such that two vertices are adjacent in the digraph if and only if the queen can move between the corresponding squares in a single turn. A legal queen's move is defined as one which moves the queen to an (orthogonally or diagonally) adjacent square, or to a square which can be reached through a series of such moves, with all of the small moves being in the same direction.

Note that the QueensGraph is the DigraphEdgeUnion (3.3-30) of the RooksGraph (3.5-40) and the BishopsGraph (3.5-5) of the same dimensions.

The chosen correspondence between vertices and chess squares is given by DigraphVertexLabels (5.1-12). In more detail, the vertices of the digraph are labelled by elements of the Cartesian product [1..m] x [1..n], where the first entry indexes the column (file) of the square in the chessboard, and the second entry indexes the row (rank) of the square. (Note that the files are traditionally indexed by the lowercase letters of the alphabet). The vertices are sorted in ascending order, first by row (second component) and then column (first component). If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> QueensGraph(2, 5);
<immutable connected symmetric digraph with 10 vertices, 66 edges>
gap> D := QueensGraph(4, 3);
<immutable connected symmetric digraph with 12 vertices, 92 edges>
gap> IsRegularDigraph(D);
false
gap> QueensGraph(6, 9) =
>    DigraphEdgeUnion(RooksGraph(6, 9), BishopsGraph(6, 9));
true

3.5-40 RooksGraph
‣ RooksGraph( [filt, ]m, n )( operation )
‣ RookGraph( [filt, ]m, n )( operation )

Returns: A digraph.

If m and n are positive integers, then this operation returns the rook's graph of an m by n chessboard, as a symmetric digraph.

A rook's graph represents all possible moves of the rook chess piece across a chessboard. An m by n chessboard is a grid of m columns ("files") and n rows ("ranks") that intersect in squares. Orthogonally adjacent squares are alternately colored light and dark, with the square in the first rank and file being dark.

The m * n vertices of the rook's graph can be placed onto the m * n squares of an m by n chessboard, such that two vertices are adjacent in the digraph if and only if a rook can move between the corresponding squares in a single turn. A legal rook's move is defined as one which moves the rook to an orthogonally adjacent square, or to a square which can be reached through a series of such moves, with all of the small moves being in the same direction.

The chosen correspondence between vertices and chess squares is given by DigraphVertexLabels (5.1-12). In more detail, the vertices of the digraph are labelled by elements of the Cartesian product [1..m] x [1..n], where the first entry indexes the column (file) of the square in the chessboard, and the second entry indexes the row (rank) of the square. (Note that the files are traditionally indexed by the lowercase letters of the alphabet). The vertices are sorted in ascending order, first by row (second component) and then column (first component). See Wikipedia for further information. See also DigraphCartesianProduct (3.3-32) and LineDigraph (3.3-41).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := RooksGraph(7, 4);
<immutable connected regular symmetric digraph with 28 vertices, 252 e\
dges>
gap> RooksGraph(1, 8);
<immutable connected regular symmetric digraph with 8 vertices, 56 edg\
es>

3.5-41 SquareGridGraph
‣ SquareGridGraph( [filt, ]n, k )( operation )
‣ GridGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n and k are positive integers, then this operation returns a square grid graph of dimension n by k.

A square grid graph of dimension n by k is the DigraphCartesianProduct (3.3-32) of the symmetric closures of the chain digraphs with n and k vertices; see DigraphSymmetricClosure (3.3-12) and ChainDigraph (3.5-9).

In particular, the n * k vertices can be arranged into an n by k grid such that two vertices are adjacent in the digraph if and only if they are orthogonally adjacent in the grid. The correspondence between vertices and grid positions is given by DigraphVertexLabels (5.1-12).

See https://en.wikipedia.org/wiki/Lattice_graph for more information.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> SquareGridGraph(5, 5);
<immutable connected bipartite symmetric digraph with bicomponent size\
s 13 and 12>
gap> GridGraph(IsMutable, 3, 4);
<mutable digraph with 12 vertices, 34 edges>

3.5-42 TriangularGridGraph
‣ TriangularGridGraph( [filt, ]n, k )( operation )

Returns: A digraph.

If n and k are positive integers, then this operation returns a triangular grid graph of dimension n by k.

A triangular grid graph of dimension n by k is a symmetric digraph constructed from the SquareGridGraph (3.5-41) of the same dimensions, where additionally two vertices are adjacent in the digraph if they are diagonally adjacent in the grid, on a particular one of the diagonals. The correspondence between vertices and grid positions is given by DigraphVertexLabels (5.1-12). More specifically, the particular diagonal is the one such that, the vertices corresponding to the grid positions [2,1] and [1,2] are adjacent (if they exist), but those corresponding to [1,1] and [2,2] are not.

See https://en.wikipedia.org/wiki/Lattice_graph#Other_kinds for more information.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> TriangularGridGraph(3, 3);
<immutable connected symmetric digraph with 9 vertices, 32 edges>
gap> TriangularGridGraph(IsMutable, 3, 3);
<mutable digraph with 9 vertices, 32 edges>

3.5-43 StarGraph
‣ StarGraph( [filt, ]k )( operation )

Returns: A digraph.

If k is a positive integer, then this operation returns the star graph with k vertices, which is the undirected tree in which vertex 1 is adjacent to all other vertices. If k is at least 2, then this is the complete bipartite digraph with bicomponents [1] and [2 .. k].

See IsUndirectedTree (6.6-9), IsCompleteBipartiteDigraph (6.2-4), and DigraphBicomponents (5.4-13).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> StarGraph(IsMutable, 10);
<mutable digraph with 10 vertices, 18 edges>
gap> StarGraph(5);
<immutable complete bipartite digraph with bicomponent sizes 1 and 4>
gap> IsSymmetricDigraph(StarGraph(3));
true
gap> IsUndirectedTree(StarGraph(3));
true

3.5-44 TadpoleGraph
‣ TadpoleGraph( [filt, ]m, n )( operation )

Returns: A digraph.

The tadpole graph is the symmetric closure of the disjoint union of the cycle digraph on [1..m] (the 'head' of the tadpole) and the chain digraph on [m+1..m+n] (the 'tail' of the tadpole), along with the additional edges [1, m+1] and [1, m+1] which connect the 'head' and the 'tail'. For more details on the tadpole graph please refer to https://en.wikipedia.org/wiki/Tadpole_graph.

See DigraphSymmetricClosure (3.3-12), DigraphDisjointUnion (3.3-29), CycleDigraph (3.5-14), and ChainDigraph (3.5-9).

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> TadpoleGraph(10, 15);
<immutable symmetric digraph with 25 vertices, 50 edges>
gap> TadpoleGraph(IsMutableDigraph, 5, 6);
<mutable digraph with 11 vertices, 22 edges>
gap> IsSymmetricDigraph(TadpoleGraph(3, 5));
true

3.5-45 WalshHadamardGraph
‣ WalshHadamardGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 1, then this operation returns the Hadamard graph constructed from the nth Hadamard matrix (of dimension 2^n) as constructed by Joseph Walsh. A Hadamard matrix is a square matrix with entries either \(1\) or \(-1\), such that all the rows are mutually orthogonal. The nth Walsh Hadamard graph is a graph on 4n matrices split into four categories \(r_i+, r_i-, c_i+, c_i-\). If \(h_ij\) are the elements of the nth Walsh matrix, then if \(h_ij = 1\) then \((r_i+, c_j+)\) and \((r_i-, c_j-)\) are edges, if \(h_ij = -1\) then \((r_i+, c_j-)\) and \((r_i-, c_j+)\) are edges. Walsh Hadamard graphs are distance transitive and distance regular.

See https://mathworld.wolfram.com/HadamardGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := WalshHadamardGraph(5);
<immutable symmetric digraph with 64 vertices, 1024 edges>
gap> IsDistanceRegularDigraph(D);
true

3.5-46 WebGraph
‣ WebGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is an integer at least 3 then this operation returns the nth web graph. The web graph is the (n,3)-th stacked prism graph with the edges of the outer cycle removed. The graph has 3n vertices and 4n undirected edges.

See https://mathworld.wolfram.com/WebGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := WebGraph(5);
<immutable symmetric digraph with 15 vertices, 40 edges>

3.5-47 WheelGraph
‣ WheelGraph( [filt, ]n )( operation )

Returns: A digraph.

If n is a positive integer at least 4, then this operation returns the nth wheel graph. The Wheel graph is formed from an n-1 cycle graph with a single additional vertex adjacent to all vertices of the cycle. The graph has n vertices and 2(n-1) edges. Wheel graphs are the skeletons of n-1 pyramids, and are self-dual. If n is odd, then the chromatic number of the wheel graph is 3 and the Wheel graph is perfect, and it is 4 otherwise. The wheel graph is also Hamiltonian and planar.

See https://mathworld.wolfram.com/WheelGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := WheelGraph(8);
<immutable Hamiltonian connected symmetric digraph with 8 vertices, 28\
 edges>
gap> ChromaticNumber(D);
4
gap> IsHamiltonianDigraph(D);
true

3.5-48 WindmillGraph
‣ WindmillGraph( [filt, ]n, m )( operation )

Returns: A digraph.

If n and m are integers greater than 1 then this operation returns the (n, m)-th windmill graph. The windmill graph is formed from m copies of the complete graph on n vertices with one shared vertex. The graph has m(n - 1) + 1 vertices and m * n * (n - 1) / 2 undirected edges. The windmill graph has chromatic number n and diameter 2.

See https://mathworld.wolfram.com/WindmillGraph.html for further details.

If the optional first argument filt is present, then this should specify the category or representation the digraph being created will belong to. For example, if filt is IsMutableDigraph (3.1-2), then the digraph being created will be mutable, if filt is IsImmutableDigraph (3.1-3), then the digraph will be immutable. If the optional first argument filt is not present, then IsImmutableDigraph (3.1-3) is used by default.

gap> D := WindmillGraph(4, 3);
<immutable symmetric digraph with 10 vertices, 36 edges>
gap> ChromaticNumber(D);
4
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 A Bib Ind

generated by GAPDoc2HTML