Skip to content

Commit ffdf33d

Browse files
committed
doc/attr.xml
1 parent 5d52cb4 commit ffdf33d

File tree

5 files changed

+142
-0
lines changed

5 files changed

+142
-0
lines changed

bellman_ford.g

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
LoadPackage("Digraphs");
2+
bellmanford := function(digraph, source)
3+
local distance, n, predecessor, i, inf, u, v, edge, w;
4+
n := DigraphNrVertices(digraph);
5+
#wouldn't work for weighted digraphs
6+
inf := n+1;
7+
distance := List([1..n],x->0);
8+
predecessor := List([1..n],x->0);
9+
for i in DigraphVertices(digraph) do
10+
distance[i] := inf;
11+
predecessor[i] := 0;
12+
od;
13+
distance[source] := 0;
14+
for i in [1..n-1] do
15+
for edge in DigraphEdges(digraph) do
16+
u := edge[1];
17+
v := edge[2];
18+
#only works for unweighted graphs, w needs to be changed into a variable
19+
w := 1;
20+
if distance[u] + w < distance[v] then
21+
distance[v] := distance[u] + w;
22+
predecessor[v] := u;
23+
fi;
24+
od;
25+
od;
26+
for edge in DigraphEdges(digraph) do
27+
u := edge[1];
28+
v := edge[2];
29+
#only works for unweighted graphs, w needs to be changed into a variable
30+
w := 1;
31+
if distance[u] + w < distance[v] then
32+
Print("Graph contains a negative-weight cycle");
33+
fi;
34+
od;
35+
for i in DigraphVertices(digraph) do
36+
if distance[i] >= inf then
37+
distance[i] := fail;
38+
fi;
39+
if predecessor[i] = 0 then
40+
predecessor[i] := fail;
41+
fi;
42+
od;
43+
return [distance, predecessor];
44+
end;
45+

doc/attr.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,36 @@ gap> DigraphShortestDistances(D);
902902
</ManSection>
903903
<#/GAPDoc>
904904

905+
<#GAPDoc Label="UnweightedBellmanFord">
906+
<ManSection>
907+
<Attr Name="UnweightedBellmanFord" Arg="digraph","source"/>
908+
<Returns>A list of integers or <K>fail</K>.</Returns>
909+
<Description>
910+
If <A>digraph</A> is a digraph with <M>n</M> vertices, then this
911+
function returns a list with two sublists of <M>n</M> entries, where each entry is
912+
either a non-negative integer, or <K>fail</K>. <P/>
913+
914+
If there is a directed path from <A>source</A> to vertex <C>i</C>, then
915+
the value of the entry i in the first sublist is the length of the shortest such directed
916+
path and the entry i in the second sublist is the vertex preceding the vertex of that entry. If no such directed path exists, then the value of i is <C>fail</C>. We use the convention that the distance from every vertex to
917+
itself is <C>0</C> for all vertices <C>i</C>.
918+
<P/>
919+
920+
<Example><![CDATA[
921+
gap> D := Digraph([[1, 2], [3], [1, 2], [4]]);
922+
<immutable digraph with 4 vertices, 6 edges>
923+
gap> UnweightedBellmanFord(D,2)
924+
[ [ 2, 0, 1, fail ], [ 3, fail, 2, fail ] ]
925+
gap> D := CycleDigraph(IsMutableDigraph, 3);
926+
<mutable digraph with 3 vertices, 3 edges>
927+
gap> UnweightedBellmanFord(D,3);
928+
[ [ 1, 2, 0 ], [ 3, 1, fail ] ]
929+
]]></Example>
930+
</Description>
931+
</ManSection>
932+
<#/GAPDoc>
933+
934+
905935
<#GAPDoc Label="DigraphDiameter">
906936
<ManSection>
907937
<Attr Name="DigraphDiameter" Arg="digraph"/>

gap/attr.gd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ DeclareAttribute("DigraphDegeneracy", IsDigraph);
4545
DeclareAttribute("DigraphDegeneracyOrdering", IsDigraph);
4646
DeclareAttribute("DIGRAPHS_Degeneracy", IsDigraph);
4747
DeclareAttribute("DigraphShortestDistances", IsDigraph);
48+
DeclareOperation("UnweightedBellmanFord", [IsDigraph, IsPosInt]);
4849
DeclareAttribute("DigraphDiameter", IsDigraph);
4950
DeclareAttribute("DigraphGirth", IsDigraph);
5051
DeclareAttribute("DigraphOddGirth", IsDigraph);

