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