Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gap/digraph.gd
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,5 @@ DeclareOperation("RandomLattice", [IsFunction, IsPosInt]);
# in the not-too-distant future!
DeclareOperation("RandomMultiDigraph", [IsPosInt]);
DeclareOperation("RandomMultiDigraph", [IsPosInt, IsPosInt]);

DeclareOperation("RemoveDigraphEdgeWeight", [IsDigraph, IsPosInt, IsPosInt]);
47 changes: 47 additions & 0 deletions gap/digraph.gi
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,41 @@ InstallMethod(DigraphMutableCopy, "for a digraph by out-neighbours",
[IsDigraphByOutNeighboursRep],
function(D)
local copy;

copy := ConvertToMutableDigraphNC(OutNeighboursMutableCopy(D));
SetDigraphVertexLabels(copy, StructuralCopy(DigraphVertexLabels(D)));

if HaveEdgeLabelsBeenAssigned(D) then
SetDigraphEdgeLabelsNC(copy, StructuralCopy(DigraphEdgeLabelsNC(D)));
fi;

if IsImmutableDigraph(D) and HasEdgeWeights(D) then
copy!.edgeweights := EdgeWeightsMutableCopy(D);
elif IsMutableDigraph(D) and IsBound(D!.edgeweights) then
copy!.edgeweights := StructuralCopy(D!.edgeweights);
fi;

return copy;
end);

InstallMethod(DigraphImmutableCopy, "for a digraph by out-neighbours",
[IsDigraphByOutNeighboursRep],
function(D)
local copy;

copy := ConvertToImmutableDigraphNC(OutNeighboursMutableCopy(D));
SetDigraphVertexLabels(copy, StructuralCopy(DigraphVertexLabels(D)));

if HaveEdgeLabelsBeenAssigned(D) then
SetDigraphEdgeLabelsNC(copy, StructuralCopy(DigraphEdgeLabelsNC(D)));
fi;

if IsImmutableDigraph(D) and HasEdgeWeights(D) then
SetEdgeWeights(copy, StructuralCopy(EdgeWeights(D)));
elif IsMutableDigraph(D) and IsBound(D!.edgeweights) then
SetEdgeWeights(copy, StructuralCopy(D!.edgeweights));
fi;

return copy;
end);

Expand Down Expand Up @@ -1837,3 +1855,32 @@ n -> RandomLatticeCons(IsImmutableDigraph, n));

InstallMethod(RandomLattice, "for a func and a pos int", [IsFunction, IsPosInt],
RandomLatticeCons);

InstallMethod(RemoveDigraphEdgeWeight, "for a mutable digraph, pos int, pos int",
[IsMutableDigraph and IsDigraphByOutNeighboursRep, IsPosInt, IsPosInt],
function(D, v, pos)
if IsBound(D!.edgeweights) and v <= Length(D!.edgeweights) and pos <= Length(D!.edgeweights[v]) then
Remove(D!.edgeweights[v], pos);
fi;
end);

InstallMethod(RemoveDigraphEdgeWeight, "for an immutable digraph, pos int, pos int",
[IsImmutableDigraph, IsPosInt, IsPosInt],
function(D, v, pos)
local newD, w;
newD := DigraphMutableCopy(D);

if IsBound(newD!.edgeweights) then
if v <= Length(newD!.edgeweights)
and pos <= Length(newD!.edgeweights[v]) then
Remove(newD!.edgeweights[v], pos);
fi;
fi;

MakeImmutable(newD);
if IsBound(newD!.edgeweights) then
SetEdgeWeights(newD, StructuralCopy(newD!.edgeweights));
fi;

return newD;
end);
61 changes: 45 additions & 16 deletions gap/oper.gi
Original file line number Diff line number Diff line change
Expand Up @@ -103,45 +103,61 @@ function(D, m, labels)
return DigraphAddVertices(D, labels);
end);

