0% found this document useful (0 votes)
26 views66 pages

44 Shortest Paths

The document discusses algorithms for finding shortest paths in edge-weighted directed graphs. It describes APIs and data structures for representing graphs and computing single-source shortest paths from a given vertex to all other vertices. Common applications of shortest path algorithms are also listed.

Uploaded by

roberiogomes8998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views66 pages

44 Shortest Paths

The document discusses algorithms for finding shortest paths in edge-weighted directed graphs. It describes APIs and data structures for representing graphs and computing single-source shortest paths from a given vertex to all other vertices. Common applications of shortest path algorithms are also listed.

Uploaded by

roberiogomes8998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 66

Algorithms R OBERT S EDGEWICK | K EVIN W AYNE

4.4 S HORTEST P ATHS


‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs
F O U R T H E D I T I O N

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Shortest paths in an edge-weighted digraph

Given an edge-weighted digraph, find the shortest path from s to t.

edge-weighted digraph
4->5 0.35
5->4 0.35
4->7 0.37
5->7 0.28
7->5 0.28
5->1 0.32
0->4 0.38
0->2 0.26
7->3 0.39 shortest path from 0 to 6
1->3 0.29
0->2 0.26
2->7 0.34
2->7 0.34
6->2 0.40
7->3 0.39
3->6 0.52
3->6 0.52
6->0 0.58
6->4 0.93

An edge-weighted digraph and a shortest path

2
Google maps

3
Shortest path applications

・PERT/CPM.
・Map routing.
・Seam carving.
・Texture mapping.
・Robot navigation.
・Typesetting in TeX. http://en.wikipedia.org/wiki/Seam_carving

・Urban traffic planning.


・Optimal pipelining of VLSI chip.
・Telemarketer operator scheduling.
・Routing of telecommunications messages.
・Network routing protocols (OSPF, BGP, RIP).
・Exploiting arbitrage opportunities in currency exchange.
・Optimal truck routing through given traffic congestion pattern.
Reference: Network Flows: Theory, Algorithms, and Applications, R. K. Ahuja, T. L. Magnanti, and J. B. Orlin, Prentice Hall, 1993.

4
Shortest path variants

Which vertices?
・Single source: from one vertex s to every other vertex.
・Single sink: from every vertex to one vertex t.
・Source-sink: from one vertex s to another t.
・All pairs: between all pairs of vertices.
Restrictions on edge weights?
・Nonnegative weights.
・Euclidean weights.
・Arbitrary weights.
Cycles?
・No directed cycles.
・No "negative cycles." which variant?

Simplifying assumption. Shortest paths from s to each vertex v exist.


5
4.4 S HORTEST P ATHS
‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Weighted directed edge API

public class DirectedEdge

DirectedEdge(int v, int w, double weight) weighted edge v→w

int from() vertex v

int to() vertex w

double weight() weight of this edge

String toString() string representation

weight
v w

Idiom for processing an edge e: int v = e.from(), w = e.to();

7
Weighted directed edge: implementation in Java

Similar to Edge for undirected graphs, but a bit simpler.

public class DirectedEdge


{
private final int v, w;
private final double weight;

public DirectedEdge(int v, int w, double weight)


{
this.v = v;
this.w = w;
this.weight = weight;
}

public int from()


from() and to() replace
{ return v; }
either() and other()

public int to()


{ return w; }

public int weight()


{ return weight; }
}

8
Edge-weighted digraph API

public class EdgeWeightedDigraph

EdgeWeightedDigraph(int V) edge-weighted digraph with V vertices

EdgeWeightedDigraph(In in) edge-weighted digraph from input stream

void addEdge(DirectedEdge e) add weighted directed edge e

Iterable<DirectedEdge> adj(int v) edges pointing from v

int V() number of vertices

int E() number of edges

Iterable<DirectedEdge> edges() all edges

String toString() string representation

Conventions. Allow self-loops and parallel edges.


9
Edge-weighted digraph: adjacency-lists representation

