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