gap/attr.gi

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,54 @@ end);
700700
# returns the vertices (i.e. numbers) of <D> ordered so that there are no
701701
# edges from <out[j]> to <out[i]> for all <i> greater than <j>.
702702

703+
InstallMethod(UnweightedBellmanFord, "for a digraph by out-neighbours",
704+
[IsDigraph,IsPosInt],
705+
function(digraph, source)
706+
local distance, n, predecessor, i, inf, u, v, edge, w;
707+
n := DigraphNrVertices(digraph);
708+
#wouldn't work for weighted digraphs
709+
inf := n+1;
710+
distance := List([1..n],x->0);
711+
predecessor := List([1..n],x->0);
712+
for i in DigraphVertices(digraph) do
713+
distance[i] := inf;
714+
predecessor[i] := 0;
715+
od;
716+
distance[source] := 0;
717+
for i in [1..n-1] do
718+
for edge in DigraphEdges(digraph) do
719+
u := edge[1];
720+
v := edge[2];
721+
#only works for unweighted graphs, w needs to be changed into a variable
722+
w := 1;
723+
if distance[u] + w < distance[v] then
724+
distance[v] := distance[u] + w;
725+
predecessor[v] := u;
726+
fi;
727+
od;
728+
od;
729+
for edge in DigraphEdges(digraph) do
730+
u := edge[1];
731+
v := edge[2];
732+
#only works for unweighted graphs, w needs to be changed into a variable
733+
w := 1;
734+
if distance[u] + w < distance[v] then
735+
Print("Graph contains a negative-weight cycle");
736+
fi;
737+
od;
738+
for i in DigraphVertices(digraph) do
739+
if distance[i] >= inf then
740+
distance[i] := fail;
741+
fi;
742+
if predecessor[i] = 0 then
743+
predecessor[i] := fail;
744+
fi;
745+
od;
746+
return [distance, predecessor];
747+
end);
748+
749+
750+
703751
InstallMethod(DigraphTopologicalSort, "for a digraph by out-neighbours",
704752
[IsDigraphByOutNeighboursRep],
705753
D -> DIGRAPH_TOPO_SORT(OutNeighbours(D)));

tst/standard/attr.tst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,24 @@ gap> DIGRAPH_ConnectivityDataForVertex(gr, 2);;
486486
gap> DigraphShortestDistances(gr);
487487
[ [ 0, 1, 1 ], [ 1, 0, 1 ], [ 1, 1, 0 ] ]
488488

489+
# UnweightedBellmanFord
490+
gap> gr := Digraph([[1, 2], [3], [1, 2], [4]]);
491+
<immutable digraph with 4 vertices, 6 edges>
492+
gap> UnweightedBellmanFord(gr,2);
493+
[ [ 2, 0, 1, fail ], [ 3, fail, 2, fail ] ]
494+
gap> gr := CycleDigraph(IsMutableDigraph, 3);
495+
<mutable digraph with 3 vertices, 3 edges>
496+
gap> UnweightedBellmanFord(gr,3);
497+
[ [ 1, 2, 0 ], [ 3, 1, fail ] ]
498+
gap> gr := Digraph([[],[]]);
499+
<immutable empty digraph with 2 vertices>
500+
gap> UnweightedBellmanFord(gr,2);
501+
[ [ fail, 0 ], [ fail, fail ] ]
502+
gap> gr := Digraph([[1],[2],[3],[4]]);
503+
<immutable digraph with 4 vertices, 4 edges>
504+
gap> UnweightedBellmanFord(gr,2);
505+
[ [ fail, 0, fail, fail ], [ fail, fail, fail, fail ] ]
506+
489507
# OutNeighbours and InNeighbours
490508
gap> gr := Digraph(rec(DigraphNrVertices := 10,
491509
> DigraphSource := [1, 1, 5, 5, 7, 10],

0 commit comments

Comments
 (0)