Skip to content

Commit 8cb1f38

Browse files
committed
Added SwapDigraphs and DigraphsRemoveAllEdges functions
1 parent 103c03f commit 8cb1f38

File tree

5 files changed

+213
-0
lines changed

5 files changed

+213
-0
lines changed

doc/oper.xml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,27 @@ true
733733
</ManSection>
734734
<#/GAPDoc>
735735

736+
<#GAPDoc Label="DigraphRemoveAllEdges">
737+
<ManSection>
738+
<Oper Name="DigraphRemoveAllEdges" Arg="digraph"/>
739+
<Returns>An empty digraph.</Returns>
740+
<Description>
741+
This operation returns a digraph constructed from <A>digraph</A>, which is mutable,
742+
by removing all of the edges in the original digraph.
743+
(see <Ref Oper="DigraphRemoveEdge" Label="for a digraph and an edge"/>).
744+
<P/>
745+
746+
<Example><![CDATA[
747+
gap> D3 := Digraph(IsMutableDigraph, [[2],[1],[2]]);
748+
<mutable digraph with 3 vertices, 3 edges>
749+
gap> DigraphRemoveAllEdges(D3);
750+
<mutable empty digraph with 3 vertices>
751+
true
752+
]]></Example>
753+
</Description>
754+
</ManSection>
755+
<#/GAPDoc>
756+
736757
<#GAPDoc Label="InducedSubdigraph">
737758
<ManSection>
738759
<Oper Name="InducedSubdigraph" Arg="digraph, verts"/>
@@ -2291,6 +2312,69 @@ gap> HomomorphicProduct(D1, D2);
22912312
</ManSection>
22922313
<#/GAPDoc>
22932314

2315+
2316+
<#GAPDoc Label="HomomorphicProduct">
2317+
<ManSection>
2318+
<Oper Name="HomomorphicProduct" Arg="D1, D2"/>
2319+
<Returns>A digraph.</Returns>
2320+
<Description>
2321+
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges,
2322+
then <C>HomomorphicProduct</C> calculates the <E>homomorphic product digraph</E>
2323+
(<C>HPD</C>) of <A>D1</A> and <A>D2</A>.
2324+
2325+
<C>HPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
2326+
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
2327+
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
2328+
an edge from <C>[a, b]</C> to <C>[c, d]</C> when at least one of the
2329+
following two conditions are satisfied:
2330+
<List>
2331+
<Item>
2332+
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal.
2333+
</Item>
2334+
<Item>
2335+
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A> and no edge from
2336+
<C>b</C> to <C>d</C> in <A>D2</A>.
2337+
</Item>
2338+
</List>
2339+
2340+
<Example><![CDATA[
2341+
gap> HomomorphicProduct(PetersenGraph(),
2342+
> DigraphSymmetricClosure(ChainDigraph(4)));
2343+
<immutable digraph with 40 vertices, 460 edges>
2344+
gap> D1 := Digraph([[2], [1, 3, 4], [2, 5], [2, 5], [3, 4]]);
2345+
<immutable digraph with 5 vertices, 10 edges>
2346+
gap> D2 := Digraph([[2], [1, 3], [2, 4], [3]]);
2347+
<immutable digraph with 4 vertices, 6 edges>
2348+
gap> HomomorphicProduct(D1, D2);
2349+
<immutable digraph with 20 vertices, 180 edges>
2350+
]]></Example>
2351+
</Description>
2352+
</ManSection>
2353+
<#/GAPDoc>
2354+
2355+
<#GAPDoc Label="SwapDigraphs">
2356+
<ManSection>
2357+
<Oper Name="SwapDigraphs" Arg="D1, D2"/>
2358+
<Description>
2359+
If <A>D1</A> and <A>D2</A> are mutable digraphs,
2360+
then <C>SwapDigraphs</C> will swap the contents of
2361+
<A>D1</A> and <A>D2</A>.
2362+
2363+
<Example><![CDATA[
2364+
gap> D1 := Digraph(IsMutableDigraph, [[4],[5],[1,2],[],[]]);
2365+
<mutable digraph with 5 vertices, 4 edges>
2366+
gap> D2 := Digraph(IsMutableDigraph, [[2, 3, 4], [1, 3, 4, 5], [1, 2], [5], [4]]);
2367+
<mutable digraph with 5 vertices, 11 edges>
2368+
gap> SwapDigraphs(D1, D2);
2369+
gap> OutNeighbours(D2);
2370+
[ [ 4 ], [ 5 ], [ 1, 2 ], [ ], [ ] ]
2371+
gap> OutNeighbours(D1);
2372+
[ [ 2, 3, 4 ], [ 1, 3, 4, 5 ], [ 1, 2 ], [ 5 ], [ 4 ] ]
2373+
]]></Example>
2374+
</Description>
2375+
</ManSection>
2376+
<#/GAPDoc>
2377+
22942378
<#GAPDoc Label="LexicographicProduct">
22952379
<ManSection>
22962380
<Oper Name="LexicographicProduct" Arg="D1, D2"/>