tinyEWD.txt
V 0 2 .26 0 4 .38
8 E
15
4 5 0.35 1 3 .29
adj
5 4 0.35
0
4 7 0.37 2 7 .34 Bag objects
5 7 0.28 1
7 5 0.28 2
5 1 0.32 3 6 .52 reference to a
3 DirectedEdge
0 4 0.38
0 2 0.26 4 object
4 7 .37 4 5 .35
7 3 0.39 5
1 3 0.29
6
2 7 0.34 5 1 .32 5 7 .28 5 4 .35
6 2 0.40 7
3 6 0.52
6 4 .93 6 0 .58 6 2 .40
6 0 0.58
6 4 0.93
7 3 .39 7 5 .28

Edge-weighted digraph representation

10
Edge-weighted digraph: adjacency-lists implementation in Java

Same as EdgeWeightedGraph except replace Graph with Digraph.

public class EdgeWeightedDigraph


{
private final int V;
private final Bag<DirectedEdge>[] adj;

public EdgeWeightedDigraph(int V)
{
this.V = V;
adj = (Bag<DirectedEdge>[]) new Bag[V];
for (int v = 0; v < V; v++)
adj[v] = new Bag<DirectedEdge>();
}

public void addEdge(DirectedEdge e)


{
int v = e.from(); add edge e = v→w to
adj[v].add(e); only v's adjacency list
}

public Iterable<DirectedEdge> adj(int v)


{ return adj[v]; }
}
11
Single-source shortest paths API

Goal. Find the shortest path from s to every other vertex.

public class SP

SP(EdgeWeightedDigraph G, int s) shortest paths from s in graph G

double distTo(int v) length of shortest path from s to v

Iterable <DirectedEdge> pathTo(int v) shortest path from s to v

boolean hasPathTo(int v) is there a path from s to v?

SP sp = new SP(G, s);


for (int v = 0; v < G.V(); v++)
{
StdOut.printf("%d to %d (%.2f): ", s, v, sp.distTo(v));
for (DirectedEdge e : sp.pathTo(v))
StdOut.print(e + " ");
StdOut.println();
}

12
Single-source shortest paths API

Goal. Find the shortest path from s to every other vertex.

public class SP

SP(EdgeWeightedDigraph G, int s) shortest paths from s in graph G

double distTo(int v) length of shortest path from s to v

Iterable <DirectedEdge> pathTo(int v) shortest path from s to v

boolean hasPathTo(int v) is there a path from s to v?

% java SP tinyEWD.txt 0
0 to 0 (0.00):
0 to 1 (1.05): 0->4 0.38 4->5 0.35 5->1 0.32
0 to 2 (0.26): 0->2 0.26
0 to 3 (0.99): 0->2 0.26 2->7 0.34 7->3 0.39
0 to 4 (0.38): 0->4 0.38
0 to 5 (0.73): 0->4 0.38 4->5 0.35
0 to 6 (1.51): 0->2 0.26 2->7 0.34 7->3 0.39 3->6 0.52
0 to 7 (0.60): 0->2 0.26 2->7 0.34

13
4.4 S HORTEST P ATHS
‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Data structures for single-source shortest paths

Goal. Find the shortest path from s to every other vertex.

Observation. A shortest-paths tree (SPT) solution exists. Why?

Consequence. Can represent the SPT with two vertex-indexed arrays:


・ distTo[v] is length of shortest path from s to v.
・ edgeTo[v] is last edge on shortest path from s to v.
edgeTo[] distTo[]
edgeTo[] distTo[]
0 null 0
0 null 0
1 1 5->1
5->10.32
0.32 1.05
1.05
2 2 0->2
0->20.26
0.26 0.26
0.26
3 3 7->3
7->30.37
0.37 0.97
0.97
4 4 0->4
0->40.38
0.38 0.38
0.38
5 5 4->5
4->50.35
0.35 0.73
0.73
6 3->6 0.52 1.49
6 3->6 0.52 1.49
7 2->7 0.34 0.60
7 2->7 0.34 0.60
Shortest paths data structures
Shortest
shortest-paths tree frompaths
0 data structures
parent-link representation

