Skip to content

Commit

Permalink
Resolve Issue digraphs#140 (ArticulationPoints)
Browse files Browse the repository at this point in the history
  • Loading branch information
James Mitchell committed Oct 18, 2018
1 parent b560442 commit e42789a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 25 deletions.
53 changes: 28 additions & 25 deletions gap/attr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

InstallMethod(ArticulationPoints, "for a digraph", [IsDigraph],
function(digraph)
local copy, nbs, counter, visited, num, low, parent, points, v_stack,
w_stack, depth, 1st_root_nb, v, w, i;
local copy, nbs, counter, visited, num, low, parent, points, points_seen,
stack, depth, v, w, i;

if (HasIsConnectedDigraph(digraph) and not IsConnectedDigraph(digraph))
or DigraphNrVertices(digraph) <= 1 then
Expand All @@ -32,51 +32,54 @@ function(digraph)
low := [];
parent := [1];
points := [];
v_stack := [1];
w_stack := [0];
points_seen := BlistList([1 .. DigraphNrVertices(copy)], []);
stack := [[1, 0]];
depth := 1;
1st_root_nb := First(nbs[1], x -> not x = 1);

while depth > 1 or not visited[1] do
if visited[v_stack[depth]] then
v := stack[depth][1];
if visited[v] then
depth := depth - 1;
v := v_stack[depth];
w := nbs[v][w_stack[depth]];
if v = 1 then
if w <> 1st_root_nb then
Add(points, v);
fi;
elif low[w] >= num[v] then
v := stack[depth][1];
w := nbs[v][stack[depth][2]];
if v <> 1 and low[w] >= num[v] and not points_seen[v] then
points_seen[v] := true;
Add(points, v);
fi;
if low[w] < low[v] then
low[v] := low[w];
fi;
else
v := v_stack[depth];
visited[v] := true;
counter := counter + 1;
num[v] := counter;
low[v] := counter;
fi;
for i in [w_stack[depth] + 1 .. Length(nbs[v])] do
i := PositionProperty(nbs[v], w -> w <> v, stack[depth][2]);
while i <> fail do
w := nbs[v][i];
if w <> v then
if not visited[w] then
parent[w] := v;
w_stack[depth] := i;
depth := depth + 1;
v_stack[depth] := w;
w_stack[depth] := 0;
break;
elif parent[v] <> w and num[w] < low[v] then
low[v] := num[w];
if not visited[w] then
parent[w] := v;
stack[depth][2] := i;
depth := depth + 1;
if not IsBound(stack[depth]) then
stack[depth] := [];
fi;
stack[depth][1] := w;
stack[depth][2] := 0;
break;
elif parent[v] <> w and num[w] < low[v] then
low[v] := num[w];
fi;
i := PositionProperty(nbs[v], w -> w <> v, i);
od;
od;

if counter = DigraphNrVertices(digraph) then
i := Position(parent, 1, 1);
if i <> fail and Position(parent, 1, i) <> fail then
Add(points, 1);
fi;
SetIsConnectedDigraph(digraph, true);
return points;
else
Expand Down
17 changes: 17 additions & 0 deletions tst/standard/attr.tst
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,23 @@ gap> ArticulationPoints(DigraphFromGraph6String("FlCX?"));
gap> ArticulationPoints(Digraph([[2, 4, 5], [1, 4], [4, 7], [1, 2, 3, 5, 6, 7],
> [1, 4], [4, 7], [3, 4, 6]]));
[ 4 ]
gap> gr := DigraphFromSparse6String(
> ":~?@V`OINBg_McouHAxQD@gyYEW}Q_@_YdgE`?OgZgpEbfYQKDGqiDQEI`wGdjoADGZG\
> FIJONFQSplq]y@IwvbPKhMh}JGK?OLzW{agKKfRCtarqTGayQGb]rMIurapkxPG?RGcI]\
> IBtB_`EQKJ@LmxlL_?k^QieOkB|T");
<digraph with 87 vertices, 214 edges>
gap> ArticulationPoints(gr);
[ 30, 27, 23, 21, 63, 12, 73, 52, 75, 84, 11, 17, 60, 19, 87, 15, 69, 76, 42,
61, 59, 66, 68, 8, 51, 41, 37, 36, 18, 79, 3, 46, 1 ]
gap> IsDuplicateFree(last);
true
gap> ForAll(ArticulationPoints(gr),
> x -> not IsConnectedDigraph(DigraphRemoveVertex(gr, x)));
true
gap> Set(ArticulationPoints(gr))
> = Filtered(DigraphVertices(gr),
> x -> not IsConnectedDigraph(DigraphRemoveVertex(gr, x)));
true

#T# HamiltonianPath
gap> g := Digraph([]);
Expand Down

0 comments on commit e42789a

Please sign in to comment.