multiple-source shortest paths

  • input: a directed planar embedded graph with a desginated infinite face , a vector assigning lengths to darts, and a shortest-path tree rooted at one of the vertices of .
  • output: a representation of the shortest-path trees rooted at the vertices on the boundary of .
our goal is to give an algorithm that solves this problem in time where is the number of vertices (assuming no parallel edges).
there is an obvious obstacle: each shortest-path tree consists of edges, so explicitly outputting one for each of the possibly many vertices on the boundary of could take far more than time.
to resolve this difficulty, we use a simple implicit representation of the shortest-path trees. let be the cycle of darts forming the boundary of where is the root of the given shortest-path tree (see [[blk:fig-mssp-4]]). for , let be the shortest-path tree rooted at . we assume that each shortest-path tree includes only finite-length darts. the algorithm will describe the changes required to transform into , the changes needed to transform into ,..., and the changes needed to transform into . we will show that the total number of changes is at most the number of finite-length darts of .
/home/mahmooz/brain/pen/1734701863.0895941.xopp
the basic unit of change in a rooted tree , called a pivot, consists of ejecting one dart and inserting another dart so that the result is again a rooted tree. a pivot is specified by the pair of darts.
transforming from to consists of
  • a special pivot that ejects the dart whose head is (from [[blk:fig-mssp-4]]), and inserts the dart (now is -rooted)) (this is shown in [[blk:fig-mssp-1]]), and
  • a sequence of ordinary pivots each of which ejects a dart and inserts a dart with the same head.
for , the MSSP algorithm outputs the sequence of pivots that transform into . we shall show that the amortized time per pivot is . the number of special pivots is . we also show that the number of ordinary pivots is at most the number of finite-length darts. it follows that the running time is .
/home/mahmooz/brain/pen/1734861345.51882.xopp
[cite:;taken from @graph_klein_2024 chapter 7.2.1 pivots]
to faciliate the exposition we first consider the non-degenerate case, where shortest paths are unique.
let be a graph, let be a dart vector, and let be a dart. for a vertex , we say is -tight with respect to if is tight with respect to the from- distance vector with respect to .
[cite:;taken from @graph_klein_2024 lemma 7.3 contiguity property of shortest-path trees in planar graphs]
there is a -rooted shortest-path tree containing iff is -tight.
[cite:;taken from @graph_klein_2024 lemma 7.3.1]
note that our unique shortest-paths assumption implies that a dart is -tight if and only if is in the shortest path tree rooted at .
let be a planar embedded graph with infinite face , and let be a dart vector. let be the cycle of darts forming the boundary of .
for each dart , the set
forms a consecutive subsequence of the cycle .
[cite:;taken from @graph_klein_2024 lemma 7.3.2]
the number of pivots required to transform shortest-path tree into , summed over all , is at most the number of finite-length darts.
[cite:;taken from @graph_klein_2024 corollary 7.3.3]
we also need to show how using specific data structures we can find the necessary pivots and apply them in an amortized time of per pivot.
throughout the algorithm, the tree we construct will always be a shortest-path tree.
for each dart , there is at most one iteration such that .
[cite:;taken from @graph_klein_2024 lemma 7.4.1]
by the consecutive-roots lemma, there is at most one integer such that is in but is not in .
[cite:;taken from @graph_klein_2024 lemma 7.4.1]
is at most the number of darts.
[cite:;taken from @graph_klein_2024 corollary 7.4.2]
we describe how to move from , the tree rooted at , to , the tree rooted at , while maintaining a shortest-path tree.
consider , this is a shortest-path tree for , let denote the distance from to . to convert to a tree rooted at , we insert into the tree the dart and throw out the dart in whose head is . the tree we receive will not be a shortest-path tree for , but if we modify the length of the dart to be , it will become a shortest-path tree. this is demonstrated in [[blk:fig-mssp-1]].
a procedure called in the algorithm consists of a loop, each iteration of which selects a dart to add to and a dart to remove from . we show later that setting up the loop takes time, the number of iterations is , and each iteration takes amortized time. the time for is therefore . summing over all and using cor-mssp-1, we infer that the total time for and therefore for MSSP is .
in each iteration, the algorithm determines that a dart not in must be added to . it then pivots into , which means
  • removing from the dart whose head is and
  • adding to .
conceptually, is as follows. let denote the -to- distance in . to initialize, temporarily sets the cost of the dart to . it then performs a special pivot, removing from the dart whose head is , and inserting into . it then gradually increases the cost of to its original cost while performing ordinary pivots as necessary to maintain that is a shortest-path tree.
after the initialization, the procedure uses a variable to represent the current modified cost of . the costs of other darts remain unmodified. let denote the vector of costs. that is,
under these costs, the cost of the path in to a vertex is denoted . the vector is not represented explicitly by the algorithm; we use it in the analysis and proof of correctness.
after initialization, the procedure repeats the following two steps until equals the original cost of :
  • increase until any further increase would result in some dart becoming tense with respect to and .
  • pivot into .
this operation is demonstrated in [[blk:fig-mssp-3]].
[cite:;taken from @graph_klein_2024 chapter 7.5 changeroot: the inner loop of the mssp algorithm]
/home/mahmooz/brain/pen/1734868601.2591472.xopp
by having that the initial value of the dart in the special pivot is , its as if we never moved from to in terms of distances from to other nodes, so the tree will be a shortest-path tree still (with respect to both and ), but we need to gradually increase while conducting normal pivots.
throughout the execution, is a shortest-path tree with respect to the costs .
[cite:;taken from @graph_klein_2024 lemma 7.5.1]
the algorithm pivots in a dart only if necessary, i.e. if continuing the shrinking or growing phase without pivoting in would result in not being a shortest-path tree, in particular if would become tense with respect to and . a dart is in danger of becoming tense only if its slack cost with respect to is decreasing.
how do we know which darts need to be inserted into and when? we check the length of every dart not in , how much longer the path is than ( denotes the path from the root to in ). this difference in length we call the slack of with respect to , and denote it by where denotes the length of the path :
when we add to the cost of , we consider what happens to :
  • if and are descendants of in , the slack doesnt change,
  • if and arent descendants of in , the slack doesnt change,
  • if is a descendant of and isnt, the slack increases by ,
  • if isnt a descendant of and is a descendant of , the slack decreases by .
we shift into the tree when its slack becomes cost becomes 0. since is a shortest-path tree, the slack cost of every edge that isnt in isnt negative, thus it suffices to keep track of the edges whose tails are in the subtree of and whose heads are in the subtree of . those are exactly the edges in the fundamental cycle of with respect to . in other words, these are the edges in the path from the face to the face . all we have to do (if at all), is to track the slack costs of the edges in the path from to in , all those edges arent in , which means they are in . the slack of all of those edges decreases by when we increase the length of by , thus the first dart whose slack cost reaches 0 is the the dart with minimal slack cost, hence to apply a pivot we need to:
  • find the dart whose slack cost in minimal in the path from to in . let be the dart, and be its slack cost,
  • subtract from the slack cost of all the darts in (on the path from to ), add to the slack cost of all darts in (on the path from to ), an add to the length of the dart .
  • remove the edge of whose head is from and insert into .
this process needs to be applied as long as hasnt yet returned to its original cost.
[cite:;taken from @graph_klein_2024 chapter 7 multiple-source shortest paths]
we can build a data structure for mssp that answers queries from a boundary vertex to any other vertex in time, where is the length of the shortest path to the destination vertex.
[cite:;refer to @graph_klein_2024 chapter 7.9 using the output of the mssp algorithm]