Dijkstra演算法(matlab)
阿新 • • 發佈:2018-12-27
Dijkstra演算法是尋找最短路徑的一種搜尋演算法,由荷蘭科學家提出。
演算法描述:通過為每個節點保留目前為止所找到的從s到e的最短路徑。為了記錄最佳路徑軌跡,記錄路徑上每個節點的前趨,通過回溯法找出最短路徑軌跡。
在網上搜索一些版本的Matlab實現方法,感覺都有些毛病。經過修改,得到比較好的效果。
function [ distance path] = Dijk( W,st,e ) %DIJK Summary of this function goes here % W 權值矩陣 st 搜尋的起點 e 搜尋的終點 n=length(W);%節點數 D = W(st,:); visit= ones(1:n); visit(st)=0; parent = zeros(1,n);%記錄每個節點的上一個節點 path =[]; for i=1:n-1 temp = []; %從起點出發,找最短距離的下一個點,每次不會重複原來的軌跡,設定visit判斷節點是否訪問 for j=1:n if visit(j) temp =[temp D(j)]; else temp =[temp inf]; end end [value,index] = min(temp); visit(index) = 0; %更新 如果經過index節點,從起點到每個節點的路徑長度更小,則更新,記錄前趨節點,方便後面回溯循跡 for k=1:n if D(k)>D(index)+W(index,k) D(k) = D(index)+W(index,k); parent(k) = index; end end end distance = D(e);%最短距離 %回溯法 從尾部往前尋找搜尋路徑 t = e; while t~=st && t>0 path =[t,path]; p=parent(t);t=p; end path =[st,path];%最短路徑 end
測試:
測試用例1
W=[0 50 inf 40 25 10
50 0 15 20 inf 25
inf 15 0 10 20 inf
40 20 10 0 10 25
25 inf 20 10 0 55
10 25 inf 25 55 0];
[distance,path]=Dijk(W,1,4);>> distance
distance =
35
>> path
path =
1 6 4
從節點1到節點4最短距離路徑為1-->6-->4, 最短距離為35
測試用例2
W=[0 1 3 4 1 0 2 inf 3 2 0 5 4 inf 5 0];
[distance,path]=Dijk(W,2,4);
>> distancedistance =
5
>> path
path =
2 1 4
從節點2到節點4最短距離路徑為2-->1-->4, 最短距離為5
java版dijkstra
import java.util.HashMap; import java.util.Map; /** * Created by zhangjackie on 18/5/2. */ public class DijkstraShortPath { private static final int N = 1000; private static int[][] graph = { {0, 7, 9, N, N, 14}, {7, 0, 10, 15, N, N}, {9, 10, 0, 11, N, 2}, {N, 15, 11, 0, 6, N}, {N, N, N, 6, 0, 9}, {14, N, 2, N, 9, 0} }; private static void dijkstra(int vstart, int[][] graph) { int n = graph.length; int[] dist = new int[n]; boolean[] visit = new boolean[n]; int[] prev = new int[n]; Map<Integer, String> path = new HashMap<Integer, String>(); int vnear = vstart; //初始化 for (int i = 0; i < n; i++) { dist[i] = graph[vstart][i]; visit[i] = false; prev[i] = vstart; } visit[vstart] = true; for (int i = 1; i < n; i++) { int min = N; //尋找最近的節點 for (int j = 0; j < n; j++) { if (!visit[j] && dist[j] < min) { min = dist[j]; vnear = j; } } visit[vnear] = true; //更新dist,記錄前一執行節點 for (int k = 0; k < n; k++) { int minDist = min + graph[vnear][k]; if (!visit[k] && minDist < dist[k]) { dist[k] = minDist; prev[k] = vnear; } } } //列印最短路徑 for (int i = 0; i < n; i++) { int preprev = prev[i]; path.put(i,Integer.toString(i)); while (preprev != vstart) { String oldpath = path.get(i); path.put(i, preprev + "->" + oldpath); preprev = prev[preprev]; } String oldpath = path.get(i); path.put(i, vstart +"->" + oldpath); } // System.out.println(Arrays.toString(dist)); for (int i = 0; i < n; i++) { // System.out.println("v" + vstart + "...v" + prev[i] + "->v" + i + ", s=" + dist[i]); System.out.println(path.get(i) + ", s=" + dist[i]); } } public static void main(String[] args) { dijkstra(3, graph); } }