Skip to content

Commit b853de6

Browse files
committed
Initial version of AmalgamDigraphs and AmalgamDigraphsIsomorphic.
1 parent 1b7826e commit b853de6

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

gap/oper.gd

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ DeclareOperation("StrongProduct", [IsDigraph, IsDigraph]);
4646
DeclareOperation("ConormalProduct", [IsDigraph, IsDigraph]);
4747
DeclareOperation("HomomorphicProduct", [IsDigraph, IsDigraph]);
4848
DeclareOperation("LexicographicProduct", [IsDigraph, IsDigraph]);
49+
DeclareOperation("AmalgamDigraphs", [IsDigraph, IsDigraph, IsList, IsList]);
50+
DeclareOperation("AmalgamDigraphsIsomorphic", [IsDigraph, IsDigraph, IsList, IsList]);
4951

5052
DeclareSynonym("DigraphModularProduct", ModularProduct);
5153
DeclareSynonym("DigraphStrongProduct", StrongProduct);

gap/oper.gi

+77
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,83 @@ function(D1, D2, edge_function)
765765
return Digraph(edges);
766766
end);
767767

768+
InstallMethod(AmalgamDigraphsIsomorphic,
769+
"for a digraph, a digraph, a list, and a list",
770+
[IsDigraph, IsDigraph, IsList, IsList],
771+
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
772+
local subdigraph1, subdigraph2, newSubdigraphVertices2, transformation, vertex;
773+
774+
subdigraph1 := InducedSubdigraph(D1, subdigraphVertices1);
775+
subdigraph2 := InducedSubdigraph(D2, subdigraphVertices2);
776+
777+
if not IsIsomorphicDigraph(subdigraph1, subdigraph2) then
778+
ErrorNoReturn(
779+
"the two subdigraphs must be isomorphic.");
780+
fi;
781+
782+
newSubdigraphVertices2 := [];
783+
transformation := DigraphEmbedding(subdigraph2, subdigraph1);
784+
for vertex in subdigraphVertices2 do
785+
newSubdigraphVertices2[Position(subdigraphVertices2, vertex) ^ transformation] := vertex;
786+
od;
787+
788+
return AmalgamDigraphs(D1, D2, subdigraphVertices1, newSubdigraphVertices2);
789+
end);
790+
791+
InstallMethod(AmalgamDigraphs,
792+
"for a digraph, a digraph, a list, and a list",
793+
[IsDigraph, IsDigraph, IsList, IsList],
794+
function(D1, D2, subdigraphVertices1, subdigraphVertices2)
795+
local D, map, vertex, vertexList, size, iterator, edgeList, subLength;
796+
797+
if not InducedSubdigraph(D1, subdigraphVertices1) = InducedSubdigraph(D2, subdigraphVertices2) then
798+
ErrorNoReturn(
799+
"the two subdigraphs must be equal.");
800+
fi;
801+
802+
# Create a mutable copy so that the function also works on immutable input digraphs.
803+
D := DigraphMutableCopy(D1);
804+
subLength := Length(subdigraphVertices1);
805+
806+
# 'map' is a mapping from the vertices of D2 to the vertices of the final output graph.
807+
# The idea is to map the subdigraph vertices of D2 onto the subdigraph vertices of D1
808+
# and then map the rest of the vertices of D2 to other (higher) values. The mapping
809+
# from D1 to the output graph can be understood as the identity mapping.
810+
map := rec();
811+
812+
for vertex in [1 .. subLength] do
813+
map.(subdigraphVertices2[vertex]) := subdigraphVertices1[vertex];
814+
od;
815+
816+
vertexList := Difference(DigraphVertices(D2), subdigraphVertices2);
817+
size := DigraphNrVertices(D1);
818+
iterator := 1;
819+
for vertex in vertexList do
820+
map.(vertex) := iterator + size;
821+
iterator := iterator + 1;
822+
od;
823+
824+
# The problem with adding edges to the output graph was that the edges of of the subdigraph
825+
# were added twice, creating multiple edges between certain pairs of points. A quick and
826+
# readable fix would have been to use DigraphRemoveAllMultipleEdges, but I decided
827+
# to check each of the edges being added to see if they were already in the subdigraph. This
828+
# way the function does not end up adding edges only to delete them later.
829+
edgeList := ShallowCopy(DigraphEdges(D2));
830+
iterator := 1;
831+
while iterator <= Length(edgeList) do
832+
if edgeList[iterator][1] in subdigraphVertices2 and edgeList[iterator][2] in subdigraphVertices2 then
833+
Remove(edgeList, iterator);
834+
else
835+
edgeList[iterator] := [map.(edgeList[iterator][1]), map.(edgeList[iterator][2])];
836+
iterator := iterator + 1;
837+
fi;
838+
od;
839+
840+
DigraphAddVertices(D, DigraphNrVertices(D2) - subLength);
841+
DigraphAddEdges(D, edgeList);
842+
return [MakeImmutable(D), map];
843+
end);
844+
768845
###############################################################################
769846
# 4. Actions
770847
###############################################################################

