To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
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 |