【发布时间】:2017-11-12 01:38:13
【问题描述】:
我正在尝试开发一个连接组件算法的修改,作为这个问题的答案:Connected Component Labelling。
基本上,我有由 0 和 1 组成的 2d 和 3d 矩阵。我的问题是找到 1 的连接区域,分别标记每个区域。矩阵大小可能非常大(由 2-d 中的 5e4×5e4 元素和 3d 中的 1000^3 个元素组成)。所以我需要一些不会给堆栈内存带来压力的东西,而且它的速度足够快,可以在模拟过程中重复几次。
使用深度优先搜索对该问题的最受好评的答案给出了堆栈溢出错误(如评论中所述)。我一直在尝试使用另一个用户建议的联合查找算法。
原始代码(由用户 Dukeling 编写)非常适用于大型二维矩阵,但我希望元素之间有对角线连接。这是我的代码,以及我尝试使用的示例输入:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
const int w = 8, h = 8;
int input[w][h] = {{1,0,0,0,1,0,0,1},
{1,1,0,1,1,1,1,0},
{0,1,0,0,0,0,0,1},
{1,1,1,1,0,1,0,1},
{0,0,0,0,0,0,1,0},
{0,0,1,0,0,1,0,0},
{0,1,0,0,1,1,1,0},
{1,0,1,1,0,1,0,1}};
int component[w*h];
void doUnion(int a, int b)
{
// get the root component of a and b, and set the one's parent to the other
while (component[a] != a)
a = component[a];
while (component[b] != b)
b = component[b];
component[b] = a;
}
void unionCoords(int x, int y, int x2, int y2)
{
if (y2 < h && x2 < w && input[x][y] && input[x2][y2] && y2 > 0 && x2 > 0)
doUnion(x*h + y, x2*h + y2);
}
int main()
{
int i, j;
for (i = 0; i < w*h; i++)
component[i] = i;
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
unionCoords(x, y, x+1, y);
unionCoords(x, y, x, y+1);
unionCoords(x, y, x+1, y+1);
unionCoords(x, y, x-1, y+1);
unionCoords(x, y, x+1, y-1);
unionCoords(x, y, x-1, y-1);
}
// print the array
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
if (input[x][y] == 0)
{
printf("%4d ",input[x][y]);
continue;
}
int c = x*h + y;
while (component[c] != c) c = component[c];
printf("%4d ", component[c]);
}
printf("\n");
}
}
如您所见,我添加了 4 个命令来实现元素之间的对角连接。这是对联合查找算法的有效修改吗?我特别搜索了谷歌和stackoverflow,但我找不到任何对角连接的例子。此外,我想将其扩展到 3 个维度 - 所以我需要添加 26 个命令进行检查。这种方式会很好地扩展吗?我的意思是代码似乎适用于我的情况,但有时我会随机得到一个未标记的孤立元素。我不想将它与我的代码集成,只是为了在几个月后发现一个错误。
谢谢。
【问题讨论】:
-
您可以重写一个函数以将数组用作堆栈而不是递归,然后您不会用完数组,直到内存不足。如果你有 goto 可用,而不是调用函数,推送一些返回地址的标记,将其参数推送到堆栈上,然后转到它的开始。一开始,从堆栈中弹出参数并继续。要返回,请弹出返回地址并前往那里。如果您没有 goto,请将函数转换为 while 循环。虽然堆栈上有任何事情要做,但尽你所能,将递归调用转换为将 todo 对象推送到堆栈。
-
嗨,我确实是用数组做的。因此,在 2d 中,函数递归调用元素的四个邻居。它很快就耗尽了内存。我还将堆栈大小调整为最大允许限制。
标签: algorithm matrix connected-components