@@ -622,69 +622,124 @@ end);
622
622
# ############################################################################
623
623
#
624
624
# returns an iterator that generates the (possibly empty) sequence of paths
625
- # between source and dest
625
+ # between source and dest by increasing weight.
626
626
#
627
627
# the iterator needs to store
628
628
# - found paths
629
629
# - candidates
630
- # -
630
+ # - reference to the digraph
631
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
632
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;
671
635
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 ;
675
639
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 ;
677
692
od ;
678
693
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);
681
729
fi ;
730
+ od ;
731
+
732
+ if IsEmpty(iter.candidatePaths) then
733
+ return fail ;
734
+ fi ;
682
735
683
- nextPath := Pop(iter.candidatePaths);
684
- Push (iter.foundPaths, nextPath);
736
+ nextPath := Pop(iter.candidatePaths);
737
+ Add (iter.foundPaths, nextPath);
685
738
686
- return nextPath;
687
- end ;
739
+ return nextPath;
740
+ end ;
688
741
689
- return findNextPath(currentIterator);
742
+ InstallGlobalFunction(DIGRAPHS_ShortestPathsIterator,
743
+ function (digraph, source, dest )
744
+ ErrorNoReturn(" Not implemented yet" );
690
745
end );
0 commit comments