最短路径迪杰斯特拉算法和弗洛伊德算法实现

迪杰斯特拉算法:
矩阵二位数组矩阵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;
    }

猜你喜欢

转载自blog.csdn.net/qq_25744595/article/details/84564427