Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/FullBNT-1.0.7/graph/dijkstra.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,112 @@ +function [D,P] = dijk(A,s,t) +%DIJK Shortest paths from nodes 's' to nodes 't' using Dijkstra algorithm. +% [D,p] = dijk(A,s,t) +% A = n x n node-node weighted adjacency matrix of arc lengths +% (Note: A(i,j) = 0 => Arc (i,j) does not exist; +% A(i,j) = NaN => Arc (i,j) exists with 0 weight) +% s = FROM node indices +% = [] (default), paths from all nodes +% t = TO node indices +% = [] (default), paths to all nodes +% D = |s| x |t| matrix of shortest path distances from 's' to 't' +% = [D(i,j)], where D(i,j) = distance from node 'i' to node 'j' +% P = |s| x n matrix of predecessor indices, where P(i,j) is the +% index of the predecessor to node 'j' on the path from 's(i)' to 'j' +% (use PRED2PATH to convert P to paths) +% = path from 's' to 't', if |s| = |t| = 1 +% +% (If A is a triangular matrix, then computationally intensive node +% selection step not needed since graph is acyclic (triangularity is a +% sufficient, but not a necessary, condition for a graph to be acyclic) +% and A can have non-negative elements) +% +% (If |s| >> |t|, then DIJK is faster if DIJK(A',t,s) used, where D is now +% transposed and P now represents successor indices) +% +% (Based on Fig. 4.6 in Ahuja, Magnanti, and Orlin, Network Flows, +% Prentice-Hall, 1993, p. 109.) + +% Copyright (c) 1998-2001 by Michael G. Kay +% Matlog Version 5 22-Aug-2001 + +% Input Error Checking ****************************************************** +error(nargchk(1,3,nargin)); + +[n,cA] = size(A); + +if nargin < 2 | isempty(s), s = (1:n)'; else s = s(:); end +if nargin < 3 | isempty(t), t = (1:n)'; else t = t(:); end + +if ~any(any(tril(A) ~= 0)) % A is upper triangular + isAcyclic = 1; +elseif ~any(any(triu(A) ~= 0)) % A is lower triangular + isAcyclic = 2; +else % Graph may not be acyclic + isAcyclic = 0; +end + +if n ~= cA + error('A must be a square matrix'); +elseif ~isAcyclic & any(any(A < 0)) + error('A must be non-negative'); +elseif any(s < 1 | s > n) + error(['''s'' must be an integer between 1 and ',num2str(n)]); +elseif any(t < 1 | t > n) + error(['''t'' must be an integer between 1 and ',num2str(n)]); +end +% End (Input Error Checking) ************************************************ + +A = A'; % Use transpose to speed-up FIND for sparse A + +D = zeros(length(s),length(t)); +if nargout > 1, P = zeros(length(s),n); end + +for i = 1:length(s) + j = s(i); + + Di = Inf*ones(n,1); Di(j) = 0; + + isLab = logical(zeros(length(t),1)); + if isAcyclic == 1 + nLab = j - 1; + elseif isAcyclic == 2 + nLab = n - j; + else + nLab = 0; + UnLab = 1:n; + isUnLab = logical(ones(n,1)); + end + + while nLab < n & ~all(isLab) + if isAcyclic + Dj = Di(j); + else % Node selection + [Dj,jj] = min(Di(isUnLab)); + j = UnLab(jj); + UnLab(jj) = []; + isUnLab(j) = 0; + end + + nLab = nLab + 1; + if length(t) < n, isLab = isLab | (j == t); end + + [jA,kA,Aj] = find(A(:,j)); + Aj(isnan(Aj)) = 0; + + if isempty(Aj), Dk = Inf; else Dk = Dj + Aj; end + + if nargout > 1, P(i,jA(Dk < Di(jA))) = j; end + Di(jA) = min(Di(jA),Dk); + + if isAcyclic == 1 % Increment node index for upper triangular A + j = j + 1; + elseif isAcyclic == 2 % Decrement node index for lower triangular A + j = j - 1; + end + end + D(i,:) = Di(t)'; +end + +if nargout > 1 & length(s) == 1 & length(t) == 1 + P = pred2path(P,s,t); +end