-
Notifications
You must be signed in to change notification settings - Fork 32
/
shortest_paths.m
executable file
·134 lines (118 loc) · 4.51 KB
/
shortest_paths.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
function [d pred] = shortest_paths(A,u,varargin)
% SHORTEST_PATHS Compute the weighted single source shortest path problem.
%
% [d pred] = shortest_paths(A,u) returns the distance (d) and the predecessor
% (pred) for each of the vertices along the shortest path from u to every
% other vertex in the graph.
%
% ... = shortest_paths(A,u,...) takes a set of
% key-value pairs or an options structure. See set_matlab_bgl_options
% for the standard options.
% options.algname: the algorithm to use
% [{'auto'} | 'dijkstra' | 'bellman_ford' | 'dag']
% options.inf: the value to use for unreachable vertices
% [double > 0 | {Inf}]
% options.target: a special vertex that will stop the search when hit
% [{'none'} | any vertex number besides the u]; target is ignored if
% visitor is set.
% options.visitor: a structure with visitor callbacks. This option only
% applies to dijkstra or bellman_ford algorithms. See dijkstra_sp or
% bellman_ford_sp for details on the visitors.
% options.edge_weight: a double array over the edges with an edge
% weight for each edge, see EDGE_INDEX and EXAMPLES/REWEIGHTED_GRAPHS
% for information on how to use this option correctly
% [{'matrix'} | length(nnz(A)) double vector]
%
% Note: if you need to compute shortest paths with 0 weight edges, you must
% use an edge_weight vector, see the examples for details.
%
% Note: 'auto' cannot be used with 'nocheck' = 1. The 'auto' algorithm
% checks if the graph has negative edges and uses bellman_ford in that
% case, otherwise, it uses 'dijkstra'. In the future, it may check if the
% graph is a dag and use 'dag'.
%
% Example:
% load graphs/clr-25-2.mat
% shortest_paths(A,1)
% shortest_paths(A,1,struct('algname','bellman_ford'))
%
% See also DIJKSTRA_SP, BELLMAN_FORD_SP, DAG_SP
% David Gleich
% Copyright, Stanford University, 2006-2008
%% History
% 2006-04-19: Initial coding
% 2007-04-18: Added edge_weight option.
% 2007-04-19: Added target option.
% Added additional error checks.
% 2007-07-12: Fixed edge_weight documentation
%%
[trans check full2sparse] = get_matlab_bgl_options(varargin{:});
if full2sparse && ~issparse(A), A = sparse(A); end
options = struct('algname', 'auto', 'inf', Inf, 'edge_weight', 'matrix', ...
'target', 'none');
options = merge_options(options,varargin{:});
% edge_weights is an indicator that is 1 if we are using edge_weights
% passed on the command line or 0 if we are using the matrix.
edge_weights = 0;
edge_weight_opt = 'matrix';
if strcmp(options.edge_weight, 'matrix')
% do nothing if we are using the matrix weights
else
edge_weights = 1;
edge_weight_opt = options.edge_weight;
end
if strcmp(options.target,'none')
target = 0; % a flag used to denote "no target" to the mex
elseif isa(options.target, 'double')
target = options.target;
else
error('matlab_bgl:invalidParameter', ...
'options.target is not ''none'' or a vertex number.');
end
if check
% check the values of the matrix
check_matlab_bgl(A,struct('values',edge_weights ~= 1));
if edge_weights && nnz(A) ~= length(edge_weight_opt)
error('matlab_bgl:invalidParameter', 'the vector of edge weights must have length nnz(A)');
end
% set the algname
if (strcmpi(options.algname, 'auto'))
if edge_weights
mv = min(edge_weights);
else
mv = min(min(A));
end
if (mv < 0)
options.algname = 'bellman_ford';
else
options.algname = 'dijkstra';
end
else
% check the data provided to match the algorithm
if strcmpi(options.algname, 'dijkstra')
if edge_weights
mv = min(edge_weight_opt);
else
mv = min(min(A));
end
if mv < 0
error('matlab_bgl:invalidParameter', ...
'dijkstra''s algorithm cannot be used with negative edge weights.');
end
end
end
else
if (strcmpi(options.algname, 'auto'))
error('shortest_paths:invalidParameter', ...
'algname auto is not compatible with no check');
end
end
if options.inf < 0, error('options.inf must be larger than 0'); end
if trans, A = A'; end
if isfield(options,'visitor')
[d pred] = matlab_bgl_sp_mex(A,u,target,lower(options.algname),options.inf,...
edge_weight_opt, options.visitor);
else
[d pred] = matlab_bgl_sp_mex(A,u,target,lower(options.algname),options.inf,...
edge_weight_opt);
end