1. 程式人生 > >最短路徑迪傑斯特拉演算法和弗洛伊德演算法實現

最短路徑迪傑斯特拉演算法和弗洛伊德演算法實現

迪傑斯特拉演算法:
矩陣二位陣列矩陣T儲存頂點vi到各頂點的最短路徑值,初始狀態為鄰接頂點為弧的權值,非鄰接頂點為無窮大。陣列S用於儲存最短路徑,儲存單元為該弧的前驅頂點的下標和與前驅頂點之間的弧的權值。
1.從T中找出一條弧值最小的弧(vi,vj),將該弧加入S中,並根據vj的鄰接點vx更新T,如果(vi,vj)+(vj ,vx) < (vi,vx),則更新(vi,vx)為(vi,vj)+(vj ,vx) ,並記錄其vx的前驅為vj
2.從T中找出不在S中的剩餘的弧中權值最小的重複1步驟。

程式碼實現:

/**
     * @name 最短路徑迪傑斯特拉演算法
     * @use 使用迪傑斯特拉演算法計算圖(二維陣列)的最短路徑
     * @param chart 圖
     * @param start 起始結點
     * @return T 最短路徑集合
     */
    public static function shortestPathD($chart, $start) {
        $points = array($start);
        $tempIndex = $start;
        $T = array();
        foreach ($chart[$start] as $key => $value) {
            $T[$key]['pre'] = $start;
            $T[$key]['value'] = $value;
        }
        while (count($points) < count($chart)) {
            $min = PHP_INT_MAX;
            foreach ($chart[$start] as $key => $value) {
                if (!in_array($key, $points) && $value != 0 && $value < $min) {
                    $min = $value;
                    $tempIndex = $key; 
                }
            }
            $T[$tempIndex]['value'] = $min;
            $points[] = $tempIndex;
            foreach ($chart[$tempIndex] as $key => $value) {
                if ($value != 0 && $key != $start) {
                    if (($chart[$start][$tempIndex] + $chart[$tempIndex][$key]) < $chart[$start][$key] ||
                        $chart[$start][$key] == 0
                    ) {
                        $chart[$start][$key] = $chart[$start][$tempIndex] + $chart[$tempIndex][$key];
                        $T[$key]['pre'] = $tempIndex;
                    }
                }
            }
        }
        unset($T[$start]);
        return $T;
    }

弗洛伊德演算法:
演算法思想,以每一個頂點為中介值去更新矩陣。

/**
     * @name 最短路徑弗洛伊德演算法
     * @use 使用弗洛伊德演算法計算圖(二維陣列)的最短路徑
     * @param chart 圖
     * @param start 起始結點
     * @return T 最短路徑集合
     */
    public static function shortestPathF($chart, $start) {
        foreach ($chart as $key => $value) {
            foreach ($chart as $k1 =>$v1) {
                foreach ($chart as $k2 =>$v2) {
                    if ($k1 == $k2) {
                        continue;
                    }
                    if (($chart[$k1][$key] + $chart[$key][$k2]) < $chart[$k1][$k2]) {
                        $chart[$k1][$k2] = $chart[$k1][$key] + $chart[$key][$k2];
                    }
                }
            }
        }
        return $chart;
    }