tst/standard/oper.tst

+35
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,41 @@ gap> path := DigraphPath(D, 5, 5);;
27572757
gap> IsDigraphPath(D, path);
27582758
true
27592759

2760+
# AmalgamDigraphs
2761+
gap> D1 := Digraph([[2, 3], [1, 3], [1, 2], [2], [3, 4]]);;
2762+
gap> D2 := Digraph([[2, 6], [1, 3, 5], [4], [3], [4, 6], [1, 5]]);;
2763+
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 4, 5], [4, 3, 5, 2]);
2764+
[ <immutable digraph with 7 vertices, 15 edges>,
2765+
rec( 1 := 6, 2 := 5, 3 := 3, 4 := 2, 5 := 4, 6 := 7 ) ]
2766+
gap> D1 := Digraph([
2767+
> [2, 3], [1, 3, 4, 6], [1, 2, 5, 7], [2, 6], [3, 7], [2, 4, 7, 8],
2768+
> [3, 5, 6, 8], [6, 7]]);;
2769+
gap> D2 := Digraph([
2770+
> [2, 3], [1, 4], [1, 5], [2, 5, 6], [3, 4, 7], [4, 7], [5, 6]]);;
2771+
gap> U := AmalgamDigraphs(D1, D2, [2, 3, 6, 7], [4, 5, 6, 7]);
2772+
[ <immutable digraph with 11 vertices, 32 edges>,
2773+
rec( 1 := 9, 2 := 10, 3 := 11, 4 := 2, 5 := 3, 6 := 6, 7 := 7 ) ]
2774+
gap> AmalgamDigraphs(D1, D2, [3, 6, 2, 7], [4, 5, 7, 6]);
2775+
Error, the two subdigraphs must be equal.
2776+
gap> D1 := PetersenGraph();;
2777+
gap> U := AmalgamDigraphs(D1, D1, [3, 4, 6, 8, 9], [3, 4, 6, 8, 9]);
2778+
[ <immutable digraph with 15 vertices, 50 edges>,
2779+
rec( 1 := 11, 10 := 15, 2 := 12, 3 := 3, 4 := 4, 5 := 13, 6 := 6, 7 := 14,
2780+
8 := 8, 9 := 9 ) ]
2781+
2782+
# AmalgamDigraphsIsomorphic
2783+
gap> D1 := PetersenGraph();;
2784+
gap> D2 := Digraph([
2785+
> [2, 4], [1, 3, 4, 5], [2, 5], [1, 2, 6], [2, 3, 7], [4, 7, 8],
2786+
> [5, 6, 8], [6, 7]]);;
2787+
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 6, 8, 9],
2788+
> [2, 4, 5, 6, 7]);
2789+
[ <immutable digraph with 13 vertices, 42 edges>,
2790+
rec( 1 := 11, 2 := 3, 3 := 12, 4 := 4, 5 := 8, 6 := 9, 7 := 6, 8 := 13 ) ]
2791+
gap> U := AmalgamDigraphsIsomorphic(D1, D2, [3, 4, 10, 8, 9],
2792+
> [2, 4, 5, 6, 7]);
2793+
Error, the two subdigraphs must be isomorphic.
2794+
27602795
#DIGRAPHS_UnbindVariables
27612796
gap> Unbind(a);
27622797
gap> Unbind(adj);

0 commit comments

Comments
 (0)