source: distools/kmst.m @ 118

Last change on this file since 118 was 10, checked in by bduin, 14 years ago
File size: 2.5 KB
RevLine 
[10]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
39function [L,d,D] = kmst(D,k,p)
40
41if nargin < 3,
42  [ss,p]= max(sum(+D));
43end
44
45if nargin < 2,
46  k = 1;
47end
48
49[n,m] = size(D);
50if n ~= m,
51  error('D should be a square matrix.');
52end
53prec = 1e-12;
54if ~issym(D,prec),
55  prwarning(1,'D should be symmetric. It is made so by averaging.');
56end
57D = 0.5*(D+D');
58
59if p < 0 | p > n |  p ~= round(p),
60  error(['P should be an integer in [1,' int2str(n) ']']);
61end
62if k < 0 | k > n | k ~= round(k),
63  error(['K should be an integer in [1,' int2str(n) ']']);
64end
65
66isdset = isdataset(D);
67
68if isdset,
69  DD = D;
70  D  = +D;
71end
72L  = [];
73d  = [];
74for 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];
95end
96
97if isdset,
98  D = setdata(DD,D);
99end
100return;
Note: See TracBrowser for help on using the repository browser.