gap/oper.gd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ DeclareOperation("DigraphRemoveEdge", [IsDigraph, IsPosInt, IsPosInt]);
2929
DeclareOperation("DigraphRemoveEdge", [IsDigraph, IsList]);
3030
DeclareOperation("DigraphRemoveEdges", [IsDigraph, IsList]);
3131

32+
DeclareOperation("DigraphRemoveAllEdges", [IsDigraph]);
33+
3234
DeclareOperation("DigraphReverseEdge", [IsDigraph, IsList]);
3335
DeclareOperation("DigraphReverseEdge", [IsDigraph, IsPosInt, IsPosInt]);
3436
DeclareOperation("DigraphReverseEdges", [IsDigraph, IsList]);
@@ -59,6 +61,8 @@ DeclareSynonym("DigraphLexicographicProduct", LexicographicProduct);
5961
DeclareGlobalFunction("DIGRAPHS_CombinationOperProcessArgs");
6062
DeclareOperation("DIGRAPHS_GraphProduct", [IsDigraph, IsDigraph, IsFunction]);
6163

64+
DeclareOperation("SwapDigraphs", [IsDigraph, IsDigraph]);
65+
6266
# 4. Actions . . .
6367
DeclareOperation("OnDigraphs", [IsDigraph, IsPerm]);
6468
DeclareOperation("OnDigraphs", [IsDigraph, IsTransformation]);

gap/oper.gi

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,25 @@ InstallMethod(DigraphRemoveEdges, "for an immutable digraph and a list",
277277
[IsImmutableDigraph, IsList],
278278
{D, edges} -> MakeImmutable(DigraphRemoveEdges(DigraphMutableCopy(D), edges)));
279279

280+
InstallMethod(DigraphRemoveAllEdges, "for a mutable digraph",
281+
[IsDigraph],
282+
function(D)
283+
local i, neighbour, nbs, currentEdges;
284+
if IsImmutableDigraph(D) then
285+
ErrorNoReturn("Argument must be a mutable digraph");
286+
else
287+
nbs := OutNeighboursMutableCopy(D);
288+
289+
for i in [1..Length(nbs)] do
290+
currentEdges := DigraphOutEdges(D, i);
291+
DigraphRemoveEdges(D, currentEdges);
292+
od;
293+
294+
return D;
295+
fi;
296+
end);
297+
298+
280299
InstallMethod(DigraphReverseEdge,
281300
"for a mutable digraph by out-neighbours and two positive integers",
282301
[IsMutableDigraph and IsDigraphByOutNeighboursRep, IsPosInt, IsPosInt],
@@ -989,6 +1008,48 @@ function(D1, D2, edge_function)
9891008
return Digraph(edges);
9901009
end);
9911010

