最短路徑迪傑斯特拉演算法和弗洛伊德演算法實現
阿新 • • 發佈:2018-12-10
迪傑斯特拉演算法:
矩陣二位陣列矩陣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; }