Skip to content

Commit acaea65

Browse files
committed
Separate code into testable functions
1 parent f6e9006 commit acaea65

File tree

2 files changed

+107
-51
lines changed

2 files changed

+107
-51
lines changed

gap/weights.gi

Lines changed: 106 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -622,69 +622,124 @@ end);
622622
#############################################################################
623623
#
624624
# returns an iterator that generates the (possibly empty) sequence of paths
625-
# between source and dest
625+
# between source and dest by increasing weight.
626626
#
627627
# the iterator needs to store
628628
# - found paths
629629
# - candidates
630-
# -
630+
# - reference to the digraph
631631
# rec( found_paths := [],
632-
InstallGlobalFunction(DIGRAPHS_ShortestPathsIterator,
633-
function(digraph, source, dest)
634-
local currentIterator, findNextPath;
635-
636-
currentIterator := rec(
637-
candidates := BinaryHeap(),
638-
foundPaths := [
639-
EdgeWeightedDigraphShortestPath(digraph, source, dest)
640-
]);
641-
642-
findNextPath := function(iter)
643-
local currentShortestPath, currentShortestPathLength, spurNode, rootPath,
644-
rootPathNode, modifiedGraph, foundPaths, i, p, spurPath, totalPath,
645-
nextPath;
646-
647-
currentShortestPath := Last(iter.foundPaths);
648-
currentShortestPathLength := Length(currentShortestPath[1]);
649-
foundPaths := iter.foundPaths;
650-
651-
for i in [1 .. currentShortestPathLength] do
652-
modifiedGraph := fail;
653-
654-
spurNode := currentShortestPath[1][i];
655-
rootPath := [
656-
currentShortestPath[1]{[1..i]},
657-
currentShortestPath[2]{[1..i-1]}
658-
];
659-
660-
for p in foundPaths do
661-
if rootPath = p[1]{[1..i]} then
662-
# remove p[2][i] from Graph;
663-
fi;
664-
od;
665632

666-
for rootPathNode in rootPath[1] do
667-
if rootPathNode <> spurNode then
668-
# remove rootPathNode from Graph;
669-
fi;
670-
od;
633+
DIGRAPHS_SPI := function(digraph, source, dest)
634+
local iter;
671635

672-
spurPath := EdgeWeightedDigraphShortestPath(modifiedGraph, spurNode, dest);
673-
totalPath := [ Concatenation(rootPath[1], spurPath[1]),
674-
Concatenation(rootPath[2], spurPath[2]) ];
636+
iter := rec(
637+
NextIterator := function(iter)
638+
local shortestPath;
675639

676-
Push(iter.candidatePaths, totalPath);
640+
if IsEmpty(iter!.foundPaths) then
641+
shortestPath := EdgeWeightedDigraphShortestPath(iter!.digraph, iter!.source, iter!.dest);
642+
Add(iter!.foundPaths, shortestPath);
643+
else
644+
645+
fi;
646+
end,
647+
IsDoneIterator := function(iter)
648+
return IsEmpty(iter!.candidatePaths);
649+
end,
650+
ShallowCopy := function(iter)
651+
# TODO
652+
return iter;
653+
end,
654+
PrintObj := function(iter)
655+
Print("<iterator of shortst paths between vertices>");
656+
end,
657+
658+
foundPaths := [],
659+
candidatePaths := BinaryHeap(),
660+
digraph := digraph,
661+
source := source,
662+
dest := dest
663+
);
664+
return IteratorByFunctions(iter);
665+
end;
666+
667+
# FIXME: find out how often paths are used as objects in
668+
# their own right.
669+
DIGRAPHS_ConcatenatePaths := function(a, b)
670+
local a_length;
671+
672+
a_length := Length(a);
673+
674+
if a[1][a_length] <> b[1][1] then
675+
ErrorNoReturn("concatenatePaths: last vertex on `a` is not equal to first vertex of `b`");
676+
fi;
677+
678+
if a_length = 0 then
679+
return StructuralCopy(b);
680+
else
681+
return [ Concatenation(a[1]{[1..a_length-1]}, b[1]),
682+
Concatenation(b[2], b[2]) ];
683+
fi;
684+
end;
685+
686+
DIGRAPHS_ModifyGraph := function(digraph, root, foundPaths)
687+
mutableWeights := EdgeWeightsMutableCopy(digraph);
688+
for p in foundPaths do
689+
if rootPath = p[1]{[1..i]} then
690+
mutableWeights[p[2][i]] := infinity;
691+
fi;
677692
od;
678693

679-
if IsEmpty(iter.candidatePaths) then
680-
return fail;
694+
rootNodes := currentShortestPath[1]{[1..i-1]};
695+
696+
o := OutNeighbours(digraph);
697+
for i in [1..Length(o)] do
698+
for j in [1..Length(o[i])] do
699+
if o[i][j] in rootNodes then
700+
mutableWeights[i][j] := infinity;
701+
fi;
702+
od;
703+
od;
704+
return EdgeWeightedDigraph(digraph, mutableWeights);
705+
end;
706+
707+
DIGRAPHS_NextShortestPath := function(iter)
708+
local currentShortestPath, currentShortestPathLength, spurNode, rootPath,
709+
rootPathNode, modifiedGraph, foundPaths, i, p, spurPath, totalPath,
710+
nextPath, mutableWeights, mutableOuts, rootNodes, j, o;
711+
712+
currentShortestPath := Last(iter.foundPaths);
713+
currentShortestPathLength := Length(currentShortestPath[1]);
714+
foundPaths := iter.foundPaths;
715+
716+
for i in [1 .. currentShortestPathLength] do
717+
spurNode := currentShortestPath[1][i];
718+
rootPath := [
719+
currentShortestPath[1]{[1..i]},
720+
currentShortestPath[2]{[1..i-1]}
721+
];
722+
723+
modifiedGraph := DIGRAPHS_ModifyGraph(digraph, rootPath, iter.foundPaths);
724+
spurPath := EdgeWeightedDigraphShortestPath(modifiedGraph, spurNode, dest);
725+
726+
if spurPath <> fail then
727+
totalPath := DIGRAPHS_ConcatenatePaths(rootPath, spurPath);
728+
Push(iter.candidatePaths, totalPath);
681729
fi;
730+
od;
731+
732+
if IsEmpty(iter.candidatePaths) then
733+
return fail;
734+
fi;
682735

683-
nextPath := Pop(iter.candidatePaths);
684-
Push(iter.foundPaths, nextPath);
736+
nextPath := Pop(iter.candidatePaths);
737+
Add(iter.foundPaths, nextPath);
685738

686-
return nextPath;
687-
end;
739+
return nextPath;
740+
end;
688741

689-
return findNextPath(currentIterator);
742+
InstallGlobalFunction(DIGRAPHS_ShortestPathsIterator,
743+
function(digraph, source, dest)
744+
ErrorNoReturn("Not implemented yet");
690745
end);

tst/standard/weights.tst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ gap> EdgeWeightedDigraphShortestPath(d, 1, 3);
274274
275275
# K Shortest Paths
276276
gap> d := EdgeWeightedDigraph([[2], [3], [4], []], [[1], [1], [1], []]);
277+
<immutable digraph with 4 vertices, 3 edges>
277278
gap> shortest_path := EdgeWeightedDigraphShortestPath(d, 1, 4);
278279
[ [ 1, 2, 3, 4 ], [ 1, 1, 1 ] ]
279280
gap> iter := DIGRAPHS_ShortestPathsIterator(d, 1, 4);

0 commit comments

Comments
 (0)