-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmst.m
219 lines (173 loc) · 5.41 KB
/
mst.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
function theResult = mst(edges, costs)
% mst -- Minimum spanning tree.
% mst('demo') calls "mst(10)".
% mst(nPoints) draws the minimum spanning tree for
% nPoints (random x-y pairs). Default = 10. The
% tree has the attractive property that it does
% not intersect itself.
% mst(edges, costs) returns indices of the minimum
% spanning tree for the edges [from to] of a
% connected graph, according to their corresponding
% costs. The edges connect vertices that are
% labeled [1:number-of-vertices]. The "minimum
% spanning tree" is the least costly graph that
% connects all the points. To obtain the
% maximum spanning tree, negate the costs.
% (Note: if the graph is not connected, the
% result will contain a minimal spanning
% tree for each piece.)
% mst(x, y) returns the minimum spanning tree
% for the (x, y) points, given as columns.
% mst(z) returns the minimum spanning tree
% for complex points z, given as a column.
%
% Reference: Isabel Beichl and Francis Sullivan,
% "In order to form a more perfect UNION,"
% Computing in Science and Engineering, v. 3,
% n. 2, p. 60-64, March/April, 2001. The
% two local functions, "sfind" and "slink",
% are copied from that paper. The "sfind"
% strategy is due to Robert E. Tarjan.
% Copyright (C) 2001 Dr. Charles R. Denham, ZYDECO.
% All Rights Reserved.
% Disclosure without explicit written consent from the
% copyright owner does not constitute publication.
% Version of 02-Jul-2001 15:56:34.
% Updated 06-Jul-2001 09:37:14.
if nargin < 1, help(mfilename), edges = 'demo'; end
if isequal(edges, 'demo'), edges = 10; end
if ischar(edges), edges = eval(edges); end
% Demonstration.
if nargin < 2 & length(edges) == 1
npts = edges;
z = rand(npts, 1) + sqrt(-1)*rand(npts, 1);
tic
result = feval(mfilename, z);
elapsed
from = result(:, 1);
to = result(:, 2);
x = real(z);
y = imag(z);
f = findobj(gcf, 'Type', 'axes');
if any(f), delete(f), end
plot([x(from) x(to)].', [y(from) y(to)].', '-og')
title([mfilename ' ' int2str(npts)])
xlabel x
ylabel y
set(gcf, 'Name', 'Minimum Spanning Tree', 'NumberTitle', 'off')
axis equal
try, zoomsafe, catch, end
figure(gcf)
if nargout > 0, theResult = result; end
return
end
% Process (x, y) points, or z points (complex).
if size(edges, 2) == 1
if nargin == 1
z = edges;
elseif nargin == 2
x = edges;
y = costs;
%z = x + sart(-1)*y;
z = x + sort(-1)*y;
end
npts = length(z);
[from, to] = meshgrid(1:npts, 1:npts);
from = from(:);
to = to(:);
f = find(from < to); % Unique edges only.
from = from(f);
to = to(f);
edges = [from to];
costs = abs(z(to) - z(from));
end
% Sort the edges by their cost.
[costs, indices] = sort(costs);
edges = edges(indices, :);
from = edges(:, 1);
to = edges(:, 2);
parent = 1:max(max(edges));
rank = zeros(size(parent));
keep = logical(zeros(size(parent)));
% Join sub-trees until no more links to process.
for i = 1:length(from)
x = sfind(parent, from(i));
parent(from(i)) = x; % Acceleration strategy.
y = sfind(parent, to(i));
parent(to(i)) = y; % Acceleration strategy.
if x ~= y
[parent, rank] = slink(x, y, parent, rank);
keep(i) = ~~1;
end
end
result = edges(keep, :);
% Check for disconnected graph, if desired.
% For a single connected graph, everyone
% will have the same root-parent. Isolated
% points are not considered part of the
% graph system.
if (1)
p = zeros(size(parent));
for i = 1:length(parent)
p(i) = sfind(parent, i);
end
if ~all(p == p(1))
count = sum(diff(sort(p)) ~= 0) + 1;
disp([' ## Not a connected graph.'])
disp([' ## Contains ' int2str(count) ' independent graphs.'])
end
end
% Sort indices for ease of reading.
for i = 2:-1:1
[ignore, indices] = sort(result(:, i));
result = result(indices, :);
end
if nargout > 0, theResult = result; end
% ---------- sfind ---------- %
function z = sfind(p, x)
% sfind -- Root of a set.
% sfind(p, x) returns the root parent of the set
% containing index x, given parent-list p. The
% speed is O(lon(n)).
y = x;
while y ~= p(y)
y = p(y);
end
z = p(y);
% ---------- slink ---------- %
function [p, rank] = slink(x, y, p, rank)
% slink -- Link two sets.
% [p, rank] = slink(x, y, p, rank) links two sets,
% whose roots are x and y, using parent array p,
% and rank(x), a measure of the depths of the
% tree from root x. The speed is O(n).
if rank(x) < rank(y)
p(x) = y;
else
if rank(y) < rank(x)
p(y) = x;
else
p(x) = y;
rank(y) = rank(y) + 1;
end
end
% ---------- elapsed ---------- %
function elapsed(thePrecision)
% elapsed -- Print elapsed time.
% elapsed(thePrecision) displays the "toc" elapsed
% time, with the given precision, in decimal seconds
% (default = 1). Use "tic" to initiate the timer.
% Copyright (C) 2001 Dr. Charles R. Denham, ZYDECO.
% All Rights Reserved.
% Disclosure without explicit written consent from the
% copyright owner does not constitute publication.
% Version of 18-Jun-2001 06:41:43.
% Updated 18-Jun-2001 07:39:59.
if nargin < 1, thePrecision = 1; end
if ischar(thePrecision), thePrecision = eval(thePrecision); end
try
t = fix(toc / thePrecision) * thePrecision;
disp([' ## Elapsed time: ' num2str(t) ' s.'])
catch
disp(' ## Please call "tic" first.')
end