1011+
InstallMethod(SwapDigraphs,
1012+
"for a digraph and digraph",
1013+
[IsDigraph, IsDigraph],
1014+
function(D1, D2)
1015+
local nb1, nb2, i, neighbour, d2edges;
1016+
1017+
if IsMutableDigraph(D1) and IsMutableDigraph(D2) then
1018+
nb1 := OutNeighboursMutableCopy(D1);
1019+
nb2 := OutNeighboursMutableCopy(D2);
1020+
1021+
DigraphRemoveAllEdges(D1);
1022+
DigraphRemoveAllEdges(D2);
1023+
1024+
#If the second digraph has more vertices than the first
1025+
if Length(nb2) < Length(nb1) then
1026+
for i in [Length(nb2)..Length(nb1)-1] do
1027+
DigraphRemoveVertex(D1, Length(nb2)+1);
1028+
DigraphAddVertex(D2);
1029+
od;
1030+
else
1031+
for i in [Length(nb1)..Length(nb2)-1] do
1032+
DigraphRemoveVertex(D2, Length(nb1)+1);
1033+
DigraphAddVertex(D1);
1034+
od;
1035+
fi;
1036+
1037+
for i in [1..Length(nb2)] do
1038+
for neighbour in nb2[i] do
1039+
DigraphAddEdge(D1, i, neighbour);
1040+
od;
1041+
od;
1042+
1043+
for i in [1..Length(nb1)] do
1044+
for neighbour in nb1[i] do
1045+
DigraphAddEdge(D2, i, neighbour);
1046+
od;
1047+
od;
1048+
else
1049+
ErrorNoReturn("Arguments must be mutable digraphs");
1050+
fi;
1051+
end);
1052+
9921053
###############################################################################
9931054
# 4. Actions
9941055
###############################################################################

tst/standard/oper.tst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,22 @@ gap> gr := DigraphRemoveEdge(gr, [2, 1]);
109109
gap> DigraphEdges(gr);
110110
[ [ 1, 2 ] ]
111111

112+
# DigraphRemoveAllEdges: for a digraph
113+
gap> gr := Digraph(IsImmutableDigraph, [[2, 3], [3], [4], []]);
114+
<immutable digraph with 4 vertices, 4 edges>
115+
gap> DigraphRemoveAllEdges(gr);
116+
Error, Argument must be a mutable digraph
117+
gap> gr2 := Digraph(IsMutableDigraph, [[2, 3], [3], [4], []]);
118+
<mutable digraph with 4 vertices, 4 edges>
119+
gap> DigraphRemoveAllEdges(gr2);
120+
<mutable empty digraph with 4 vertices>
121+
gap> gr3 := Digraph(IsMutableDigraph, [[], [], [], []]);
122+
<mutable empty digraph with 4 vertices>
123+
gap> DigraphRemoveAllEdges(gr3);
124+
<mutable empty digraph with 4 vertices>
125+
gap> OutNeighbours(gr3);
126+
[ [ ], [ ], [ ], [ ] ]
127+
112128
# OnDigraphs: for a digraph and a perm
113129
gap> gr := Digraph([[2], [1], [3]]);
114130
<immutable digraph with 3 vertices, 3 edges>
@@ -2523,6 +2539,40 @@ gap> OutNeighbours(last);
25232539
gap> LexicographicProduct(ChainDigraph(3), CycleDigraph(7));
25242540
<immutable digraph with 21 vertices, 119 edges>
25252541

