Princeton Alogorithm COS226 Week8 Shortest Path

shortest path is in an edge-weighted digrah, given an edge weighted digraph, find the shortest path from s to t.
application used shortest path below:


image.png

there are some variants in shortest path problem;

like which vertices?
single source: from one vertex s to every other vertex.
source-sink, from one vertex s to another t
all pairs, between all pairs of vertices.

restriction on edge weights,
non-negative weights, euclidean weights, arbitrary weights.

cycle,
no directed cycle, no "negative cycles"

api

image.png

image.png

image.png

edge relaxation

image.png
 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;
 }
 }
image.png

Dijkstra

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


image.png

image.png

time complexity

image.png

shortest path in DAG

consider vertices in topological order, relax all edges pointing from that vertex;

image.png

image.png

longest path

image.png

image.png

add this implementation and visualization in extra credit

Bellman-Ford

when a graph which have negative edge will break the invariants in Dijkstra algorithm.
and the graph which have negative cycle will have no shortest path.

to handle both situation, we will use Bellman ford algorithm.


image.png

improvement

if distTo[v] does not change during pass i, no need to relax any edge pointing from v in pass i+1

so we can maintain queue of verices whose distTo[] changed.

the running time is still proportional to E * V in worst case, but much faster than that in practice


image.png

handle negative cycle

if there is a negative cycle, bellman-ford gets stuck in loop, updating distTo[] and edgeTo[] entries of vertices in the cycle.
if any vertex v is updated in phase V, there exists a negative cycle

arbitrage detection

image.png

add this implementation and visualization in extra credit
when we use improvement bellman ford, we could check one node into queue V times means there exists negative cycle.

QUIZ

Q1 Monotonic shortest path

image.png

the solution in this stackoverflow https://stackoverflow.com/questions/22876105/find-a-monotonic-shortest-path-in-a-graph-in-oe-logv
could only solve this problem when edge is all positive.
my solution is that (assumption edge weight is distinct)

  1. init every node except s, others are positive infinity. s = 0;
  2. sort the edges by weight in ascending order(when find increase path)
  3. considerate edge in this order, then check this edge can relax or not, if it could relax, relax it. if not, discard it. (if from point is positive infinity, failed to relax)
  4. then check is there a path reach the t.

now edge could have duplicate weight, how to handle it. below is a distinct edge weigh algorithm not handle case. because we need a strictly monotonic increasing path.

image.png

for every vertex we need to save two value, one is minPathSum, and secondPathSum, on above picture, the minPath is to third node is {6}, the second path is {3,4}
when we find a edge is same as min path edge weight, we need to check the second could build a possible relaxation.

Q2 Second shortest path

image.png

a naive wrong idea is that we compute the shortest path distances from s to every vertex and the shortest path distances from every vertex to t. and find the shortest path, we need to select a node which are not in the shortest path vertex, then find the minimum path in all of these node.

the correct way is that node could be same,but the path diff is that at least one edge is not same as the shortest path, so we need to select a edge which are not in the shortest path edge set. then use s to this edge from() , and this edge to() to t. find the minimum path.

Q3 Shortest path with one skippable edge

image.png

the idea is same as Q2, we precompute the shortest path from s to every vertex; compute the shortest path from every vertex to t. then we iterate every edge, check without this edge, what is minimum from s to this edge from(), and this edge to() to t.

Project Seam Carving

image.png

image.png

this project we need to keep the two two-dimension array, one is for picture another is for energy.

Start by writing the constructor as well as picture(), width() and height(). These should be very easy.

From there, write energy(). Calculating Δx^2 and Δy^2 are very similar. Using two private methods will keep your code simple. To test that your code works, use the client PrintEnergy described in the testing section above.

the core of this project is use topological sort to find the shortest path, but with the navie graph, we donot need to build a real graph object, we can define the two-dimension array as a graph


image.png

this is very similar with dynamic programming
one cell depend on its above three cells.

then for the improvement.

  • When finding a seam, call energy() at most once per pixel. For example, you can save the energies in a local variable energy[][] and access the information directly from the 2D array (instead of recomputing from scratch).
  • Avoid redundant calls to the get() method in Picture. For example, to access the red, green, and blue components of a pixel, call get() only once (and not three times).
  • The order in which you traverse the pixels (row-major order vs. column-major order) can make a big difference.
  • Creating Color objects can be a bottleneck. Each call to the get() method in Picture creates a new Color object. You can avoid this overhead by using the getRGB() method in Picture, which returns the color, encoded as a 32-bit int. The companion setRGB() method sets the color of a given pixel using a 32-bit int to encode the color.
  • Don’t explicitly transpose the Picture or int[][] until you need to do so. For example, if you perform a sequence of 50 consecutive horizontal seam removals, you should need only two transposes (not 100).
  • Consider using System.arraycopy() to shift elements within an array.
  • Reuse the energy array and shift array elements to plug the holes left from the seam that was just removed. You will need to recalculate the energies for the pixels along the seam that was just removed, but no other energies will change.

course quiz and project : https://github.com/yixuaz/algorithm4-princeton-cos226

你可能感兴趣的:(Princeton Alogorithm COS226 Week8 Shortest Path)