1 | %KMST Finds K Minimum Spanning Trees based on a Distance Matrix
|
---|
2 | %
|
---|
3 | % [L,DL,D] = KMST(D,K,P)
|
---|
4 | %
|
---|
5 | % INPUT
|
---|
6 | % D NxN Symmetric dissimilarity matrix or dataset
|
---|
7 | % K Number of minimum spanning trees (optional, default: 1)
|
---|
8 | % P Object number, P = 1..N (optional, default: object P with the
|
---|
9 | % largest distances to all other objects)
|
---|
10 | %
|
---|
11 | % OUTPUT
|
---|
12 | % L K(N-1)x2 List of edges in the minimum spanning tree
|
---|
13 | % DL K(N-1)x1 List of the corresponding minimal distances
|
---|
14 | % D NxN Dissimilarity matrix (dataset) with removed edges of L
|
---|
15 | % (set to INF)
|
---|
16 | % DEFAULT
|
---|
17 | % K = 1
|
---|
18 | % P = Object number which has the largest distances to all other objects
|
---|
19 | %
|
---|
20 | % DESCRIPTION
|
---|
21 | % Finds K minimum spanning trees (MSTs) based on the given symmetric distance
|
---|
22 | % matrix D. D(i,j)=INF and D(j,i)=INF denote the lack of edge (connection)
|
---|
23 | % between i and j. Starting from the first MST, the procedure finds the
|
---|
24 | % current MST and then removes all the edges from D. It repeats until K MSTs
|
---|
25 | % are determined. The search for MSTs starts from the object P. The result does
|
---|
26 | % not depend on P, however, the ordering does.
|
---|
27 | %
|
---|
28 | % The implementation relies on the Prim's algorithm.
|
---|
29 | %
|
---|
30 | % SEE ALSO
|
---|
31 | % PLOTGRAPH, DISTGRAPH, GRAPHPATH
|
---|
32 |
|
---|
33 | % Copyright: Elzbieta Pekalska, ela.pekalska@googlemail.com
|
---|
34 | % Faculty EWI, Delft University of Technology and
|
---|
35 | % School of Computer Science, University of Manchester
|
---|
36 |
|
---|
37 |
|
---|
38 |
|
---|
39 | function [L,d,D] = kmst(D,k,p)
|
---|
40 |
|
---|
41 | if nargin < 3,
|
---|
42 | [ss,p]= max(sum(+D));
|
---|
43 | end
|
---|
44 |
|
---|
45 | if nargin < 2,
|
---|
46 | k = 1;
|
---|
47 | end
|
---|
48 |
|
---|
49 | [n,m] = size(D);
|
---|
50 | if n ~= m,
|
---|
51 | error('D should be a square matrix.');
|
---|
52 | end
|
---|
53 | prec = 1e-12;
|
---|
54 | if ~issym(D,prec),
|
---|
55 | prwarning(1,'D should be symmetric. It is made so by averaging.');
|
---|
56 | end
|
---|
57 | D = 0.5*(D+D');
|
---|
58 |
|
---|
59 | if p < 0 | p > n | p ~= round(p),
|
---|
60 | error(['P should be an integer in [1,' int2str(n) ']']);
|
---|
61 | end
|
---|
62 | if k < 0 | k > n | k ~= round(k),
|
---|
63 | error(['K should be an integer in [1,' int2str(n) ']']);
|
---|
64 | end
|
---|
65 |
|
---|
66 | isdset = isdataset(D);
|
---|
67 |
|
---|
68 | if isdset,
|
---|
69 | DD = D;
|
---|
70 | D = +D;
|
---|
71 | end
|
---|
72 | L = [];
|
---|
73 | d = [];
|
---|
74 | for z=1:k
|
---|
75 | Lmst = zeros(n-1,2);
|
---|
76 | dmst = zeros(n-1,1);
|
---|
77 | Z = setdiff(1:n,p);
|
---|
78 | [dmst(1),z] = min(D(p,Z));
|
---|
79 | Lmst(1,:) = [p Z(z)];
|
---|
80 | for i=2:n-1
|
---|
81 | LL = Lmst(1:i-1,:);
|
---|
82 | Jmst = unique(LL(:))';
|
---|
83 | J = setdiff(1:n,Jmst);
|
---|
84 | [Dmin,Z] = min(D(Jmst,J),[],2);
|
---|
85 | [dmst(i),k] = min(Dmin);
|
---|
86 | Lmst(i,:) = [Jmst(k) J(Z(k))];
|
---|
87 | end
|
---|
88 |
|
---|
89 | LL = [Lmst; Lmst(:,[2 1])];
|
---|
90 | %for u=1:length(LL), D(LL(u,1),LL(u,2)) = inf; end
|
---|
91 | D((LL(:,2)-1)*n+LL(:,1)) = inf;
|
---|
92 |
|
---|
93 | L = [L; Lmst];
|
---|
94 | d = [d; dmst];
|
---|
95 | end
|
---|
96 |
|
---|
97 | if isdset,
|
---|
98 | D = setdata(DD,D);
|
---|
99 | end
|
---|
100 | return;
|
---|