2542+
# SwapDigraphs
2543+
gap> D1 := Digraph([[2, 3, 4], [1, 3, 4, 5], [1, 2], [5], [4]]);
2544+
<immutable digraph with 5 vertices, 11 edges>
2545+
gap> D2 := Digraph(IsMutableDigraph, [[4],[5],[1,2],[],[]]);
2546+
<mutable digraph with 5 vertices, 4 edges>
2547+
gap> SwapDigraphs(D1, D2);
2548+
Error, Arguments must be mutable digraphs
2549+
gap> D1 := Digraph(IsMutableDigraph, [[2, 3, 4], [1, 3, 4, 5], [1, 2], [5], [4]]);
2550+
<mutable digraph with 5 vertices, 11 edges>
2551+
gap> SwapDigraphs(D1, D2);
2552+
gap> OutNeighbours(D1);
2553+
[ [ 4 ], [ 5 ], [ 1, 2 ], [ ], [ ] ]
2554+
gap> OutNeighbours(D2);
2555+
[ [ 2, 3, 4 ], [ 1, 3, 4, 5 ], [ 1, 2 ], [ 5 ], [ 4 ] ]
2556+
gap> D3 := Digraph(IsMutableDigraph, [[2],[1],[2]]);
2557+
<mutable digraph with 3 vertices, 3 edges>
2558+
gap> SwapDigraphs(D1, D3);
2559+
gap> OutNeighbours(D1);
2560+
[ [ 2 ], [ 1 ], [ 2 ] ]
2561+
gap> OutNeighbours(D3);
2562+
[ [ 4 ], [ 5 ], [ 1, 2 ], [ ], [ ] ]
2563+
gap> SwapDigraphs(D1, D3);
2564+
gap> OutNeighbours(D1);
2565+
[ [ 4 ], [ 5 ], [ 1, 2 ], [ ], [ ] ]
2566+
gap> OutNeighbours(D3);
2567+
[ [ 2 ], [ 1 ], [ 2 ] ]
2568+
gap> D2 := Digraph(IsMutableDigraph, [[],[],[]]);
2569+
<mutable empty digraph with 3 vertices>
2570+
gap> SwapDigraphs(D3, D2);
2571+
gap> OutNeighbours(D2);
2572+
[ [ 2 ], [ 1 ], [ 2 ] ]
2573+
gap> OutNeighbours(D3);
2574+
[ [ ], [ ], [ ] ]
2575+
25262576
# DigraphShortestPathSpanningTree
25272577
gap> D := Digraph([[2, 3, 4], [1, 3, 4, 5], [1, 2], [5], [4]]);
25282578
<immutable digraph with 5 vertices, 11 edges>

tst/testinstall.tst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ gap> DigraphNrEdges(gr2);
258258
gap> DigraphNrAdjacencies(gr2);
259259
21
260260

261+
# DigraphRemoveAllEdges
262+
gap> gr := Digraph(IsMutableDigraph, [[3], [4], [5], [1, 5], [1, 2]]);;
263+
gap> DigraphRemoveAllEdges(gr);
264+
<mutable empty digraph with 5 vertices>
265+
261266
# Fix seg fault cause by wrong handling of no edges in
262267
# FuncDIGRAPH_SOURCE_RANGE
263268
gap> gr := Digraph([[]]);
@@ -509,6 +514,15 @@ rec( comps := [ ], id := [ ] )
509514
gap> IsConnectedDigraph(D);
510515
true
511516

517+
# SwapDigraphs
518+
gap> C := Digraph(IsMutableDigraph, [[4],[5],[1,2],[],[]]);;
519+
gap> D := Digraph(IsMutableDigraph, [[2, 3, 4], [1, 3, 4, 5], [1, 2], [5], [4]]);;
520+
gap> SwapDigraphs(C, D);
521+
gap> OutNeighbours(D);
522+
[ [ 4 ], [ 5 ], [ 1, 2 ], [ ], [ ] ]
523+
gap> OutNeighbours(C);
524+
[ [ 2, 3, 4 ], [ 1, 3, 4, 5 ], [ 1, 2 ], [ 5 ], [ 4 ] ]
525+
512526
#
513527
gap> DIGRAPHS_StopTest();
514528
gap> STOP_TEST("Digraphs package: testinstall.tst", 0);

0 commit comments

Comments
 (0)