@@ -616,3 +616,75 @@ function(digraph, source)
616616
617617 return rec (distances := distances, parents := parents, edges := edges);
618618end );
619+
620+ # ############################################################################
621+ # 4. Shortest Paths Iterator
622+ # ############################################################################
623+ #
624+ # returns an iterator that generates the (possibly empty) sequence of paths
625+ # between source and dest
626+ #
627+ # the iterator needs to store
628+ # - found paths
629+ # - candidates
630+ # -
631+ # 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 ;
665+
666+ for rootPathNode in rootPath[ 1 ] do
667+ if rootPathNode <> spurNode then
668+ # remove rootPathNode from Graph;
669+ fi ;
670+ od ;
671+
672+ spurPath := EdgeWeightedDigraphShortestPath(modifiedGraph, spurNode, dest);
673+ totalPath := [ Concatenation(rootPath[ 1 ] , spurPath[ 1 ] ),
674+ Concatenation(rootPath[ 2 ] , spurPath[ 2 ] ) ] ;
675+
676+ Push(iter.candidatePaths, totalPath);
677+ od ;
678+
679+ if IsEmpty(iter.candidatePaths) then
680+ return fail ;
681+ fi ;
682+
683+ nextPath := Pop(iter.candidatePaths);
684+ Push(iter.foundPaths, nextPath);
685+
686+ return nextPath;
687+ end ;
688+
689+ return findNextPath(currentIterator);
690+ end );
0 commit comments