function [sp, spcost] = dijkstraties(G, s, d) % function [sp, spcost] = dijkstraties(G, s, d) %----------------------------------------------------------------------------- % Dijkstra algorithm to find _all_ minimal paths in a weighted oriented graph % with the adjacency matrix G(nnod,nnod) (containing 1/segment_weight), % leading from node (s) to node (d) %*** parameters: % G(nnod,nnod) -in- sparse adjacency matrix containing 1/segment_weights % G(i,j)=s: cost of passing through oriented % segment (i-->j) is 1/s % s,d -in- indices of start node (s) and destination node (d) % sp{npaths} -in- cell array containing all minimal paths % sp{ipath} = [s ... d] == nodes along the path (ipath) % spcost -in- cost of the minimal path(s) %*** For information about this algorithm visit: % http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm %----------------------------------------------------------------------------- % This function is built on the dijkstra.m function written by Jorge % Ignacia Barrera Alviar (April 2008), available at % http://www.mathworks.com/matlabcentral/fileexchange under file ID 5550. % Modified to record all ties for shortest path by David Blum % Modified to accept sparse adjacency matrix G(i,j)=1/segment_cost by % Ales Janka %----------------------------------------------------------------------------- Ginv = @(u,i) (1/(G(u,i)+1e-10*(G(u,i)==0))); n=size(G,1); S(1:n) = 0; %s, vector, set of visited vectors dist(1:n) = inf; % it stores the shortest distance between the source node and any other node; prev = cell(1,n); % prev(1:n) = n+1; % Previous node, informs about the best previous node known to reach each network node prev(1:n) = {n+1}; dist(s) = 0; counter(1:n) = 1; while sum(S)~=n candidate=[]; for i=1:n if S(i)==0 candidate=[candidate dist(i)]; else candidate=[candidate inf]; end end [u_index u]=min(candidate); S(u)=1; for i=1:n if(dist(u)+Ginv(u,i)) 1 for j=2:counter prev(counter,i) = {NaN}; end end counter(i) = 1; elseif(dist(u)+Ginv(u,i)) == dist(i) % SEE DOCUMENTATION Switch 3 (add) % elseif (1 - (1 - dist(u)) * (1 - Ginv(u,i))) == dist(i) % SEE DOCUMENTATION Switch 3 (mult) prev(counter(i)+1,i) = {u}; counter(i) = counter(i)+1; end end end % Define a vector to represent how many ties are contained in the prev cell % array corresponding to each node prevcolindex = ones(1,n); for i = 1:n for j = 2:size(prev,1) if isempty(prev{j,i}) == 1 break; else prevcolindex(i) = j; end end end % Trace the branches of the path backwards beginning at d using the prev cell array. Record % the history of all steps each branch of the shortest path in backpaths cell array. % (Each step backwards along any branch in the path trace occupies a new cell in backpaths.) backpaths = cell(1,1); backpaths(1,1) = {d}; counters = 1; counterf = 1; test = 0; while all(test == s) == 0 % The stopping criteria is that all remaining active branches (ie step histories that have not yet arrived at s) arrive at s simultaneuously test = s; for j = counters:counterf if backpaths{j}(1) == s continue; % If a step history his already arrived at s, it is skipped end counterm = length(backpaths); for i = 1:prevcolindex(backpaths{j}) % Step backwards along each branch of the shortest path, and record the resulting history in a new cell in backpaths backpaths{counterm+i} = cat(2,prev{i,backpaths{j}(1)},backpaths{j}); end test = cat(1,test,prev{i,backpaths{j}(1)}); end counters = 1+counterf; counterf = length(backpaths); end % Extract the step histories that end (ie begin) at node s, and save them % to sp (the shortest path array) sp = cell(1,1); for i = 1:counterf if backpaths{i}(1) == s && isempty(sp{1}) == 1 sp = backpaths(i); elseif backpaths{i}(1) == s && isempty(sp{1}) == 0 sp = cat(1,sp,backpaths(i)); end end spcost = dist(d); end