Skip to content

Commit

Permalink
Merge branch 'master' into lollipop
Browse files Browse the repository at this point in the history
  • Loading branch information
marinaanagno authored Mar 2, 2021
2 parents 1ea6646 + 6a4ab85 commit f110df9
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 8 deletions.
63 changes: 63 additions & 0 deletions doc/grahom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -798,3 +798,66 @@ false
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="MaximalCommonSubdigraph">
<ManSection>
<Oper Name="MaximalCommonSubdigraph" Arg="D1, D2"/>
<Returns>A list containing a digraph and two transformations.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
<C>MaximalCommonSubdigraph</C> returns a maximal common subgraph <C>M</C> of
<A>D1</A> and <A>D2</A> with the maximum number of vertices. So <C>M</C> is a
digraph which embeds into both <A>D1</A> and <A>D2</A> and has the largest
number of vertices amoung such digraphs.

It returns a list <C>[M, t1, t2]</C> where <C>M</C> is the maximal common
subdigraph and <C>t1, t2</C> are transformations embedding <C>M</C> into
<A>D1</A> and <A>D2</A> respectively.

<Example><![CDATA[
gap> MaximalCommonSubdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 2 vertices, 2 edges>,
IdentityTransformation, IdentityTransformation ]
gap> MaximalCommonSubdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 5 vertices, 10 edges>,
IdentityTransformation, IdentityTransformation ]
gap> MaximalCommonSubdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable empty digraph with 0 vertices>, IdentityTransformation,
IdentityTransformation ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalCommonSuperdigraph">
<ManSection>
<Oper Name="MinimalCommonSuperdigraph" Arg="D1, D2"/>
<Returns>A list containing a digraph and two transformations.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
<C>MinimalCommonSuperdigraph</C> returns a minimal common superdigraph
<C>M</C> of <A>D1</A> and <A>D2</A> with the minimum number of vertices.
So <C>M</C> is a digraph into which both <A>D1</A> and <A>D2</A> embed and
has the smallest number of vertices amoung such digraphs.

It returns a list <C>[M, t1, t2]</C> where <C>M</C> is the minimal common
superdigraph and <C>t1, t2</C> are transformations embedding <A>D1</A> and
<A>D2</A> respectively into <C>M</C>.
<Example><![CDATA[
gap> MinimalCommonSuperdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 18 vertices, 118 edges>,
IdentityTransformation,
Transformation( [ 1, 2, 11, 12, 13, 14, 15, 16, 17, 18, 11, 12, 13,
14, 15, 16, 17, 18 ] ) ]
gap> MinimalCommonSuperdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 10 vertices, 30 edges>,
IdentityTransformation, IdentityTransformation ]
gap> MinimalCommonSuperdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable digraph with 10 vertices, 90 edges>,
IdentityTransformation, IdentityTransformation ]
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
19 changes: 13 additions & 6 deletions doc/grape.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#############################################################################
##
#W grape.xml
#Y Copyright (C) 2014-19 James D. Mitchell
#Y Copyright (C) 2014-21 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
Expand Down Expand Up @@ -51,12 +51,19 @@ true]]></Example>
<Description>
Let <A>G</A> be any group and let <A>gens</A> be a list of elements of
<A>G</A>. This operation returns an immutable digraph that corresponds to
the Cayley graph of <A>G</A> with respect
<A>gens</A>. The vertices are the elements of <A>G</A>. There exists an edge
from the vertex <C>u</C> to the vertex <C>v</C> if and only if there exists
a generator <C>g</C> in <A>gens</A> such that <C>x * g = y</C>. <P/>
the Cayley graph of <A>G</A> with respect to <A>gens</A>. <P/>

<!-- FIXME What is the correspondence between vertices and elements? -->
The vertices of the digraph correspond to the elements of <A>G</A>,
in the order given by <C>AsList(<A>G</A>)</C>.
There exists an edge from vertex <C>u</C> to vertex <C>v</C>
if and only if there exists a generator <C>g</C> in <A>gens</A>
such that <C>AsList(<A>G</A>)[u] * g = AsList(<A>G</A>)[v]</C>. <P/>

The labels of the vertices <C>u</C>, <C>v</C>, and the edge <C>[u, v]</C>
are the corresponding elements <C>AsList(<A>G</A>)[u]</C>,
<C>AsList(<A>G</A>)[v]</C>, and generator <C>g</C>, respectively;
see <Ref Oper="DigraphVertexLabel"/> and <Ref Oper="DigraphEdgeLabel"/>.
<P/>

