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:
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
edge relaxation
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;
}
}
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
time complexity
shortest path in DAG
consider vertices in topological order, relax all edges pointing from that vertex;
longest path
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.
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
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
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
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)
- init every node except s, others are positive infinity. s = 0;
- sort the edges by weight in ascending order(when find increase path)
- 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)
- 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.
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
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
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
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
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 variableenergy[][]
and access the information directly from the 2D array (instead of recomputing from scratch). - Avoid redundant calls to the
get()
method inPicture
. For example, to access the red, green, and blue components of a pixel, callget()
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 theget()
method inPicture
creates a newColor
object. You can avoid this overhead by using thegetRGB()
method inPicture
, which returns the color, encoded as a 32-bitint
. The companionsetRGB()
method sets the color of a given pixel using a 32-bitint
to encode the color. - Don’t explicitly transpose the
Picture
orint[][]
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