语言:MATLAB
问题定义:
我在太空中有一组2D点。我想根据他们的欧氏距离对点进行分组。我的数据有一个属性,即两个组总是至少相隔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 任何其他比Triangulation更快获得组的替代方法也会很棒!
提前谢谢