MATLAB 中的 Disjoint-Set (union-find) 数据结构
Disjoint-Set (union-find) data structure in MATLAB
MATLAB 中有联合查找算法的实现吗?
如果没有,是否可以使用 classdef 或任何其他方法来实现它?
我在网上看了很多,找不到任何 MATLAB 的实现!这是我最后能问的地方了,手会很棒!
提前致谢
一个不相交的集合可以只用向量来实现。 a[u] = ancestor of node u
.
我的实现,使用路径减半和按大小合并来限制树的高度(没有很好地测试):
classdef DJSet < handle
properties
N; root;size;
end
methods
function obj=DJSet(n)
obj.N = n;
obj.root = 1:n;
obj.size = ones(1,n);
end
function root = find(obj, u)
while obj.root(u) ~= u
obj.root(u) = obj.root(obj.root(u));
u = obj.root(u);
end
root = u;
end
function union(obj, u, v)
root_u = obj.find(u);
root_v = obj.find(v);
if root_u == root_v
return;
end
if obj.size(root_u) < obj.size(root_v)
obj.root(root_u) = root_v;
obj.size(root_v) = obj.size(root_v) + obj.size(root_u);
else
obj.root(root_v) = root_u;
obj.size(root_u) = obj.size(root_u) + obj.size(root_v);
end
end
function res = is_connected(obj, u, v)
root_u = obj.find(u);
root_v = obj.find(v);
res = root_u == root_v;
end
end
end
测试用例:
dj=DJSet(10);
edges = [1 2; 3 4; 5 6; 7 8; 2 3; 1 3; 6 7];
for i = 1:size(edges,1)
dj.union(edges(i,1), edges(i,2));
end
for j = 2:10
fprintf('%d and %d connection is %d\n', 1, j, dj.is_connected(1, j));
end
dj.union(3,6);
fprintf('#####\nAfter connecting 3 and 6\n')
for j = 2:10
fprintf('%d and %d connection is %d\n', 1, j, dj.is_connected(1, j));
end
>> test
1 and 2 connection is 1
1 and 3 connection is 1
1 and 4 connection is 1
1 and 5 connection is 0
1 and 6 connection is 0
1 and 7 connection is 0
1 and 8 connection is 0
1 and 9 connection is 0
1 and 10 connection is 0
#####
After connecting 3 and 6
1 and 2 connection is 1
1 and 3 connection is 1
1 and 4 connection is 1
1 and 5 connection is 1
1 and 6 connection is 1
1 and 7 connection is 1
1 and 8 connection is 1
1 and 9 connection is 0
1 and 10 connection is 0
MATLAB 中有联合查找算法的实现吗?
如果没有,是否可以使用 classdef 或任何其他方法来实现它?
我在网上看了很多,找不到任何 MATLAB 的实现!这是我最后能问的地方了,手会很棒!
提前致谢
一个不相交的集合可以只用向量来实现。 a[u] = ancestor of node u
.
我的实现,使用路径减半和按大小合并来限制树的高度(没有很好地测试):
classdef DJSet < handle
properties
N; root;size;
end
methods
function obj=DJSet(n)
obj.N = n;
obj.root = 1:n;
obj.size = ones(1,n);
end
function root = find(obj, u)
while obj.root(u) ~= u
obj.root(u) = obj.root(obj.root(u));
u = obj.root(u);
end
root = u;
end
function union(obj, u, v)
root_u = obj.find(u);
root_v = obj.find(v);
if root_u == root_v
return;
end
if obj.size(root_u) < obj.size(root_v)
obj.root(root_u) = root_v;
obj.size(root_v) = obj.size(root_v) + obj.size(root_u);
else
obj.root(root_v) = root_u;
obj.size(root_u) = obj.size(root_u) + obj.size(root_v);
end
end
function res = is_connected(obj, u, v)
root_u = obj.find(u);
root_v = obj.find(v);
res = root_u == root_v;
end
end
end
测试用例:
dj=DJSet(10);
edges = [1 2; 3 4; 5 6; 7 8; 2 3; 1 3; 6 7];
for i = 1:size(edges,1)
dj.union(edges(i,1), edges(i,2));
end
for j = 2:10
fprintf('%d and %d connection is %d\n', 1, j, dj.is_connected(1, j));
end
dj.union(3,6);
fprintf('#####\nAfter connecting 3 and 6\n')
for j = 2:10
fprintf('%d and %d connection is %d\n', 1, j, dj.is_connected(1, j));
end
>> test
1 and 2 connection is 1
1 and 3 connection is 1
1 and 4 connection is 1
1 and 5 connection is 0
1 and 6 connection is 0
1 and 7 connection is 0
1 and 8 connection is 0
1 and 9 connection is 0
1 and 10 connection is 0
#####
After connecting 3 and 6
1 and 2 connection is 1
1 and 3 connection is 1
1 and 4 connection is 1
1 and 5 connection is 1
1 and 6 connection is 1
1 and 7 connection is 1
1 and 8 connection is 1
1 and 9 connection is 0
1 and 10 connection is 0