在 Matlab 中删除超集的问题
Issue in deleting supersets in Matlab
我有一组数据,其中包含我想删除的超集,其子集如下所示:
a{1} = [5]
a{2} = [4 11 14]
a{3} = [1]
a{4} = [5 16]
a{5} = [5]
a{6} = [11 16]
a{7} = [11]
a{8} = [16]
a{9} = [9 14 17]
a{10} = [14]
[ii, jj] = ndgrid(1:numel(a));
s = cellfun(@(x,y) all(ismember(x,y)), a(ii), a(jj));
s = triu(s,1); %// count each pair just once, and remove self-pairs
similarity = a(~any(s,1));
celldisp(similarity)
结果如下:
a{1} = [5]
a{2} = [4 11 14]
a{3} = [1]
a{4} = [11 16]
a{5} = [11]
a{6} = [16]
a{7} = [9 14 17]
a{8} = [14]
如输出所示,仍然有应该删除的超集,即 a{2}
因为 a{5}
包含 11
这是它的子集,a{4}
应该被删除,因为 a{5}
包含 11
和 a{6}
包含 16
以及 a{7}
也应该删除,因为 a{8}
包含子集 14
。
预期输出是
a{1} = [5]
a{2} = [1]
a{3} = [11]
a{4} = [16]
a{5} = [14]
任何人都可以帮助修复此代码,以便我可以获得准确的结果集。谢谢
我认为你需要使用下三角部分而不是上三角部分:
s = tril(s,-1); % instead of s = triu(s,1);
编辑
仅当超集总是出现在子集之前时,保留下三角部分才有效。这是一个应该始终可以正常工作的通用版本。
[ii, jj] = ndgrid(1:numel(a));
s = cellfun(@(x,y) all(ismember(x,y)), a(ii), a(jj));
% Set diagonal to zero.
s = s - diag(diag(s));
% Indicator matrix for sets that are exactly equal.
same = s & s';
% For equal sets keep only the first occurence.
keep = triu(same) | ~same.*s;
% Delete supersets.
similarity = a(~any(keep,1));
celldisp(similarity)
顺便说一句,用运行一个双循环代替上面的矩阵运算可能更容易。
我有一组数据,其中包含我想删除的超集,其子集如下所示:
a{1} = [5]
a{2} = [4 11 14]
a{3} = [1]
a{4} = [5 16]
a{5} = [5]
a{6} = [11 16]
a{7} = [11]
a{8} = [16]
a{9} = [9 14 17]
a{10} = [14]
[ii, jj] = ndgrid(1:numel(a));
s = cellfun(@(x,y) all(ismember(x,y)), a(ii), a(jj));
s = triu(s,1); %// count each pair just once, and remove self-pairs
similarity = a(~any(s,1));
celldisp(similarity)
结果如下:
a{1} = [5]
a{2} = [4 11 14]
a{3} = [1]
a{4} = [11 16]
a{5} = [11]
a{6} = [16]
a{7} = [9 14 17]
a{8} = [14]
如输出所示,仍然有应该删除的超集,即 a{2}
因为 a{5}
包含 11
这是它的子集,a{4}
应该被删除,因为 a{5}
包含 11
和 a{6}
包含 16
以及 a{7}
也应该删除,因为 a{8}
包含子集 14
。
预期输出是
a{1} = [5]
a{2} = [1]
a{3} = [11]
a{4} = [16]
a{5} = [14]
任何人都可以帮助修复此代码,以便我可以获得准确的结果集。谢谢
我认为你需要使用下三角部分而不是上三角部分:
s = tril(s,-1); % instead of s = triu(s,1);
编辑
仅当超集总是出现在子集之前时,保留下三角部分才有效。这是一个应该始终可以正常工作的通用版本。
[ii, jj] = ndgrid(1:numel(a));
s = cellfun(@(x,y) all(ismember(x,y)), a(ii), a(jj));
% Set diagonal to zero.
s = s - diag(diag(s));
% Indicator matrix for sets that are exactly equal.
same = s & s';
% For equal sets keep only the first occurence.
keep = triu(same) | ~same.*s;
% Delete supersets.
similarity = a(~any(keep,1));
celldisp(similarity)
顺便说一句,用运行一个双循环代替上面的矩阵运算可能更容易。