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
.
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
-tight if and only if is in the shortest path tree rooted at
.
per pivot.
throughout the algorithm, the tree we construct will always be a shortest-path tree.
is at most the number of darts.
[cite:;taken from @graph_klein_2024 corollary 7.4.2]
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.
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.
[cite:;taken from @graph_klein_2024 chapter 7 multiple-source shortest paths]to resolve this difficulty, we use a simple implicit representation of the shortest-path trees. let
/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
, 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.
transforming
- 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.
/home/mahmooz/brain/pen/1734861345.51882.xopp
[cite:;taken from @graph_klein_2024 chapter 7.2.1 pivots]
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]
[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 [cite:;taken from @graph_klein_2024 lemma 7.3.1]
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]
for each dart
[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 [cite:;taken from @graph_klein_2024 corollary 7.3.3]
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]
[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]
[cite:;taken from @graph_klein_2024 lemma 7.4.1]
[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
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
:
[cite:;taken from @graph_klein_2024 chapter 7.5 changeroot: the inner loop of the mssp algorithm]
/home/mahmooz/brain/pen/1734868601.2591472.xopp
consider
a procedure
in each iteration, the algorithm determines that a dart
- removing from
the dart whose head is
and
- adding
to
.
after the initialization, the procedure uses a variable
after initialization, the procedure
- increase
until any further increase would result in some dart
becoming tense with respect to
and
.
- pivot
into
.
[cite:;taken from @graph_klein_2024 chapter 7.5 changeroot: the inner loop of the mssp algorithm]
by having that the initial value of the dart in the special pivot is
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 [cite:;taken from @graph_klein_2024 lemma 7.5.1]
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
:
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:
hasnt yet returned to its original cost.
- 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
.
- 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
.
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]
[cite:;refer to @graph_klein_2024 chapter 7.9 using the output of the mssp algorithm]