15
Data structures for single-source shortest paths

Goal. Find the shortest path from s to every other vertex.

Observation. A shortest-paths tree (SPT) solution exists. Why?

Consequence. Can represent the SPT with two vertex-indexed arrays:


・ distTo[v] is length of shortest path from s to v.
・ edgeTo[v] is last edge on shortest path from s to v.
public double distTo(int v)
{ return distTo[v]; }

public Iterable<DirectedEdge> pathTo(int v)


{
Stack<DirectedEdge> path = new Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()])
path.push(e);
return path;
}

16
Edge relaxation

Relax edge e = v→w.


・ distTo[v] is length of shortest known path from s to v.
・ distTo[w] is length of shortest known path from s to w.
・ edgeTo[w] is last edge on shortest known path from s to w.
・If e = v→w gives shorter path to w through v,
update both distTo[w] and edgeTo[w].

v→w successfully relaxes

v 3.1

1.3
s

w 7.2 4.4

black edges
are in edgeTo[]

17
Edge relaxation

Relax edge e = v→w.


・ distTo[v] is length of shortest known path from s to v.
・ distTo[w] is length of shortest known path from s to w.
・ edgeTo[w] is last edge on shortest known path from s to w.
・If e = v→w gives shorter path to w through v,
update both distTo[w] and edgeTo[w].

private void relax(DirectedEdge e)


{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
}
}

18
Shortest-paths optimality conditions

Proposition. Let G be an edge-weighted digraph.


Then distTo[] are the shortest path distances from s iff:
・distTo[s] = 0.
・For each vertex v, distTo[v] is the length of some path from s to v.
・For each edge e = v→w, distTo[w] ≤ distTo[v] + e.weight().
Pf. ⇐ [ necessary ]
・Suppose that distTo[w] > distTo[v] + e.weight() for some edge e = v→w.
・Then, e gives a path from s to w (through v) of length less than distTo[w].
v 3.1 distTo[v]

1.3
s

w 7.2 distTo[w]

19
Shortest-paths optimality conditions

Proposition. Let G be an edge-weighted digraph.


Then distTo[] are the shortest path distances from s iff:
・distTo[s] = 0.
・For each vertex v, distTo[v] is the length of some path from s to v.
・For each edge e = v→w, distTo[w] ≤ distTo[v] + e.weight().
Pf. ⇒ [ sufficient ]
・Suppose that s = v → v → v → … → v = w is a shortest path from s to w.
0 1 2 k

・Then, distTo[v ] ≤ distTo[v ] + e .weight()


1 0 1
ei = ith edge on shortest
distTo[v2] ≤ distTo[v1] + e2.weight() path from s to w
...
distTo[vk] ≤ distTo[vk-1] + ek.weight()

・Add inequalities; simplify; and substitute distTo[v ] = 0 distTo[s] = 0:


distTo[w] = distTo[vk] ≤ e1.weight() + e2.weight() + … + ek.weight()
weight of shortest path from s to w

・Thus, distTo[w] is the weight of shortest path to w. !

weight of some path from s to w 20


Generic shortest-paths algorithm

Generic algorithm (to compute SPT from s)

Initialize distTo[s] = 0 and distTo[v] = ∞ for all other vertices.

Repeat until optimality conditions are satisfied:


- Relax any edge.

Proposition. Generic algorithm computes SPT (if it exists) from s.


Pf sketch.
・The entry distTo[v] is always the length of a simple path from s to v.
・Each successful relaxation decreases distTo[v] for some v.
・The entry distTo[v] can decrease at most a finite number of times. !

21
Generic shortest-paths algorithm

Generic algorithm (to compute SPT from s)

Initialize distTo[s] = 0 and distTo[v] = ∞ for all other vertices.

Repeat until optimality conditions are satisfied:


- Relax any edge.

Efficient implementations. How to choose which edge to relax?


Ex 1. Dijkstra's algorithm (nonnegative weights).
Ex 2. Topological sort algorithm (no directed cycles).
Ex 3. Bellman-Ford algorithm (no negative cycles).

