Skip to content

Commit

Permalink
Fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
Murray Whyte committed Nov 28, 2018
1 parent 2d7d29a commit 06ed6ef
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
5 changes: 1 addition & 4 deletions doc/oper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1208,10 +1208,7 @@ fail
<Oper Name="DigraphShortestPath" Arg="digraph, u, v"/>
<Returns>A pair of lists, or <K>fail</K>.</Returns>
<Description>
If there exists a non-trivial directed path (or a non-trivial cycle, in the
case that <A>u</A> <C>=</C> <A>v</A>) from vertex <A>u</A> to vertex
<A>v</A> in the digraph <A>digraph</A>, then this operation returns such a
directed path (or directed cycle) of minimum length. Otherwise, this operation returns
Returns the shortest directed path in the digraph digraph from the vertex u to the vertex v, if such a path exists. If u = v, then the shortest non-trivial cycle is returned, again, if it exists. Otherwise, this operation returns
<K>fail</K>. See Section <Ref Subsect="Definitions" Style="Text"/> for the
definition of a directed path and a directed cycle.
<P/>
Expand Down
60 changes: 34 additions & 26 deletions gap/oper.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1244,60 +1244,68 @@ end);
InstallMethod(DigraphShortestPath, "for a digraph and two pos ints",
[IsDigraph, IsPosInt, IsPosInt],
function(digraph, u, v)
local current, next, parent, distance, falselist, verts, nbs, n, a, b, i, path;
local current, next, parent, distance, falselist, verts, nbs, path, edge,
n, a, b, i;

verts := DigraphVertices(digraph);
nbs := OutNeighbors(digraph);
distance := [];
verts := DigraphVertices(digraph);
if not (u in verts and v in verts) then
ErrorNoReturn("Digraphs: DigraphPath: usage,\n",
"the second and third arguments <u> and <v> must be\n",
"vertices of the first argument <digraph>,");
fi;

if u = v and v in nbs[v] then # Considers the trivial path from v to v
return [[v, v], [Position(nbs[v], v)]];
if IsDigraphEdge(digraph, [u, v]) then
return [[u, v], [Position(OutNeighboursOfVertex(digraph, u), v)]];
elif HasIsTransitiveDigraph(digraph) and IsTransitiveDigraph(digraph) then
# If it's a known transitive digraph, just check whether the edge exists
return fail;
# Glean information from WCC if we have it
elif HasDigraphConnectedComponents(digraph)
and DigraphConnectedComponents(digraph).id[u] <>
DigraphConnectedComponents(digraph).id[v] then
return fail;
fi;

nbs := OutNeighbors(digraph);
distance := ListWithIdenticalEntries(Length(verts), -1);

# Setting up objects useful in the function.
for i in verts do
Add(distance, -1);
od;
parent := [];
current := [u];
next := [];
falselist := [];
for i in verts do
Add(next, false);
Add(falselist, false);
od;
parent := [];
current := [u];
edge := [];
next := BlistList([1 .. Length(verts)], []);
falselist := BlistList([1 .. Length(verts)], []);

n := 0; # Counts the loops
n := 0;
while current <> [] do
n := n + 1;
n := n + 1;
for a in current do
for b in nbs[a] do
for i in [1 .. Length(nbs[a])] do
b := nbs[a][i];
if distance[b] = -1 then
distance[b] := n;
next[b] := true;
parent[b] := a;
edge[b] := i;
fi;

if b = v then
path := [[], []];
# Finds the path
for i in [1 .. n] do
Add(path[1], b);
Add(path[2], Position(nbs[parent[b]], b));
Add(path[2], edge[b]);
b := parent[b];
od;
Add(path[1], u); # Adds the starting vertex to the list of vertices.
return [Reversed(path[1]), Reversed(path[2])];
fi;

od;
od;

current := ListBlist(verts, next);
next := IntersectionBlist(next, falselist);

IntersectBlist(next, falselist);
od;
return fail;
return fail;
end);

# IteratorOfPaths: for a digraph and two pos ints
Expand Down

0 comments on commit 06ed6ef

Please sign in to comment.