annotate toolboxes/FullBNT-1.0.7/graph/dijkstra.m @ 0:cc4b1211e677 tip

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