To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / _FullBNT / BNT / graph / dijkstra.m @ 8:b5b38998ef3b

History | View | Annotate | Download (3.59 KB)

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