在随机分离的数据上标记连接的组件
Connected Component Labelling over Randomly Separated Data?
我目前的任务是在数据库系统中实现CCL算法(用C++编写)。此算法将为超过阈值的给定多维数组的所有值分配一个标签,相邻的标记值将具有相同的标签。
编写基本的 CCL 算法并不困难,但在我的域中,输入数组在数据库的多个实例中随机分区。调用我的 CCL 运算符时,每个实例对其负责的数据块执行操作并返回其本地 CCL 结果。然后将这些局部结果合并以产生最终结果。
我不知道在运行时哪个实例负责数组的任何给定部分,并且在最后的合并步骤之前,这些实例无法相互通信。
-=-=-=-
目前,我通过执行以下操作来工作:
每个实例创建一个布尔值数组,其大小等于数组中的项数,并将所有值设置为 FALSE。
每个实例都会经历它负责的值和检查这些值是否超过阈值;如果是,他们将本地数组中的相应布尔值更改为 TRUE。
这些实例都将其数组发送给协调器,协调器由协调器发送使用 OR 组合结果以创建最终布尔向量。
协调器遍历数组中的每个值,跳过已标记的值。如果未标记该值,并且对应于该值的布尔值为 true,它为其分配了一个新标签并递归分配其所有邻居(以及邻居的邻居等)相同的标签。
返回标签向量。
上述算法有效,但唯一利用多个实例的是阈值计算。因为这个实现只是收集所有内容并在协调器上扫描它,所以它首先破坏了使用多个实例的意义。
-=-=-=-
从本质上讲,这种算法正在自动变成一种分而治之的算法,但划分是完全且不可控的随机的。
我们希望利用这种划分,在每个实例上执行 CCL 的两次扫描,然后在协调器上组合这些本地 CCL 结果;也就是说,如果两个实例生成彼此相邻的标签组,我们希望合并这两个标签而不再次扫描每个值。这个斜体点给我们带来了最大的麻烦,我们对如何进行感到迷茫。如果有人对算法或数据结构有很好的建议,将不胜感激。
相邻连接的组件(与图形连接的组件相反)需要检查所有相邻(相邻像素)对的集合。
那是
- 在相邻的点对上定义集合:
-
{ ((x1, y1), (x2, y2)) }
- 对于 4 连接:
(abs(x2 - x1) + abs(y2 - y1)) <= 1
和(x1 != x2 && y1 != y2)
- 对于 8 连接:
max(abs(x2 - x1), abs(y2 - y1)) <= 1
和(x1 != x2 && y1 != y2)
- 对于 4 连接:
-
理解的下一步需要知道等价关系。值得注意的是,它必须满足:
- 自反 性
- 对称
- 传递
这三个要求有一个有趣的结果:
- 假设给你一个等价关系的部分列表,例如 (a, b), (b, c), (c, d), (e, f)
- 请注意,排列此列表、插入"等效"等价关系(例如 (a, c) 假设 (a, b) 和 (b, c) 已经存在)等,不会影响分区。
采取的一点是,下面要讨论的"脱节集"的算法接口正是等价关系的列表。因此,人们可以以不同的方式处理这个等价关系列表,并且仍然得到相同的结果。
为了表示和描述计算和处理连接组件的算法,应该研究脱节集。
人们应该学习脱节集的实际实现,并学习如何从连接的组件算法中实际使用(调用)它。
之后,应该提高理解的抽象水平——脱节集的抽象概念(算法接口)。在学习了这个抽象之后,你将能够以不寻常的方式重新实现脱节集。
- 在构建阶段,只需要从主循环调用
Union
函数。 Find
函数仅在Union
函数中使用。- 因此,可以通过为
Union( (x1, y1), (x2, y2) )
消息调用流提供接收器来抽象出 Disjoint-Set 的操作。 - 这些消息调用可以是异步的、排队的、随机排列的、批处理的,但您希望如何处理它们,只要最终完整地处理所有这些调用。
- 这将导致对
Union
的冗余调用,因为在排队调用之前不会检查两个节点是否已经是相同的标签。这个问题将在下一部分讨论。
现在,我们将介绍一种调度这些Union
消息进行处理的方法。
假设节点分布到不同的计算机。
- 我们将相邻像素对的集合
{ ((x1, y1), (x2, y2)) }
如下:- 对于每台机器,我们希望找到驻留在同一台机器上的相邻像素对的子集。
- 之后,我们想要其他所有内容的子集 - 驻留在两台独立机器上的相邻像素对。
要跨不同的机器处理联合查找,只需 * 从同一组相邻像素对的同一台机器生成Union
消息 *然后,过滤Union
消息以删除多余的消息。 * 从相邻像素对的不同机器集合生成Union
消息。 * 对同一机器消息的结果执行不同的机器消息。
这个答案是用过于抽象的方式写的,因为更具体的答案需要更多关于问题的细节,尤其是关于"完全和不受控制的随机分区"的部分。
- 到连接组件算法的问题(递归)
- 使用 bfs 解决连接组件问题时得到错误的答案
- 将无向连接图分解为两个组件
- 连接的组件程序产生不正确的输出
- 查找每个连接组件区域的邻域
- 根据现有的标签(而不是二进制图像)查找使用 OpenCV 连接的组件
- 如何在OpenCV中对连接组件进行分割
- OpenCV 3.4.0 中带有 cuda 的连接组件(在 GPU 上)
- 在一个DFS中查找Di-Graph中的强烈连接组件
- OpenCV 中的连接组件
- 使用带有笛卡尔点的升压连接组件
- C++ 中无向图中的连接组件
- 用于 SPOJ 底部的强连接组件
- OpenCV如何在二进制图像中查找连接组件的列表
- 连接组件算法输出
- 定义强连接组件
- C++-如何增加堆栈大小以允许Kosaraju算法进行更多递归以计算强连接组件
- DFS:如何在c++中表示连接组件的节点
- 带有STL c++ bug的强连接组件
- 图形连接和连接组件