22
4.4 S HORTEST P ATHS
‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Edsger W. Dijkstra: select quotes

“ Do only what only you can do. ”

“ In their capacity as a tool, computers will be but a ripple on the


surface of our culture. In their capacity as intellectual challenge,
they are without precedent in the cultural history of mankind. ”

“ The use of COBOL cripples the mind; its teaching should,


Edsger W. Dijkstra
therefore, be regarded as a criminal offence. ” Turing award 1972

“ It is practically impossible to teach good programming to


students that have had a prior exposure to BASIC: as potential
programmers they are mentally mutilated beyond hope of
regeneration. ”

“ APL is a mistake, carried through to perfection. It is the


language of the future for the programming techniques
of the past: it creates a new generation of coding bums. ”
24
Edsger W. Dijkstra: select quotes

25
Dijkstra's algorithm demo

・Consider vertices in increasing order of distance from s


(non-tree vertex with the lowest distTo[] value).
・Add vertex to tree and relax all edges pointing from that vertex.
1 3 0→1 5.0
15
0→4 9.0
5
4 0→7 8.0
12
s 0 3 1→2 12.0
8 1→3 15.0
7 2 9
7 1→7 4.0
9 2→3 3.0
6 1
11 2→6 11.0
5
5 3→6 9.0
4 13 4→5 4.0
4→6 20.0
4 20 6
4→7 5.0
5→2 1.0
5→6 13.0
an edge-weighted digraph 7→5 6.0
7→2 7.0
26
Dijkstra's algorithm demo

・Consider vertices in increasing order of distance from s


(non-tree vertex with the lowest distTo[] value).
・Add vertex to tree and relax all edges pointing from that vertex.
1 3
v distTo[] edgeTo[]
0 0.0 -
s 0 1 5.0 0→1
2 14.0 5→2
7 2 3 17.0 2→3
4 9.0 0→4
5 13.0 4→5
5 6 25.0 2→6
7 8.0 0→7

4 6

shortest-paths tree from vertex s

27
Dijkstra's algorithm visualization

28
Dijkstra's algorithm visualization

29
Dijkstra's algorithm: correctness proof

Proposition. Dijkstra's algorithm computes a SPT in any edge-weighted


digraph with nonnegative weights.

Pf.
・Each edge e = v→w is relaxed exactly once (when vertex v is relaxed),
leaving distTo[w] ≤ distTo[v] + e.weight().
・Inequality holds until algorithm terminates because:
– distTo[w] cannot increase distTo[] values are monotone decreasing

– distTo[v] will not change we choose lowest distTo[] value at each step
(and edge weights are nonnegative)

・Thus, upon termination, shortest-paths optimality conditions hold. !

30
Dijkstra's algorithm: Java implementation

public class DijkstraSP


{
private DirectedEdge[] edgeTo;
private double[] distTo;
private IndexMinPQ<Double> pq;

public DijkstraSP(EdgeWeightedDigraph G, int s)


{
edgeTo = new DirectedEdge[G.V()];
distTo = new double[G.V()];
pq = new IndexMinPQ<Double>(G.V());

for (int v = 0; v < G.V(); v++)


distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;

pq.insert(s, 0.0); relax vertices in order


while (!pq.isEmpty()) of distance from s
{
int v = pq.delMin();
for (DirectedEdge e : G.adj(v))
relax(e);
}
}
}
31
Dijkstra's algorithm: Java implementation

private void relax(DirectedEdge e)


{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.decreaseKey(w, distTo[w]); update PQ
else pq.insert (w, distTo[w]);
}
}

32
Dijkstra's algorithm: which priority queue?

Depends on PQ implementation: V insert, V delete-min, E decrease-key.

PQ implementation insert delete-min decrease-key total

unordered array 1 V 1 V2

binary heap log V log V log V E log V

d-way heap logd V d logd V logd V E logE/V V

Fibonacci heap 1† log V † 1† E + V log V

† amortized

