最短路徑問題就是給定一個圖,這個圖中的邊是有方向和權重的。求s到t的最短路徑。
最短路徑問題其實分為很多種。按照起點和終點來分,可以分為:
從一個頂點到另一個頂點
從一個頂點到其他所有頂點
從所有頂點到所有頂點
按照邊的權重來分可以分為:
非負權
任意權
歐幾裡德權
按照是否有環可以分為
無環最短路徑
無負環最短路徑
在實現最短路徑算法之前,需要先在程序中定義有向權重圖。
有向權重邊的定義如下:
public class DirectedEdge { private int v; private int w; private double weight; public DirectedEdge(int v, int w, double weight) { this.v = v; this.w = w; this.weight = weight; } public int from() { return v; } public int to() { return w; } public double weight() { return this.weight; } @Override public String toString() { return String.format("%s->%s[%s]", v, w, weight); } }
有向權重圖的定義如下:
import java.util.LinkedList; public class EdgeWeightedDigraph { private int V; private LinkedList[] adj; public EdgeWeightedDigraph(int V) { this.V = V; adj = new LinkedList[V]; for (int i = 0; i < V; i++) { adj[i] = new LinkedList (); } } public void addEdge(DirectedEdge edge) { int v = edge.from(); adj[v].add(edge); } public Iterable adj(int v) { return adj[v]; } public int V() { return V; } public int E() { int result = 0; for (LinkedList e : adj) { result += e.size(); } return result; } @Override public String toString() { String result = ""; for (int i = 0; i < adj.length; i++) { result += i + ":"; for (DirectedEdge e : adj[i]) { result += String.format(" %s[%s]", e.to(), e.weight()); } } return result; } }
這樣定義有向權重圖的好處就是可以有自連接,可以實現頂點之間有多個連接。
最短路徑算法類的接口如下:
public class SP { public double distTo(int v); public IterablepathTo(int v); }