From 06ed6ef2f3e75dc198a33058de38c25d247300fb Mon Sep 17 00:00:00 2001 From: Murray Whyte Date: Wed, 28 Nov 2018 15:51:35 +0000 Subject: [PATCH] Fixup --- doc/oper.xml | 5 +---- gap/oper.gi | 60 +++++++++++++++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/doc/oper.xml b/doc/oper.xml index a7f5ba7ad..f0650d219 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -1208,10 +1208,7 @@ fail A pair of lists, or fail. - If there exists a non-trivial directed path (or a non-trivial cycle, in the - case that u = v) from vertex u to vertex - v in the digraph digraph, 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 fail. See Section for the definition of a directed path and a directed cycle.

diff --git a/gap/oper.gi b/gap/oper.gi index 77b699b6a..5975008ec 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -1244,38 +1244,49 @@ 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 and must be\n", + "vertices of the first argument ,"); + 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 @@ -1283,21 +1294,18 @@ function(digraph, u, v) # 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