If the optional second argument <A>gens</A> is not present, then the
generators of <A>G</A> are used by default.<P/>
Expand Down
2 changes: 2 additions & 0 deletions doc/z-chap6.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ from} $E_a$ \emph{to} $E_b$. In this case we say that $E_a$ and $E_b$ are
<#Include Label="RepresentativeOutNeighbours">
<#Include Label="IsDigraphAutomorphism">
<#Include Label="IsDigraphColouring">
<#Include Label="MaximalCommonSubdigraph">
<#Include Label="MinimalCommonSuperdigraph">
</Section>

<Section><Heading>Homomorphisms of digraphs</Heading>
Expand Down
3 changes: 3 additions & 0 deletions gap/grahom.gd
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,6 @@ DeclareOperation("DigraphsRespectsColouring",
[IsDigraph, IsDigraph, IsTransformation, IsList, IsList]);
DeclareOperation("DigraphsRespectsColouring",
[IsDigraph, IsDigraph, IsPerm, IsList, IsList]);

DeclareOperation("MaximalCommonSubdigraph", [IsDigraph, IsDigraph]);
DeclareOperation("MinimalCommonSuperdigraph", [IsDigraph, IsDigraph]);
77 changes: 77 additions & 0 deletions gap/grahom.gi
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,80 @@ function(D, t)
n := DigraphNrVertices(D);
return IsDigraphColouring(D, ImageListOfTransformation(t, n));
end);

InstallMethod(MaximalCommonSubdigraph, "for a pair of digraphs",
[IsDigraph, IsDigraph],
function(A, B)
local D1, D2, MPG, nonloops, Clqus, M, l, n, m, embedding1, embedding2, iso;

D1 := DigraphImmutableCopy(A);
D2 := DigraphImmutableCopy(B);

# If the digraphs are isomorphic then we return the first one as the answer
iso := IsomorphismDigraphs(D1, D2);
if iso <> fail then
return [D1, IdentityTransformation, AsTransformation(iso)];
fi;

n := DigraphNrVertices(D1);
m := DigraphNrVertices(D2);

# The algorithm works as follows: We construct the modular product digraph
# MPG (see https://en.wikipedia.org/wiki/Modular_product_of_graphs for the
# undirected version) a maximal partial isomorphism between D1 and D2 is
# equal to a maximal clique this digraph. We then search for cliques using the
# DigraphMaximalCliquesReps function.

MPG := ModularProduct(D1, D2);

nonloops := Filtered([1 .. n * m], x -> not x in OutNeighbours(MPG)[x]);
# We find a big clique
Clqus := DigraphMaximalCliquesReps(MPG, [], nonloops);
M := 1;
for l in [1 .. Size(Clqus)] do
if Size(Clqus[l]) > Size(Clqus[M]) then
M := l;
fi;
od;

embedding1 := List(Clqus[M], x -> QuoInt(x - 1, m) + 1);
embedding2 := List(Clqus[M], x -> RemInt(x - 1, m) + 1);
return [InducedSubdigraph(D1, embedding1),
Transformation([1 .. Size(embedding1)], embedding1),
Transformation([1 .. Size(embedding2)], embedding2)];

end);

InstallMethod(MinimalCommonSuperdigraph, "for a pair of digraphs",
[IsDigraph, IsDigraph],
function(D1, D2)
local out, L, v, e, embfunc, embedding1, embedding2, newvertices;
L := MaximalCommonSubdigraph(D1, D2);
L[2] := List([1 .. DigraphNrVertices(L[1])], x -> x ^ L[2]);
L[3] := List([1 .. DigraphNrVertices(L[1])], x -> x ^ L[3]);
out := List(OutNeighbours(D1), x -> ShallowCopy(x));
newvertices := Filtered(DigraphVertices(D2), x -> not x in L[3]);
embedding1 := [1 .. DigraphNrVertices(D1)];

embfunc := function(v)
if v in L[3] then
return L[2][Position(L[3], v)];
fi;
return Position(newvertices, v) + DigraphNrVertices(D1);
end;
embedding2 := List(DigraphVertices(D2), embfunc);

for v in newvertices do
Add(out, []);
od;

for e in DigraphEdges(D2) do
if (not e[1] in L[3]) or (not e[2] in L[3]) then
Add(out[embedding2[e[1]]], embedding2[e[2]]);
fi;
od;

return [Digraph(out), Transformation([1 .. Size(embedding1)], embedding1),
Transformation([1 .. Size(embedding2)], embedding2)];

end);
4 changes: 3 additions & 1 deletion gap/grape.gi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#############################################################################
##
## grape.gi
## Copyright (C) 2019 James D. Mitchell
## Copyright (C) 2019-21 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
Expand Down Expand Up @@ -111,6 +111,8 @@ function(G, gens)
SetFilterObj(D, IsCayleyDigraph);
SetGroupOfCayleyDigraph(D, G);
SetGeneratorsOfCayleyDigraph(D, gens);
SetDigraphEdgeLabels(D, ListWithIdenticalEntries(Size(G), gens));
SetDigraphVertexLabels(D, AsList(G));