Bottom line.
・Array implementation optimal for dense graphs.
・Binary heap much faster for sparse graphs.
・4-way heap worth the trouble in performance-critical situations.
・Fibonacci heap best in theory, but not worth implementing.
33
Computing a spanning tree in a graph

Dijkstra's algorithm seem familiar?


・Prim's algorithm is essentially the same algorithm.
・Both are in a family of algorithms that compute a spanning tree.
Main distinction: Rule used to choose next vertex for the tree.
・Prim: Closest vertex to the tree (via an undirected edge).
・Dijkstra: Closest vertex to the source (via a directed path).

Note: DFS and BFS are also in this family of algorithms.


34
4.4 S HORTEST P ATHS
‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Acyclic edge-weighted digraphs

Q. Suppose that an edge-weighted digraph has no directed cycles.


Is it easier to find shortest paths than in a general digraph?

1 15 3

5
4
12
s 0 3
8
7 2 9
7

9 6 1
11
5
5
4 13

4 20 6

A. Yes!
36
Acyclic shortest paths demo

・Consider vertices in topological order.


・Relax all edges pointing from that vertex.

0→1 5.0
1 15 3
0→4 9.0
5 0→7 8.0
4
12 1→2 12.0
s 0 3
8 1→3 15.0
7 2 9 1→7 4.0
7
2→3 3.0
9 6 1 2→6 11.0
11
5 3→6 9.0
5
4→5 4.0
4 13
4→6 20.0
4 20 6 4→7 5.0
5→2 1.0
5→6 13.0
an edge-weighted DAG 7→5 6.0
7→2 7.0
37
Acyclic shortest paths demo

・Consider vertices in topological order.


・Relax all edges pointing from that vertex.
0 1 4 7 5 2 3 6

1 3
v distTo[] edgeTo[]
0 0.0 -
s 0 1 5.0 0→1
2 14.0 5→2
7 2 3 17.0 2→3
4 9.0 0→4
5 13.0 4→5
5 6 25.0 2→6
7 8.0 0→7

4 6

shortest-paths tree from vertex s

38
Shortest paths in edge-weighted DAGs

Proposition. Topological sort algorithm computes SPT in any edge-


weighted DAG in time proportional to E + V.
edge weights
can be negative!

Pf.
・Each edge e = v→w is relaxed exactly once (when vertex v is relaxed),
leaving distTo[w] ≤ distTo[v] + e.weight().
・Inequality holds until algorithm terminates because:
– distTo[w] cannot increase distTo[] values are monotone decreasing

– distTo[v] will not change because of topological order, no edge pointing to v


will be relaxed after v is relaxed

・Thus, upon termination, shortest-paths optimality conditions hold. !

39
Shortest paths in edge-weighted DAGs

public class AcyclicSP


{
private DirectedEdge[] edgeTo;
private double[] distTo;

public AcyclicSP(EdgeWeightedDigraph G, int s)


{
edgeTo = new DirectedEdge[G.V()];
distTo = new double[G.V()];

for (int v = 0; v < G.V(); v++)


distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;

Topological topological = new Topological(G); topological order


for (int v : topological.order())
for (DirectedEdge e : G.adj(v))
relax(e);
}
}

40
Content-aware resizing

Seam carving. [Avidan and Shamir] Resize an image without distortion for
display on cell phones and web browsers.

http://www.youtube.com/watch?v=vIFCV2spKtg
41
Content-aware resizing

Seam carving. [Avidan and Shamir] Resize an image without distortion for
display on cell phones and web browsers.

In the wild. Photoshop CS 5, Imagemagick, GIMP, ...


42
Content-aware resizing

To find vertical seam:


・Grid DAG: vertex = pixel; edge = from pixel to 3 downward neighbors.
・Weight of pixel = energy function of 8 neighboring pixels.
・Seam = shortest path (sum of vertex weights) from top to bottom.

43
Content-aware resizing

To find vertical seam:


・Grid DAG: vertex = pixel; edge = from pixel to 3 downward neighbors.
・Weight of pixel = energy function of 8 neighboring pixels.
・Seam = shortest path (sum of vertex weights) from top to bottom.
seam