InstallMethod(DigraphRemoveVertex,
"for a mutable digraph by out-neighbours and positive integer",
InstallMethod(DigraphRemoveVertex, "for a mutable digraph by out-neighbours and positive integer",
[IsMutableDigraph and IsDigraphByOutNeighboursRep, IsPosInt],
function(D, u)
local pos, w, v;

if u > DigraphNrVertices(D) then
return D;
fi;

RemoveDigraphVertexLabel(D, u);
if IsBound(D!.edgelabels) then
Remove(D!.edgelabels, u);
fi;

Remove(D!.OutNeighbours, u);
if IsBound(D!.edgeweights) then
Remove(D!.edgeweights, u);
fi;

for v in DigraphVertices(D) do
pos := 1;
while pos <= Length(D!.OutNeighbours[v]) do
w := D!.OutNeighbours[v][pos];

if w = u then
Remove(D!.OutNeighbours[v], pos);
RemoveDigraphEdgeLabel(D, v, pos);
RemoveDigraphEdgeWeight(D, v, pos);

elif w > u then
D!.OutNeighbours[v][pos] := w - 1;
pos := pos + 1;
D!.OutNeighbours[v][pos] := w - 1;
pos := pos + 1;

else
pos := pos + 1;
pos := pos + 1;
fi;
od;
od;
return D;
end);

InstallMethod(DigraphRemoveVertex,
"for an immutable digraph and positive integer",
InstallMethod(DigraphRemoveVertex, "for an immutable digraph and positive integer",
[IsImmutableDigraph, IsPosInt],
function(D, u)
if u > DigraphNrVertices(D) then
return D;
local newD;

newD := DigraphMutableCopy(D);
DigraphRemoveVertex(newD, u);
MakeImmutable(newD);

if IsBound(newD!.edgeweights) then
SetEdgeWeights(newD, StructuralCopy(newD!.edgeweights));
fi;
return MakeImmutable(DigraphRemoveVertex(DigraphMutableCopy(D), u));

return newD;
end);

InstallMethod(DigraphRemoveVertices, "for a mutable digraph and a list",
Expand Down Expand Up @@ -223,8 +239,7 @@ InstallMethod(DigraphAddEdges, "for an immutable digraph and a list",
[IsImmutableDigraph, IsList],
{D, edges} -> MakeImmutable(DigraphAddEdges(DigraphMutableCopy(D), edges)));

InstallMethod(DigraphRemoveEdge,
"for a mutable digraph by out-neighbours and two positive integers",
InstallMethod(DigraphRemoveEdge, "for a mutable digraph by out-neighbours and two positive integers",
[IsMutableDigraph and IsDigraphByOutNeighboursRep, IsPosInt, IsPosInt],
function(D, src, ran)
local pos;
Expand All @@ -238,19 +253,33 @@ function(D, src, ran)
ErrorNoReturn("the 3rd argument <ran> must be a vertex of the ",
"digraph <D> that is the 1st argument,");
fi;

pos := Position(D!.OutNeighbours[src], ran);

if pos <> fail then
Remove(D!.OutNeighbours[src], pos);
RemoveDigraphEdgeLabel(D, src, pos);
RemoveDigraphEdgeWeight(D, src, pos);
fi;

return D;
end);

InstallMethod(DigraphRemoveEdge,
"for a immutable digraph and two positive integers",
InstallMethod(DigraphRemoveEdge, "for a immutable digraph and two positive integers",
[IsImmutableDigraph, IsPosInt, IsPosInt],
{D, src, ran}
-> MakeImmutable(DigraphRemoveEdge(DigraphMutableCopy(D), src, ran)));
function(D, src, ran)
local newD;

newD := DigraphMutableCopy(D);
DigraphRemoveEdge(newD, src, ran);
MakeImmutable(newD);

if IsBound(newD!.edgeweights) then
SetEdgeWeights(newD, StructuralCopy(newD!.edgeweights));
fi;

return newD;
end);

InstallMethod(DigraphRemoveEdge, "for a mutable digraph and a list",
[IsMutableDigraph, IsList],
Expand Down
59 changes: 58 additions & 1 deletion tst/standard/digraph.tst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#@local adjacencies, b, bin, c, c1, c2, d, di, digraph, divides, elms, eq
#@local eq_distr, eq_new, error, f, failed, failed_names, failed_values, foo, g
#@local gr, gr1, gr2, gr3, gr4, gr5, graph, graph1, graph2, grnc, group, h
#@local hom13, hom21, hom23, hom31, hom41, hom42, hom52, hom53, i, im, inn
#@local hom13, hom21, hom23, hom31, hom41, hom42, hom52, hom53, i, im, im2, inn
#@local isGraph, iso, iso_distr, iso_new, j, k, list, m, main, mat, n, name
#@local name2, names, new, order, p, prop, properties, r, r1, r2, record, rel1
#@local rel2, rel3, representatives, s, schreierVector, sgn, temp, test, v, x
Expand Down Expand Up @@ -565,6 +565,63 @@ gap> OutNeighbours(D);
gap> AsDigraph(AsPartialPerm((2, 5, 3)), 2);
fail

# Tests for DigraphMutableCopy, DigraphImmutableCopy, RemoveDigraphEdgeWeight (mutable & immutable).
gap> d := EdgeWeightedDigraph([[2,3],[3],[],[]], [[5,10],[15],[],[]]);
<immutable digraph with 4 vertices, 3 edges>
gap> HasEdgeWeights(d);
true
gap> EdgeWeights(d);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]
gap> m := DigraphMutableCopy(d);
<mutable digraph with 4 vertices, 3 edges>
gap> IsMutableDigraph(m);
true
gap> OutNeighbours(m) = OutNeighbours(d);
true
gap> DigraphVertexLabels(m) = DigraphVertexLabels(d);
true
gap> HasEdgeWeights(m);
false
gap> IsBound(m!.edgeweights);
true
gap> m!.edgeweights = [[5,10],[15],[],[]];
true
gap> m!.edgeweights[1][1] := 999;
999
gap> EdgeWeights(d)[1][1];
5
gap> im := DigraphImmutableCopy(d);
<immutable digraph with 4 vertices, 3 edges>
gap> IsImmutableDigraph(im);
true
gap> OutNeighbours(im) = OutNeighbours(d);
true
gap> HasEdgeWeights(im);
true
gap> EdgeWeights(im);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]
gap> EdgeWeights(im)[1][1] := 777;
Error, List Assignment: <list> must be a mutable list
gap> EdgeWeights(d);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]
gap> m := DigraphMutableCopy(d);
<mutable digraph with 4 vertices, 3 edges>
gap> RemoveDigraphEdgeWeight(m, 1, 2);
gap> m!.edgeweights;
[ [ 5 ], [ 15 ], [ ], [ ] ]
gap> EdgeWeights(d);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]
gap> im2 := DigraphImmutableCopy(d);
<immutable digraph with 4 vertices, 3 edges>
gap> im2 := RemoveDigraphEdgeWeight(im2, 1, 2);
<immutable digraph with 4 vertices, 3 edges>
gap> EdgeWeights(im2);
[ [ 5 ], [ 15 ], [ ], [ ] ]
gap> HasEdgeWeights(im2);
true
gap> EdgeWeights(d);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]

