Transcript [ppt]

Nondecreasing Paths in
Weighted Graphs
Or: How to optimally read a
train schedule
Virginia Vassilevska
Traveling?
Tomorrow after 8am
As early as possible!
Nondecreasing Paths in
Weighted Graphs
Or: How to optimally read a
train schedule
flight
Virginia Vassilevska
Routes with Multiple Stops
New York
London
Newark
Frankfurt
7pm – 1:20pm
5:30pm – 10:40am
Scheduling



You might need to make several
connections.
There are multiple possible stopover
points, and multiple possible
schedules.
How do you choose which segments
to combine?
Talk Overview

Graph-theoretic abstraction

History

Two algorithms

Improved algorithm, linear time
Graph-Theoretic Abstraction
…
New York
London
6*pm
2:20*pm
1:20*pm
Newark
Frankfurt
Nondecreasing
Graph:
(Origin,
(flight,
A vertex
departure
arrival
Destination)
path
time
flight)
for
time
with
weight;
each
edges;
weight;
minimum
city;
flight;
edges; last edge?
Versions of the problem
Single source – single destination
Single source (every destination)
All pairs
S
We’ll focus on single source
T
SSNP.
History

G. Minty 1958: graph abstraction and
first algorithm for SSNP – polytime

E. F. Moore 1959: a new algorithm for
shortest paths, and SSNP – cubic time
History


Dijkstra 1959
Fredman and Tarjan 1987 – Fibonacci
Heaps implementation of Dijkstra’s; until
now asymptotically fastest algorithm for
SSNP. O(m+n log n) m – number of edges
n – number of vertices

Nowadays – experimental research on
improving Dijkstra’s algorithm
implementation
Fibonacci Heaps
Fredman and Tarjan’s Fibonacci heaps:

Maintain a set of elements with weights d[·]

Insert element v with d[v] = ∞ in constant time

Update the weight d[v] of an element v in
constant time

Return and remove the element v of
minimum weight d[v] in O(log N) time where
N is the number of elements
Dijkstra’s Algorithm for SSNP

Maintain conservative “distance”
estimates for all vertices;

d[S] = -, d[v] =  for all other v

U contains vertices with undetermined
distances. Use Fibonacci Heaps!

Vertices outside of U are completed.
Dijkstra’s algorithm




Set U = V and T = { }. Iterate:
At each iteration, pick u from U
minimizing d[u].
T
d[u]
T = T U {u}, U = U \ {u}.
For all edges (u, v),
 If w(u,v) ≥ d[u],
set d[v] = min (d[v], w(u,v))
w(u,v)
min d[u]
S u
v
U
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
U - Fibonacci Heap:
S: -infinity
P: infinity
Q: infinity
a: infinity
b: infinity
c: infinity
d: infinity
3
2 P
2
5
d
3
Other Distances:
Example
U - Fibonacci Heap:
P: infinity
Q: infinity
a: 5
b: 1
c: 3
d: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
3
S – extract min from U
Example
U - Fibonacci Heap:
P: 2
Q: infinity
a: 5
c: 3
d: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
3
b – extract min from U
Example
U - Fibonacci Heap:
Q: 3
a: 3
c: 3
d: 2
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
P: 2
3
P – extract min from U
Example
U - Fibonacci Heap:
Q: 3
a: 2
c: 3
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
P: 2
d: 2
3
d – extract min from U
Example
U - Fibonacci Heap:
Q: 3
c: 2
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
P: 2
d: 2
a: 2
3
a – extract min from U
Example
U - Fibonacci Heap:
Q: 3
2
S
c
1
5
a
3
3
b
3
4
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
P: 2
d: 2
a: 2
c: 2
3
c – extract min from U
Example
U - Fibonacci Heap:
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
S: -infinity
b: 1
P: 2
d: 2
a: 2
c: 2
Q: 3
3
Q – extract min from U
Running time of Dijkstra

Inserting all n nodes in the Fibonacci
heap takes O(n) time.