44
Content-aware resizing

To remove vertical seam:


・Delete pixels on seam (one in each row).

seam

45
Content-aware resizing

To remove vertical seam:


・Delete pixels on seam (one in each row).

46
Longest paths in edge-weighted DAGs

Formulate as a shortest paths problem in edge-weighted DAGs.


・Negate all weights.
・Find shortest paths. equivalent: reverse sense of equality in relax()

・Negate weights in result.

longest paths input shortest paths input


5->4 0.35 5->4 -0.35
4->7 0.37 4->7 -0.37
5->7 0.28 5->7 5->4
-0.28-0.35
s
5->1 0.32 5->1 4->7
-0.32-0.37
4->0 0.38 4->0 5->7
-0.38-0.28
0->2 0.26 0->2 5->1
-0.26-0.32
3->7 0.39 3->7 -0.39
4->0 -0.38
1->3 0.29 1->3 -0.29
0->2 -0.26
7->2 0.34 7->2 -0.34
6->2 0.40 6->2 3->7
-0.40-0.39
3->6 0.52 3->6 1->3
-0.52-0.29
6->0 0.58 6->0 7->2
-0.58-0.34
6->4 0.93 6->4 6->2
-0.93-0.40
3->6 -0.52
6->0 -0.58
6->4 -0.93

Key point. Topological sort algorithm works even with negative weights.
47
Longest paths in edge-weighted DAGs: application

Parallel job scheduling. Given a set of jobs with durations and precedence
constraints, schedule the jobs (by finding a start time for each) so as to
achieve the minimum completion time, while respecting the constraints.

job duration must complete


before
0 41.0 1 7 9
1 51.0 2
2 50.0
3 36.0
4 38.0
1
5 45.0
7 3
6 21.0 3 8
0 9 6 8 2
7 32.0 3 8
5 4
8 32.0 2
9 29.0 4 6 0 41 70 91 123 173

A job scheduling problem Parallel job scheduling solution

48
Critical path method

CPM. To solve a parallel job-scheduling problem, create edge-weighted DAG:


・Source and sink vertices. job duration must complete

・Two vertices (begin and end) for each job. 0 41.0 1


before
7 9

・Three edges for each job. 1


2
51.0
50.0
2

– begin to end (weighted by duration) 3 36.0


4 38.0
– source to begin (0 weight) 5 45.0
6 21.0 3 8
– end to sink (0 weight) 7 32.0 3 8

・One edge for each precedence constraint (0 weight).


8 32.0 2
9 29.0 4 6
A job scheduling problem

job start job finish precedence constraint


51 (zero weight)
41 1 1
0 0
50
32 32
2 2
duration 7 7 8 8
zero-weight zero-weight
edge to each 21 36 edge from each
job start 6 6 3 3 job finish
29
9 9
38
4 4

45
5 5

Edge-weighted DAG representation of job scheduling 49


Critical path method

CPM. Use longest path from the source to schedule each job.

7 3

0 9 6 8 2

5 4

0 41 70 91 123 173

Parallel job scheduling solution

51
41 1 1
0 0
50
32 32
2 2
duration 7 7 8 8
critical path
21 36
6 6 3 3
29
9 9
38
4 4

45
5 5

Longest paths solution to job scheduling example


50
4.4 S HORTEST P ATHS
‣ APIs
‣ shortest-paths properties
‣ Dijkstra's algorithm
Algorithms
‣ edge-weighted DAGs

R OBERT S EDGEWICK | K EVIN W AYNE


‣ negative weights
http://algs4.cs.princeton.edu
Shortest paths with negative weights: failed attempts

Dijkstra. Doesn’t work with negative edge weights.

0 6 1

Dijkstra selects vertex 3 immediately after 0.


2 4 -8
But shortest path from 0 to 3 is 0→1→2→3.

3 3 2

Re-weighting. Add a constant to every edge weight doesn’t work.

0 14 1

Adding 8 to each edge weight changes the


