求最短路径算法,目前我知道的有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法。相比前一种算法,后一种算法
相对更加简洁优雅,所以先用php实现此种算法。
既然是有最短路径,肯定是对于由多个顶点组成的图形结构来应用的,且上述算法对无向图、有向图都使用。
首先是构造描述图形结构的邻接矩阵和描述对应顶点的最小路径的前驱矩阵的二维数组。
//权值数组
$pathArray = [
[0, 1, 5, 65535, 65535, 65535, 65535, 65535, 65535],
[1, 0, 3, 7, 5, 65535, 65535, 65535, 65535],
[5, 3, 0, 65535, 1, 7, 65535, 65535, 65535],
[65535, 7, 65535, 0, 2, 65535, 3, 65535, 65535],
[65535, 5, 1, 2, 0, 3, 6, 9, 65535],
[65535, 65535, 7, 65535, 3, 0, 65535, 5, 65535],
[65535, 65535, 65535, 3, 6, 65535, 0, 2, 7 ],
[65535, 65535, 65535, 65535, 9, 5, 2, 0, 4 ],
[65535, 65535, 65535, 65535, 65535, 65535, 7, 4, 0 ],
];
//最短路径数组
$shortPathArray = [];
for ($i=0; $i < 9; $i++) {
for ($j=0; $j < 9; $j++) {
$shortPathArray[$i][$j] = $j;
}
}
数组构造就是上面的代码,如有更好方法,请留言指教,先在此多谢了。。。
第二步,是对两个矩阵不断进行调整的过程。
function shortestPath_Floyd(&$pathArray, &$shortPathArray)
{
for ($k=0; $k < 9; ++$k) {
for ($v=0; $v < 9; ++$v) {
for ($w=0; $w < 9; ++$w) {
if ($pathArray[$v][$w] > ($pathArray[$v][$k] + $pathArray[$k][$w])) {
$pathArray[$v][$w] = $pathArray[$v][$k] + $pathArray[$k][$w];
$shortPathArray[$v][$w] = $shortPathArray[$v][$k];
}
}
}
}
}
至此,前驱矩阵和邻接矩阵就已经调整完成。邻接矩阵可以清楚的看到各顶点到其他顶点的最小路径权值,前驱矩阵需要一定分析,即可知道一顶点到另一定点最短路径的具体途径过程。
下面是求各顶点到其他顶点的最短路径的具体途径顶点路线。
function shortTestPath($pathArray, $shortPathArray)
{
for ($v=0; $v < 9; ++$v) {
for ($w=$v+1; $w < 9; ++$w) {
echo "V{$v} - V{$w} weight: {$pathArray[$v][$w]}";
$k = $shortPathArray[$v][$w];
echo " path: {$v}";
while ($k != $w) {
echo " -> {$k}";
$k = $shortPathArray[$k][$w];
}
echo " -> {$w}\n";
}
echo "\n";
}
}
到这里,就讲解结束了,可能具体描述的不太清楚,可以参考大话数据结构这本书的相关示例。