Skip to content

Commit 063023f

Browse files
oper: minor fix to Dijkstra
1 parent c3fae09 commit 063023f

File tree

5 files changed

+91
-80
lines changed

5 files changed

+91
-80
lines changed

doc/oper.xml

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -989,17 +989,6 @@ gap> Display(shortest_distances);
989989
</ManSection>
990990
<#/GAPDoc>
991991

992-
<#GAPDoc Label="DigraphDijkstraS">
993-
<ManSection>
994-
<Oper Name="DigraphDijkstraS" Arg="digraph, source"/>
995-
<Oper Name="DigraphDijkstraST" Arg="digraph, source, target"/>
996-
<Returns></Returns>
997-
<Description>
998-
999-
</Description>
1000-
</ManSection>
1001-
<#/GAPDoc>
1002-
1003992
<#GAPDoc Label="DigraphEdgeUnion">
1004993
<ManSection>
1005994
<Func Name="DigraphEdgeUnion" Arg="D1, D2, ..."
@@ -1711,30 +1700,41 @@ true
17111700
</ManSection>
17121701
<#/GAPDoc>
17131702

1714-
<#GAPDoc Label="DigraphDijkstraST">
1703+
<#GAPDoc Label="DigraphDijkstra">
17151704
<ManSection>
1716-
<Oper Name="DigraphDijkstraST" Arg="digraph, source, target"/>
1717-
<Returns>Two lists.</Returns>
1718-
<Description>
1719-
If <A>digraph</A> is a digraph and <A>source</A> and <A>target</A> are vertices of <A>digraph</A>,
1720-
then <C>DigraphDijkstraST</C> calculates the shortest distance from <A>source</A> and returns two lists. Each element of the first list
1721-
is the distance of the corresponding element from <A>source</A>.
1722-
If a vertex was not visited in the process of calculating the shortest distance to <A>target</A> or if there is no path connecting that vertex
1723-
with <A>source</A> then the corresponding distance is infinity.
1724-
Each element of the second list gives the previous vertex in the shortest pahth from <A>source</A> to the corresponding vertex.
1725-
For <A>source</A> and for any vertices that remained unvisited this will be -1.
1726-
1727-
<Example><![CDATA[
1728-
gap> mat:= [ [0, 1, 1], [0, 0, 1], [0, 0, 0]];
1729-
[ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ]
1730-
gap> gr:=DigraphByAdjacencyMatrix(mat);
1731-
<immutable digraph with 3 vertices, 3 edges>
1732-
gap> DigraphDijkstraST(gr,2,3);
1733-
[ [ infinity, 0, 1 ], [ -1, -1, 2 ] ]
1734-
gap> DigraphDijkstraST(gr,1,3);
1735-
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ]
1736-
gap> DigraphDijkstraST(gr,1,2);
1737-
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ] ]]></Example>
1738-
</Description>
1739-
</ManSection>
1740-
<#/GAPDoc>
1705+
<Oper Name="DigraphDijkstra" Arg="digraph, source, target"/>
1706+
<Oper Name="DigraphDijkstra" Arg="digraph, source"/>
1707+
<Returns>Two lists.</Returns>
1708+
<Description>
1709+
If <A>digraph</A> is a digraph and <A>source</A> and <A>target</A> are
1710+
vertices of <A>digraph</A>, then <C>DigraphDijkstra</C> calculates the
1711+
length of the shortest path from <A>source</A> to <A>target</A> and returns
1712+
two lists. Each element of the first list is the distance of the
1713+
corresponding element from <A>source</A>. If a vertex was not visited in
1714+
the process of calculating the shortest distance to <A>target</A> or if
1715+
there is no path connecting that vertex with <A>source</A>, then
1716+
the corresponding distance is <K>infinity</K>. Each element of the
1717+
second list gives the previous vertex in the shortest path
1718+
from <A>source</A> to the corresponding vertex. For
1719+
<A>source</A> and for any vertices that remained unvisited this
1720+
will be <C>-1</C>.<P/>
1721+
1722+
If the optional second argument <A>target</A> is not present, then
1723+
<C>DigraphDijkstra</C> returns the shortest path from <A>source</A> to
1724+
every vertex that is reachable from <A>source</A>.
1725+
1726+
<Example><![CDATA[
1727+
gap> mat := [[0, 1, 1], [0, 0, 1], [0, 0, 0]];
1728+
[ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ]
1729+
gap> D := DigraphByAdjacencyMatrix(mat);
1730+
<immutable digraph with 3 vertices, 3 edges>
1731+
gap> DigraphDijkstra(D, 2, 3);
1732+
[ [ infinity, 0, 1 ], [ -1, -1, 2 ] ]
1733+
gap> DigraphDijkstra(D, 1, 3);
1734+
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ]
1735+
gap> DigraphDijkstra(D, 1, 2);
1736+
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ]
1737+
]]></Example>
1738+
</Description>
1739+
</ManSection>
1740+
<#/GAPDoc>

