Dijkstra’s algorithm
迪杰斯特拉算法是目前已知的解决单源最短路径问题的最快算法.
单源(single source)最短路径,就是从一个源点出发,考察它到任意顶点所经过的边的权重之和为最小的路径.
迪杰斯特拉算法不能处理权值为负数或为零的边,因为本质上它是一种贪心算法,出现了负数意味着它可能会舍弃一条正确的边,而选择一个长边和一个负数边,因为长边和负数边的权值之和可能小于那条正确的边.
算法描述
它的过程也很简单,按照广度遍历的方式考察每一条有向边(v,w),如果可以对边进行松弛,就记录这条边,并更新到边的目标顶点的最短距离.
注意,这个“最短距离”是当前搜索进程中已知的最短距离而不一定是最终的最短距离.
对边进行松弛的操作如下:
/**
* 对边进行松弛
*
* 对一条有向边(v,w,weight)进行考察:
* 如果当前已知的到w的距离distance_to(w) > distance_to(v) + weight,
* 说明可以改善到w的距离.从而更新这个距离:
* distance_to(w) = distance_to(v) + weight;
* 同时选择这条边为到w的目前已知的最短边
* last_edge_to(w) = (v,w,weight)
*
* @param edge 有向带权边
*/
private void relaxEdge(WeightedEdge edge) {
IndexPriorityQueue<Double> q = indexCrossingEdges;
int src = edge.src;
int to =edge.to;
if(distanceTo[to] > distanceTo[src] + edge.weight) {
distanceTo[to] = distanceTo[src] + edge.weight;
lastEdgeTo[to] = edge;
if(q.contains(to))
q.decreaseKey(to,distanceTo[to]);
else
q.offer(to,distanceTo[to]);
}
}
松弛操作中,使用