# RandomDigraph
gap> IsImmutableDigraph(RandomDigraph(100, 0.2));
true
Expand Down
42 changes: 41 additions & 1 deletion tst/standard/oper.tst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#@local G, G1, L, TestPartialOrderDigraph
#@local TestPartialOrderDigraph2, TestUnion, a, adj, b, comps, copy, d, e
#@local edges, edges2, func, g, gr, gr1, gr2, gr3, gr4, gri, grrt, grt, h, i
#@local i1, i2, id, idom, in1, in2, in3, iter, j1, j2, m, m1, m2, mat, n, nbs
#@local i1, i2, id, idom, in1, in2, in3, iter, j1, j2, m, m1, m2, m3, m4, im3, im4, mat, n, nbs
#@local out, out1, out2, out3, p1, p2, path, preorder, qr, r, res, rtclosure, t
#@local tclosure, u1, u2, x
gap> START_TEST("Digraphs package: standard/oper.tst");
Expand Down Expand Up @@ -3299,6 +3299,46 @@ gap> DigraphEdges(D);
gap> DigraphVertexLabels(D);
[ 1, 2, 3, 6, [ 4, 5 ] ]

# Tests for DigraphRemoveVertex, DigraphRemoveVertex (immutable), DigraphRemoveEdge, DigraphRemoveEdge (immutable).
gap> d := EdgeWeightedDigraph([[2,3],[3],[],[]], [[5,10],[15],[],[]]);
<immutable digraph with 4 vertices, 3 edges>
gap> m2 := DigraphMutableCopy(d);
<mutable digraph with 4 vertices, 3 edges>
gap> DigraphRemoveEdge(m2, 1, 3);
<mutable digraph with 4 vertices, 2 edges>
gap> OutNeighbours(m2);
[ [ 2 ], [ 3 ], [ ], [ ] ]
gap> m2!.edgeweights;
[ [ 5 ], [ 15 ], [ ], [ ] ]
gap> im3 := DigraphRemoveEdge(d, 1, 3);
<immutable digraph with 4 vertices, 2 edges>
gap> IsImmutableDigraph(im3);
true
gap> OutNeighbours(im3);
[ [ 2 ], [ 3 ], [ ], [ ] ]
gap> EdgeWeights(im3);
[ [ 5 ], [ 15 ], [ ], [ ] ]
gap> m4 := DigraphMutableCopy(d);
<mutable digraph with 4 vertices, 3 edges>
gap> DigraphRemoveVertex(m4, 1);
<mutable digraph with 3 vertices, 1 edge>
gap> OutNeighbours(m4);
[ [ 2 ], [ ], [ ] ]
gap> m4!.edgeweights;
[ [ 15 ], [ ], [ ] ]
gap> im4 := DigraphRemoveVertex(d, 1);
<immutable digraph with 3 vertices, 1 edge>
gap> IsImmutableDigraph(im4);
true
gap> OutNeighbours(im4);
[ [ 2 ], [ ], [ ] ]
gap> EdgeWeights(im4);
[ [ 15 ], [ ], [ ] ]
gap> OutNeighbours(d);
[ [ 2, 3 ], [ 3 ], [ ], [ ] ]
gap> EdgeWeights(d);
[ [ 5, 10 ], [ 15 ], [ ], [ ] ]

#
gap> DIGRAPHS_StopTest();
gap> STOP_TEST("Digraphs package: standard/oper.tst", 0);
Loading