10 0 shortest path from 0→1→2→3 to 0→3.
12

3 11 2

Conclusion. Need a different algorithm.


52
Negative cycles

Def. A negative cycle is a directed cycle whose sum of edge weights is


negative.
digraph
4->5 0.35
s
5->4 -0.66
4->7 0.37
5->7 0.28
7->5 0.28
5->1 0.32
0->4 0.38
0->2 0.26
7->3 0.39
1->3 0.29 negative cycle (-0.66 + 0.37 + 0.28)
2->7 0.34 5->4->7->5
6->2 0.40
3->6 0.52
6->0 0.58 shortest path from 0 to 6
6->4 0.93 0->4->7->5->4->7->5...->1->3->6

An edge-weighted digraph with a negative cycle

Proposition. A SPT exists iff no negative cycles.

assuming all vertices reachable from s


53
Bellman-Ford algorithm

Bellman-Ford algorithm

Initialize distTo[s] = 0 and distTo[v] = ∞ for all other vertices.

Repeat V times:
- Relax each edge.

for (int i = 0; i < G.V(); i++)


for (int v = 0; v < G.V(); v++)
for (DirectedEdge e : G.adj(v)) pass i (relax each edge)
relax(e);

54
Bellman-Ford algorithm demo

Repeat V times: relax all E edges.

0→1 5.0
0→4 9.0
0→7 8.0
1 15 3 1→2 12.0

5 1→3 15.0
4
12 1→7 4.0
s 0 3
2→3 3.0
8
7 2 9 2→6 11.0
7
3→6 9.0
9 6 1
11 4→5 4.0
5
5 4→6 20.0
4 13 4→7 5.0
5→2 1.0
4 20 6
5→6 13.0
7→5 6.0

an edge-weighted digraph 7→2 7.0

55
Bellman-Ford algorithm demo

Repeat V times: relax all E edges.

1 3
v distTo[] edgeTo[]
0 0.0 -
s 0 1 5.0 0→1
2 14.0 5→2
7 2 3 17.0 2→3
4 9.0 0→4
5 13.0 4→5
5 6 25.0 2→6
7 8.0 0→7

4 6

shortest-paths tree from vertex s

56
Bellman-Ford algorithm: visualization

passes
4 7 10

13 SPT

Bellman-Ford (250 vertices)


57
Bellman-Ford algorithm: analysis

Bellman-Ford algorithm

Initialize distTo[s] = 0 and distTo[v] = ∞ for all other vertices.

Repeat V times:
- Relax each edge.

Proposition. Dynamic programming algorithm computes SPT in any edge-


weighted digraph with no negative cycles in time proportional to E × V.

Pf idea. After pass i, found path that is at least as short as any shortest
path containing i (or fewer) edges.

58
Bellman-Ford algorithm: practical improvement

Observation. If distTo[v] does not change during pass i,


no need to relax any edge pointing from v in pass i+1.

FIFO implementation. Maintain queue of vertices whose distTo[] changed.

be careful to keep at most one copy


of each vertex on queue (why?)

Overall effect.
・The running time is still proportional to E × V in worst case.
・But much faster than that in practice.

59
Single source shortest-paths implementation: cost summary

algorithm restriction typical case worst case extra space

no directed
topological sort E+V E+V V
cycles

Dijkstra no negative
E log V E log V V
(binary heap) weights

Bellman-Ford EV EV V
no negative
cycles
Bellman-Ford
E+V EV V
(queue-based)

Remark 1. Directed cycles make the problem harder.


Remark 2. Negative weights make the problem harder.
Remark 3. Negative cycles makes the problem intractable.

60
Finding a negative cycle

Negative cycle. Add two method to the API for SP.

boolean hasNegativeCycle() is there a negative cycle?

Iterable <DirectedEdge> negativeCycle() negative cycle reachable from s