Each d[v] update is due to some edge
(u, v), and each edge is touched at
most once.

d[v] updates take O(m) time overall.
Running time of Dijkstra

Every node removed from Fibonacci
heap at most once – at most n extractmins. This takes O(n log n) time overall.

Final runtime: O(m+n log n).

Optimal for Dijkstra’s algorithm – nodes
visited in sorted order of their distance.
More on Dijkstra’s

Suppose we only maintain F vertices in the
Fibonacci heaps. The rest we maintain in
some other way.
N(F)
F

Then the runtime due to the Fibonacci heaps
would be O(F log F + N(F)) where N(F) is the
number of edges pointing to the F vertices.

For F = m/log n, this is O(m)!
ALG2: Depth First Search
DFS(v, d[v]):
For all (v, u) with w(v, u) ≥ d[v]:
Remove (v, u) from graph.
d[u] = min (d[u], w(v,u))
DFS(u, d[u])
d[v]=2
v
1
3
3
u
d[u]=3
d[u]=4
d[S] = - ∞, start with DFS(S, d[S]).
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
3
Distances:
S: -infinity
P: infinity
Q: infinity
a: infinity
b: infinity
c: infinity
d: infinity
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: infinity
Q: infinity
a: infinity
b: 1
c: infinity
d: infinity
5
d
3
DFS(S, -infinity)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: infinity
a: infinity
b: 1
c: infinity
d: infinity
5
d
3
DFS(b, 1)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: infinity
a: infinity
b: 1
c: infinity
d: 2
5
d
3
DFS(P, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: infinity
a: 2
b: 1
c: infinity
d: 2
5
d
3
DFS(d, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: infinity
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(a, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: infinity
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(c, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(P, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(Q, 3)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(Q, 3)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(Q, 3)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(P, 2)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(S, -infinity)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(S, -infinity)
Example
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
Distances:
S: -infinity
P: 2
Q: 3
a: 2
b: 1
c: 2
d: 2
5
d
3
DFS(S, -infinity)
Runtime of DFS



The number of times we call
DFS(v, d[v]) for any particular v is at
most indegree(v).
Every such time we might have to
check all outedges (w(v,u)≥?d[v]).
Worst case running time:
Σv (indegree(v) × outdegree(v)) ≤
n Σv indegree(v) = O(mn).
More on DFS

The runtime can be improved!

Suppose for a node v and weight d[v]
we can access each edge (v, u) with
w(v, u)≥ d[v] in O(t) time.
As each edge is accessed at most
once, the runtime is O(m t).

DFS with Binary Search Trees


For each vertex v, insert outedges in
binary search tree sorted by weight.
Splay trees, treaps, AVL trees etc.
support the following on totally ordered
sets of size k in O(log k) time: 2



insert,
delete,
find, predecessor, successor
1
5
3
6
DFS with Binary Search Trees

Given any weight d[v], one can find an
edge (v, u) with w(v, u) ≥ d[v] in
O(log [deg(v)]) time.
Σv deg(v)=2m

All inserts in the beginning take
O(Σv deg(v) log [deg(v)]) = O(m log n)
time, and DFS takes O(m log n) time.
Combining Dijkstra with DFS

Recall:
If F nodes used in Fibonacci heaps, then
the runtime due to the heaps is
O(F log F + N(F)) ◄ O(m+n) for F = m/log n


If DFS with binary search trees is run on a
set of nodes T, the runtime is
O(Σv  T { deg(v) log (deg(v)) })
O(m log log n) for T = {v | deg(v)<log n}
Idea!



Run DFS on vertices of low degree < log n:
O(m log log n) time.
Put the rest in Fibonacci heaps and run
Dijkstra on them.
There are at most O(m/log n) high degree
nodes.
Time due to Fibonacci heaps: O(m).
We get O(m log log n). Better than
O(m+n log n) for m = o(n log n/log log n).
But we wanted linear time…
Fredman and Willard atomic heaps:
 After O(n) preprocessing, a collection
of O(n) sets of O(log n) size can be
maintained so that the following are in
constant time:

Insert

Delete

Given w, return an element of weight ≥ w.
Linear runtime



Replace binary trees by atomic heaps.
Time due to Dijkstra with Fibonacci Heaps
on O(m/log n) elements is still O(m).
Time due to DFS with atomic heaps:



inserting outedges into atomic heaps takes
constant time per edge;
given d[v], accessing an edge with w(v,u) ≥ d[v]
takes constant time.
O(m+n) time overall!
New Algorithm

Stage 1: Initialize

Find all vertices v of degree ≥ log n and
insert into Fibonacci Heaps with d[v] = ∞;
Insert S with d[S] = - ∞

For all vertices u of degree < log n, add
outedges into atomic heap sorted by
weights.
This stage takes O(m+n) time.

New Algorithm

Stage 2: Repeat:
1.
2.
3.
Extract vertex v from Fibonacci
heaps with minimum d[v]
For all neighbors u of v, if
w(u,v) ≥ d[v]:
1.
Update d[u] if w(v,u) < d[u]
2.
Run DFS(u, d[u]) on the graph
spanned by low degree vertices
until no more can be reached
If Fib.heaps nonempty, go to 1.
Fibonacci Heaps
2
3
4
1
5
4
4
Example
U - Fibonacci Heap:
S: -infinity
P: infinity
Q: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
3
Other Distances:
a: infinity
b: infinity
c: infinity
d: infinity
Example
U - Fibonacci Heap:
P: infinity
Q: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
a: 5
b: 1
c: 3
d: infinity
S: -infinity
3
S – extract min from U
Example
U - Fibonacci Heap:
P: 2
Q: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
a: 5
b: 1
c: 3
d: infinity
S: -infinity
3
DFS(b, 1)
Example
U - Fibonacci Heap:
P: 2
Q: infinity
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
a: 5
b: 1
c: 3
d: infinity
S: -infinity
3
DFS(a, 3)
DFS(c,
5)
Example
U - Fibonacci Heap:
Q: 3
2
S
c
1
5
a
3
3
4
3
b
2
Q
3
2 P
2
5
d
Other Distances:
a: 3
b: 1
c: 3
d: 2
S: -infinity
P: 2
3
P – extract min from U
Example
U - Fibonacci Heap:
Q: 3
2
S
c
1
5
a
3
b
3
4
3
2
Q
3
2 P
2
5
d
Other Distances:
a: 2
b: 1
c: 3
d: 2
S: -infinity
P: 2
3
DFS(d, 2)
Example
U - Fibonacci Heap:
Q: 3
2
S
c
1
5
a
3
b
3
4
3
2
Q
3
2 P
2
5
d
Other Distances:
a: 2
b: 1
c: 2
d: 2
S: -infinity
P: 2
3
DFS(a, 2)
Example
U - Fibonacci Heap:
Q: 3
2
S
c
1
5
a
3
b
3
4
3
2
Q
3
2 P
2
5
d
Other Distances:
a: 2
b: 1
c: 2
d: 2
S: -infinity
P: 2
3
DFS(c, 2)
DFS(a,
3)
Example
U - Fibonacci Heap:
2
S
c
1
5
a
3
3
b
3
4
2
Q
3
2 P
2
5
d
Other Distances:
a: 2
b: 1
c: 2
d: 2
S: -infinity
P: 2
Q: 3
3
Q – extract min from U
Summary



We gave the first linear time algorithm
for the single source nondecreasing
paths problem.
We did this by combining two known
algorithms, and by using clever data
structures.
Now you can read a train schedule
optimally!
Directions for future work



What about the all-pairs version of the
problem? That is, if we want to
schedule the best trips between any
two cities?
Naïve algorithm: apply linear time
algorithm for all possible sources –
O(mn) time, O(n3) in the worst case.
Can we do anything better? O(n2.9)?
Conclusion
With the aid of the right data structures
simple algorithms can be fast.
THANK YOU!