@@ -616,3 +616,75 @@ function(digraph, source)
616
616
617
617
return rec (distances := distances, parents := parents, edges := edges);
618
618
end );
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