【发布时间】:2015-06-12 12:55:50
【问题描述】:
语言:MATLAB
问题防御:
我在空间中有一组二维点。我想根据欧几里得距离对点进行分组。我的数据有一个属性,即两组总是至少被 R 个单位分开。因此对于一个给定的点,所有接近 50 个单位的点都可以被认为是它的邻居。组合具有共同邻居的点将产生组(至少是这个想法)。
建议方法:
在 matlab 中使用 delaunay 三角剖分并获取生成的三角形的边列表。删除所有大于 R 个单位的边。剩下的每一组点都是我正在寻找的组。剩余的未连接点可以忽略。
尝试: 我试图在 MATLAB 中实现上述内容,但在对剩余点进行分组时犯了一个错误。我附上我的代码。
DT = delaunayTriangulation(double(frame(:,1:2)));
edgeList = edges(DT);
edgeVertex1 = frame(edgeList(:,1),:);
edgeVertex2 = frame(edgeList(:,2),:);
dVec = edgeVertex1 - edgeVertex2;
edgeLengths = sqrt(sum(abs(dVec).^2,2));
requiredEdges = edgeLengths < NEIGH_RADIUS;
edgeLengthsFiltered = edgeLengths(requiredEdges);
edgeListFiltered = edgeList(requiredEdges,:);
% Clustering
edgeOrigins = edgeListFiltered(:,1);
edgeEndings = edgeListFiltered(:,2);
nodeList = unique(edgeOrigins);
if isempty(nodeList)
Result = struct([]);
super_struct(i).result = Result;
else
groups = cell(10,1);
groups{1} = nodeList(1);
groupLength = 2;
flag = 0;
% grouping
for j = 1:1:length(nodeList);
neighbourList = [nodeList(j); edgeEndings(edgeOrigins==nodeList(j))];
% add current node as part of neighbourList
for k = 1:1:groupLength-1
te = ismembc(groups{k}, neighbourList);
if sum(te) ~=0
temp = sort([groups{k}; neighbourList]);
groups{k} = temp([true;diff(temp(:))>0]);
flag = 1;
break;
end
end
if ~flag
groups{groupLength} = neighbourList;
groupLength = groupLength + 1;
end
flag = 0;
end
largeGroups = cell(1,1);
largeGroups_c = 1;
for j = 1:1:groupLength -1;
if ~ isempty(groups{j})
for k = j+1:1:groupLength - 1
te = ismembc(groups{j}, groups{k});
if sum(te) ~= 0
temp = sort([groups{j}; groups{k}]);
groups{j} = temp([true;diff(temp(:))>0]);
groups{k} =[];
end
end
% ignore small groups
if length(groups{j}) > MIN_PTS_IN_GROUP
largeGroups{largeGroups_c} = groups{j};
largeGroups_c = largeGroups_c+1;
end
end
end
在上面的代码中,frame 是具有点列表的变量。常量NEIGH_RADIUS 代表问题中的R。另一个常量MIN_PTS_IN_GROUP 是用户定义的,用于选择将其视为感兴趣集群所需的最小点数。
当我运行上述代码时,仍然存在单组点仍表示为多组的情况。
红线与上面代码所标识的单个组相邻。显然存在错误的交叉组。
问题 1 有人可以提出更好(和正确)的分组方式吗?
问题 2 任何其他比三角测量更快地获得组的替代方法也会很棒!
提前谢谢你
【问题讨论】:
-
你提前知道有多少组吗?
-
没有。组数未知。
-
构建长度小于
R的边图,通过this answer获取连通分量。 -
@knedlsepp 你的建议奏效了。谢谢你。获得连接的组件是我真正想要的。我也对解决问题的替代方法感兴趣(即不使用三角测量)。
-
也许你可以通过只使用以下边缘来加速它:
edges = knnsearch(frame,frame,'K',2)而不是 delaunay-edges。然而,就计算复杂性而言,您的 delaunay 方法应该已经相当不错了。
标签: matlab nearest-neighbor delaunay