digraph
4->5digraph
0.35
5->4 -0.66
4->5 0.35 s
4->7 0.37
5->4 -0.66
5->7 0.28
4->7 0.37
7->5 0.28
5->7 0.28
5->1 0.32
7->5 0.28
0->4 0.38
5->1 0.32
0->2 0.26
0->4 0.38
7->3 0.39
0->2 0.26
1->3 0.29 negative cycle (-0.66 + 0.37 + 0.28)
7->3 0.39
2->7 0.34
1->3 0.29 negative cycle (-0.66 + 0.37 + 0.28)
5->4->7->5
6->2 0.40
2->7 0.34 5->4->7->5
3->6 0.52
6->2 0.40
6->0 0.58 shortest path from 0 to 6
3->6 0.52
6->4 0.93
6->0 0.58 shortest path from 0 to 6
0->4->7->5->4->7->5...->1->3->6
6->4 0.93 0->4->7->5->4->7->5...->1->3->6
An edge-weighted digraph with a negative cycle
An edge-weighted digraph with a negative cycle 61
Finding a negative cycle

Observation. If there is a negative cycle, Bellman-Ford gets stuck in loop,


updating distTo[] and edgeTo[] entries of vertices in the cycle.

s 2 6 3 4

edgeTo[v]
1 5 v

Proposition. If any vertex v is updated in pass V, there exists a negative


cycle (and can trace back edgeTo[v] entries to find it).

In practice. Check for negative cycles more frequently.

62
Negative cycle application: arbitrage detection

Problem. Given table of exchange rates, is there an arbitrage opportunity?

USD EUR GBP CHF CAD

USD 1 0.741 0.657 1.061 1.011

EUR 1.350 1 0.888 1.433 1.366

GBP 1.521 1.126 1 1.614 1.538

CHF 0.943 0.698 0.620 1 0.953

CAD 0.995 0.732 0.650 1.049 1

Ex. $1,000 ⇒ 741 Euros ⇒ 1,012.206 Canadian dollars ⇒ $1,007.14497.

1000 × 0.741 × 1.366 × 0.995 = 1007.14497

63
Negative cycle application: arbitrage detection

Currency exchange graph.


・Vertex = currency.
・Edge = transaction, with weight equal to exchange rate.
・Find a directed cycle whose product of edge weights is > 1.
0.741 * 1.366 * .995 = 1.00714497
EUR
0.
88
0 8
.35

1.4
66
41 1
7

1.3
0. 1.

33
12
6
0.657
USD GBP
1. 1.521
0 61
3 8
1.0

.5

14
1
11

1.6
32

20
0.9

0.6
0.7

0.6
65
95

98
0. 0.
94
3
1.049
CAD CHF
0.953

An arbitrage opportunity

Challenge. Express as a negative cycle detection problem.


64
Negative cycle application: arbitrage detection

Model as a negative cycle detection problem by taking logs.


・Let weight of edge v→w be -ln (exchange rate from currency v to w).
・Multiplication turns to addition; > 1 turns to < 0.
・Find a directed cycle whose sum of edge weights is < 0 (negative cycle).
-ln(.741) -ln(1.366) -ln(.995)

EUR
.2998 - .3119 + .0050 = -.0071 .1
18
0 01 8
3
-.

-.3
98

119
9
.2 -.

598
-.3
11
87
.4201
USD GBP
-. -.4914
05 replace each
92 05
weight w 43
-.0

787
with !ln(w) -.
109

-.4
20

80
.00

.35
.31

.47
30
50

95
.4 .0
58
7
-.0478
CAD CHF
.0481

A negative cycle that represents


an arbitrage opportunity
Remark. Fastest algorithm is extraordinarily valuable!
65
Shortest paths summary

Nonnegative weights.
・Arises in many application.
・Dijkstra's algorithm is nearly linear-time.
Acyclic edge-weighted digraphs.
・Arise in some applications.
・Topological sort algorithm is linear time.
・Edge weights can be negative.
Negative weights and negative cycles.
・Arise in some applications.
・If no negative cycles, can find shortest paths via Bellman-Ford.
・If negative cycles, can find one via Bellman-Ford.
Shortest-paths is a broadly useful problem-solving model.

66

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy