如何解决找到连接的节点集群的算法
我正在处理 3d 数据,并提供了一个相互连接的顶点列表。数据格式如下:
faces = [
(0,1,2),(1,3,(3,5,6),(5,7,4),(10,11,12),(11,12,13),(12,13,14)
]
数组中的每一项都由一个三元组组成,其中每个位置的数字表示相互连接的顶点的索引。我在图片中形象化了这个例子,以便更好地理解顶点是如何连接的。
我正在寻找一种简单、易于实现的算法,该算法将 faces
作为输入并在输出时返回以下内容:
[
[0,2,4,6,7],[10,14]
]
解决方法
您可以使用 union-find
我会在这里添加一个简单的版本
未测试的代码
using face = std::array<int,3>;
std::vector<face> faces = {
{0,1,2},{1,3,{3,5,6},{5,7,4},{10,11,12},{11,12,13},{12,13,14}
}
std::unordered_map<int> con;
int Find(int vert) {
while (vert != con[very])
vert = con[vert];
return vert;
}
for (auto triple : faces) {
for (int vert : triple) {
if (!con.count(vert)) {
con[vert]=vert; // i'm my own parent ...
} else {
con[vert] = Find(vert);
}
}
}
std::unordered_map<int,std::vector<int>> clusters
for (auto& pair : con) {
// reduce the search path for nodes that has pair as parent.
int cluster = Find(pair.second);
con[pair.second] = cluster;
clusters[cluster].push_back(pair.first);
}
return clusters; // or convert to vector of vectors
注意如果没有路径减半和有效联合,这将有一个可怕的运行时间。
,Surt 算法是一种可能的解决方案。
由于您的图是无向图并且您正在寻找非常简单的东西,请查看广度优先搜索或深度优先搜索(它们是图论的标准算法,非常易于理解和实现) .
您基本上搜索从起始顶点可到达的每个顶点并将它们标记为同一组。重复这个过程,直到每个顶点都有一个组。
,假设您想将顶点分成彼此均可到达的顶点集,但不能从该集合外的任何顶点到达。
这是算法的伪代码
LOOP
CONSTRUCT empty current set
SELECT V arbitrary vertex
add V to current set
remove V from graph
LOOP // while set is growing
added_to_set = false
LOOP V over vertices in graph
LOOP Vset over current set
IF Vset connected to V
add V to current set
remove V from graph
added_to_set = true
break;
IF added_to_set == false
break; // the set is maximal
ADD current set to list of sets
IF graph has no remaining vertices
OUTPUT sets found
STOP
有关此的 C++ 实现,请参阅 https://github.com/JamesBremner/PathFinder2/blob/dbd6ff06edabd6a6d35d5eb10ed7972dc2d779a6/src/cPathFinder.cpp#L483
中的代码版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。