doc/z-chap4.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<#Include Label="DigraphDegeneracyOrdering">
6868
<#Include Label="HamiltonianPath">
6969
<#Include Label="NrSpanningTrees">
70+
<#Include Label="DigraphDijkstra">
7071
</Section>
7172

7273
<Section><Heading>Cayley graphs of groups</Heading>

gap/oper.gd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ DeclareOperation("IsPerfectMatching", [IsDigraph, IsHomogeneousList]);
9494
# 9. Connectivity . . .
9595
DeclareOperation("DigraphFloydWarshall",
9696
[IsDigraph, IsFunction, IsObject, IsObject]);
97-
DeclareOperation("DigraphDijkstraS",
97+
DeclareOperation("DigraphDijkstra",
9898
[IsDigraph, IsPosInt]);
99-
DeclareOperation("DigraphDijkstraST",
99+
DeclareOperation("DigraphDijkstra",
100100
[IsDigraph, IsPosInt, IsPosInt]);
101101

102102
DeclareOperation("DigraphConnectedComponent", [IsDigraph, IsPosInt]);

gap/oper.gi

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,47 +1314,57 @@ function(D, u, v)
13141314
return fail;
13151315
end);
13161316

1317-
InstallMethod(DigraphDijkstraS, "for a digraph, and a vertex",
1318-
[IsDigraph, IsPosInt],
1319-
{digraph, source} -> DigraphDijkstraST(digraph, source, fail));
1320-
1321-
InstallMethod(DigraphDijkstraST, "for a digraph, a vertex, and a vertex",
1322-
[IsDigraph, IsPosInt, IsPosInt],
1317+
BindGlobal("DIGRAPHS_DijkstraST",
13231318
function(digraph, source, target)
1324-
local dist, prev, queue, u, v, alt;
1319+
local dist, prev, queue, u, v, alt;
13251320

1326-
dist := [];
1327-
prev := [];
1328-
queue := BinaryHeap({x, y} -> x[1] < y[1]);
1321+
if not source in DigraphVertices(digraph) then
1322+
ErrorNoReturn("the 2nd argument <source> must be a vertex of the ",
1323+
"1st argument <digraph>");
1324+
elif target <> fail and not target in DigraphVertices(digraph) then
1325+
ErrorNoReturn("the 3rd argument <target> must be a vertex of the ",
1326+
"1st argument <digraph>");
1327+
fi;
13291328

1330-
for v in DigraphVertices(digraph) do
1331-
dist[v] := infinity;
1332-
prev[v] := -1;
1333-
od;
1329+
dist := [];
1330+
prev := [];
1331+
queue := BinaryHeap({x, y} -> x[1] < y[1]);
13341332

1335-
dist[source] := 0;
1336-
Push(queue, [0, source]);
1333+
for v in DigraphVertices(digraph) do
1334+
dist[v] := infinity;
1335+
prev[v] := -1;
1336+
od;
13371337

1338-
while not IsEmpty(queue) do
1339-
u := Pop(queue);
1340-
u := u[2];
1341-
# TODO: this has a small performance impact for DigraphDijkstraS,
1342-
# but do we care?
1343-
if u = target then
1344-
return [dist, prev];
1345-
fi;
1346-
for v in OutNeighbours(digraph)[u] do
1347-
alt := dist[u] + DigraphEdgeLabel(digraph, u, v);
1348-
if alt < dist[v] then
1349-
dist[v] := alt;
1350-
prev[v] := u;
1351-
Push(queue, [dist[v], v]);
1352-
fi;
1353-
od;
1338+
dist[source] := 0;
1339+
Push(queue, [0, source]);
1340+
1341+
while not IsEmpty(queue) do
1342+
u := Pop(queue);
1343+
u := u[2];
1344+
# TODO: this has a small performance impact for DigraphDijkstraS,
1345+
# but do we care?
1346+
if u = target then
1347+
return [dist, prev];
1348+
fi;
1349+
for v in OutNeighbours(digraph)[u] do
1350+
alt := dist[u] + DigraphEdgeLabel(digraph, u, v);
1351+
if alt < dist[v] then
1352+
dist[v] := alt;
1353+
prev[v] := u;
1354+
Push(queue, [dist[v], v]);
1355+
fi;
13541356
od;
1355-
return [dist, prev];
1357+
od;
1358+
return [dist, prev];
13561359
end);
13571360

1361+
InstallMethod(DigraphDijkstra, "for a digraph, a vertex, and a vertex",
1362+
[IsDigraph, IsPosInt, IsPosInt], DIGRAPHS_DijkstraST);
1363+
1364+
InstallMethod(DigraphDijkstra, "for a digraph, and a vertex",
1365+
[IsDigraph, IsPosInt],
1366+
{digraph, source} -> DIGRAPHS_DijkstraST(digraph, source, fail));
1367+
13581368
InstallMethod(IteratorOfPaths,
13591369
"for a digraph by out-neighbours and two pos ints",
13601370
[IsDigraphByOutNeighboursRep, IsPosInt, IsPosInt],

tst/standard/oper.tst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,19 +2010,19 @@ gap> OutNeighbours(C);
20102010
[ [ 5, 6, 7 ], [ 7 ], [ 7 ], [ 7 ], [ 1, 6, 7 ], [ 1, 5, 7 ],
20112011
[ 3, 2, 1, 6, 5, 4 ] ]
20122012

2013-
#DigraphDijkstraST
2013+
#DigraphDijkstra
20142014
# When there is one path to target
20152015
gap> mat := [[0, 1, 1], [0, 0, 1], [0, 0, 0]];
20162016
[ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ]
20172017
gap> gr := DigraphByAdjacencyMatrix(mat);
20182018
<immutable digraph with 3 vertices, 3 edges>
20192019
gap> DigraphShortestDistance(gr, 2, 3);
20202020
1
2021-
gap> DigraphDijkstraST(gr, 2, 3);
2021+
gap> DigraphDijkstra(gr, 2, 3);
20222022
[ [ infinity, 0, 1 ], [ -1, -1, 2 ] ]
2023-
gap> DigraphDijkstraST(gr, 1, 3);
2023+
gap> DigraphDijkstra(gr, 1, 3);
20242024
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ]
2025-
gap> DigraphDijkstraST(gr, 1, 2);
2025+
gap> DigraphDijkstra(gr, 1, 2);
20262026
[ [ 0, 1, 1 ], [ -1, 1, 1 ] ]
20272027
gap> DigraphShortestDistance(gr, 1, 3);
20282028
1
@@ -2034,21 +2034,21 @@ gap> gr := DigraphByAdjacencyMatrix(mat);
20342034
<immutable digraph with 3 vertices, 2 edges>
20352035
gap> DigraphShortestDistance(gr, 2, 3);
20362036
fail
2037-
gap> DigraphDijkstraST(gr, 2, 3);
2037+
gap> DigraphDijkstra(gr, 2, 3);
20382038
[ [ infinity, 0, infinity ], [ -1, -1, -1 ] ]
20392039
gap> mat := [[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 0, 0], [1, 0, 0, 0]];
20402040
[ [ 0, 1, 1, 1 ], [ 0, 0, 1, 1 ], [ 0, 1, 0, 0 ], [ 1, 0, 0, 0 ] ]
20412041
gap> gr := DigraphByAdjacencyMatrix(mat);
20422042
<immutable digraph with 4 vertices, 7 edges>
2043-
gap> DigraphDijkstraST(gr, 1, 4);
2043+
gap> DigraphDijkstra(gr, 1, 4);
20442044
[ [ 0, 1, 1, 1 ], [ -1, 1, 1, 1 ] ]
20452045
gap> mat := [[0, 1, 1, 1], [0, 0, 1, 1], [0, 1, 0, 0], [1, 0, 0, 0]];
20462046
[ [ 0, 1, 1, 1 ], [ 0, 0, 1, 1 ], [ 0, 1, 0, 0 ], [ 1, 0, 0, 0 ] ]
20472047
gap> gr := DigraphByAdjacencyMatrix(mat);
20482048
<immutable digraph with 4 vertices, 7 edges>
2049-
gap> DigraphDijkstraST(gr, 1, 2);
2049+
gap> DigraphDijkstra(gr, 1, 2);
20502050
[ [ 0, 1, 1, 1 ], [ -1, 1, 1, 1 ] ]
2051-
gap> DigraphDijkstraST(gr, 1, 3);
2051+
gap> DigraphDijkstra(gr, 1, 3);
20522052
[ [ 0, 1, 1, 1 ], [ -1, 1, 1, 1 ] ]
20532053

20542054
#DIGRAPHS_UnbindVariables

0 commit comments

Comments
 (0)