comparison toolboxes/FullBNT-1.0.7/graph/dijkstra.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e9a9cd732c1e
1 function [D,P] = dijk(A,s,t)
2 %DIJK Shortest paths from nodes 's' to nodes 't' using Dijkstra algorithm.
3 % [D,p] = dijk(A,s,t)
4 % A = n x n node-node weighted adjacency matrix of arc lengths
5 % (Note: A(i,j) = 0 => Arc (i,j) does not exist;
6 % A(i,j) = NaN => Arc (i,j) exists with 0 weight)
7 % s = FROM node indices
8 % = [] (default), paths from all nodes
9 % t = TO node indices
10 % = [] (default), paths to all nodes
11 % D = |s| x |t| matrix of shortest path distances from 's' to 't'
12 % = [D(i,j)], where D(i,j) = distance from node 'i' to node 'j'
13 % P = |s| x n matrix of predecessor indices, where P(i,j) is the
14 % index of the predecessor to node 'j' on the path from 's(i)' to 'j'
15 % (use PRED2PATH to convert P to paths)
16 % = path from 's' to 't', if |s| = |t| = 1
17 %
18 % (If A is a triangular matrix, then computationally intensive node
19 % selection step not needed since graph is acyclic (triangularity is a
20 % sufficient, but not a necessary, condition for a graph to be acyclic)
21 % and A can have non-negative elements)
22 %
23 % (If |s| >> |t|, then DIJK is faster if DIJK(A',t,s) used, where D is now
24 % transposed and P now represents successor indices)
25 %
26 % (Based on Fig. 4.6 in Ahuja, Magnanti, and Orlin, Network Flows,
27 % Prentice-Hall, 1993, p. 109.)
28
29 % Copyright (c) 1998-2001 by Michael G. Kay
30 % Matlog Version 5 22-Aug-2001
31
32 % Input Error Checking ******************************************************
33 error(nargchk(1,3,nargin));
34
35 [n,cA] = size(A);
36
37 if nargin < 2 | isempty(s), s = (1:n)'; else s = s(:); end
38 if nargin < 3 | isempty(t), t = (1:n)'; else t = t(:); end
39
40 if ~any(any(tril(A) ~= 0)) % A is upper triangular
41 isAcyclic = 1;
42 elseif ~any(any(triu(A) ~= 0)) % A is lower triangular
43 isAcyclic = 2;
44 else % Graph may not be acyclic
45 isAcyclic = 0;
46 end
47
48 if n ~= cA
49 error('A must be a square matrix');
50 elseif ~isAcyclic & any(any(A < 0))
51 error('A must be non-negative');
52 elseif any(s < 1 | s > n)
53 error(['''s'' must be an integer between 1 and ',num2str(n)]);
54 elseif any(t < 1 | t > n)
55 error(['''t'' must be an integer between 1 and ',num2str(n)]);
56 end
57 % End (Input Error Checking) ************************************************
58
59 A = A'; % Use transpose to speed-up FIND for sparse A
60
61 D = zeros(length(s),length(t));
62 if nargout > 1, P = zeros(length(s),n); end
63
64 for i = 1:length(s)
65 j = s(i);
66
67 Di = Inf*ones(n,1); Di(j) = 0;
68
69 isLab = logical(zeros(length(t),1));
70 if isAcyclic == 1
71 nLab = j - 1;
72 elseif isAcyclic == 2
73 nLab = n - j;
74 else
75 nLab = 0;
76 UnLab = 1:n;
77 isUnLab = logical(ones(n,1));
78 end
79
80 while nLab < n & ~all(isLab)
81 if isAcyclic
82 Dj = Di(j);
83 else % Node selection
84 [Dj,jj] = min(Di(isUnLab));
85 j = UnLab(jj);
86 UnLab(jj) = [];
87 isUnLab(j) = 0;
88 end
89
90 nLab = nLab + 1;
91 if length(t) < n, isLab = isLab | (j == t); end
92
93 [jA,kA,Aj] = find(A(:,j));
94 Aj(isnan(Aj)) = 0;
95
96 if isempty(Aj), Dk = Inf; else Dk = Dj + Aj; end
97
98 if nargout > 1, P(i,jA(Dk < Di(jA))) = j; end
99 Di(jA) = min(Di(jA),Dk);
100
101 if isAcyclic == 1 % Increment node index for upper triangular A
102 j = j + 1;
103 elseif isAcyclic == 2 % Decrement node index for lower triangular A
104 j = j - 1;
105 end
106 end
107 D(i,:) = Di(t)';
108 end
109
110 if nargout > 1 & length(s) == 1 & length(t) == 1
111 P = pred2path(P,s,t);
112 end