1. 程式人生 > >演算法8-10:最短路徑演算法之拓撲排序

演算法8-10:最短路徑演算法之拓撲排序

該演算法的基本思想就是按照拓撲排序的順序依次將每個頂點加入到最短路徑樹中,每次加入時將該頂點延伸出的所有頂點進行“放鬆”操作。這種演算法的複雜度是E+V。

程式碼

這種演算法的程式碼比Dijkstra還要簡單,程式碼如下:

public class TopologySP extends SP {
    public TopologySP(EdgeWeightedDigraph G, int s) {
        super(G, s);
 
        // 將所有頂點到原點的距離設為無窮大
        // 注意:下面這段程式碼不要遺漏
        for(int i=0;i<G.V();i++){
            distTo[i] = Double.POSITIVE_INFINITY;
        }
        distTo[s] = 0;
 
        DepthFirstOrder dfo = new DepthFirstOrder(G);
        for (int v : dfo.sort()) {
            for (DirectedEdge e : G.adj(v)) {
                relax(e);
            }
        }
    }
}


應用

Seam Carving

Seam Carving是一種新型的影象縮放演算法。傳統的圖片縮放會導致影象變形,而這種演算法不會。從Photoshop CS4開始支援這種縮放方法,中文名為“內容識別比例”,在編輯選單中。

下圖是原始圖片,等待縮放,要將其縮放成正方形。

下圖是傳統的拉伸縮放方法,這種方法會導致城堡變形。

下圖是傳統的裁剪伸縮方法,這種方法會導致城堡無法完全顯示。

下圖是新型的Seam Carving縮放演算法,城堡沒有變形,而且顯示完全。這種結果比較理想。

Seam Carving演算法中使用了最短路徑,將每個畫素看作一個頂點,從上到下建立能量流。縮放時依次將能量流最小的一列畫素刪除。

最長路徑

最長路徑問題可以轉換成最短路徑問題,只要將圖中所有的權都取相反數,再計算最短路徑即可。

計算任務流程中的關鍵路徑就是最長路徑的一個例子。