return D;
end);
Expand Down
40 changes: 40 additions & 0 deletions tst/standard/grahom.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2453,6 +2453,46 @@ false
gap> IsDigraphEmbedding(ran, src, (), [2, 1], [1, 1, 2]);
false

# MaximalCommSubdigraph and MinimalCommonSuperDigraph
gap> MaximalCommonSubdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable empty digraph with 0 vertices>, IdentityTransformation,
IdentityTransformation ]
gap> MinimalCommonSuperdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable digraph with 10 vertices, 90 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MaximalCommonSubdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 2 vertices, 2 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MinimalCommonSuperdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 18 vertices, 118 edges>, IdentityTransformation,
Transformation( [ 1, 2, 11, 12, 13, 14, 15, 16, 17, 18, 11, 12, 13, 14, 15,
16, 17, 18 ] ) ]
gap> MaximalCommonSubdigraph(NullDigraph(10), CompleteDigraph(10));
[ <immutable empty digraph with 1 vertex>, IdentityTransformation,
IdentityTransformation ]
gap> MinimalCommonSuperdigraph(NullDigraph(10), CompleteDigraph(10));
[ <immutable digraph with 19 vertices, 90 edges>, IdentityTransformation,
Transformation( [ 1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 11, 12, 13, 14, 15,
16, 17, 18, 19 ] ) ]
gap> MaximalCommonSubdigraph(CompleteDigraph(100), CompleteDigraph(100));
[ <immutable digraph with 100 vertices, 9900 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MinimalCommonSuperdigraph(CompleteDigraph(100), CompleteDigraph(100));
[ <immutable digraph with 100 vertices, 9900 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MaximalCommonSubdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 5 vertices, 10 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MinimalCommonSuperdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 10 vertices, 30 edges>, IdentityTransformation,
IdentityTransformation ]
gap> MaximalCommonSubdigraph(Digraph([[1, 1]]), Digraph([[1]]));
Error, ModularProduct does not support multidigraphs,
gap> MinimalCommonSuperdigraph(Digraph([[1, 1]]), Digraph([[1]]));
Error, ModularProduct does not support multidigraphs,

# DIGRAPHS_UnbindVariables
gap> Unbind(edges);
gap> Unbind(epis);
Expand Down
10 changes: 9 additions & 1 deletion tst/standard/grape.tst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#############################################################################
##
#W standard/grape.tst
#Y Copyright (C) 2019 James D. Mitchell
#Y Copyright (C) 2019-21 James D. Mitchell
##
## Licensing information can be found in the README file of this package.
##
Expand All @@ -18,6 +18,14 @@ gap> group := DihedralGroup(8);
<pc group of size 8 with 3 generators>
gap> digraph := CayleyDigraph(group);
<immutable digraph with 8 vertices, 24 edges>
gap> DigraphVertexLabels(digraph) = AsList(group);
true
gap> DigraphEdgeLabels(digraph) =
> ListWithIdenticalEntries(Size(group), GeneratorsOfGroup(group));
true
gap> ForAll(DigraphEdges(digraph), e -> AsList(group)[e[1]]
> * DigraphEdgeLabel(digraph, e[1], e[2]) = AsList(group)[e[2]]);
true
gap> group := DihedralGroup(IsPermGroup, 8);
Group([ (1,2,3,4), (2,4) ])
gap> digraph := CayleyDigraph(group);
Expand Down

0 comments on commit f110df9

Please sign in to comment.