微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

找到连接的节点集群的算法

如何解决找到连接的节点集群的算法

我正在处理 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]
]

Example of connected vertices

解决方法

您可以使用 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 举报,一经查实,本站将立刻删除。