是否有算法来确定网格中连续的彩色区域?

时间:2009-01-16 23:58:10

标签: algorithm cellular-network

给定一个基本网格(就像一张方格纸),其中每个单元格随机填充n种颜色中的一种,是否有一个可靠的算法可以告诉我哪些连续区域(单元格组)在侧面连接的相同颜色)有?让我们说n是合理的,比如5。

我有一些想法,但他们都感到非常低效。

7 个答案:

答案 0 :(得分:8)

最好的算法是O(单元格数),与颜色数无关。

这可以通过遍历单元格来实现,并且每次访问尚未标记为已访问的单元格时,执行图形遍历以查找该区域中的所有连续单元格,然后继续迭代。

编辑:

这是深度优先搜索的简单伪代码示例,这是一个易于实现的图遍历:

function visit(cell) {
    if cell.marked return
    cell.marked = true
    foreach neighbor in cell.neighbors {
        if cell.color == neighbor.color {
            visit(neighbor)
        }
    }
}

答案 1 :(得分:5)

除了递归的递归回答之外,如果递归太慢,你可以使用堆栈:

function visit(cell) {
    stack = new stack
    stack.push cell

    while not stack.empty {
        cell = stack.pop
        if cell.marked continue
        cell.marked = true
        foreach neighbor in cell.neighbors {
            if cell.color == neighbor.color {
                stack.push neighbor
            }
        }
    }
}

答案 2 :(得分:3)

您可以尝试在每个广场上进行洪水填充。当泛滥传播时,将数组中的网格方块记录下来,然后用未使用的颜色(例如-1)对它们进行着色。

答案 3 :(得分:3)

关于洪水填充的维基百科文章可能对您有用:http://en.wikipedia.org/wiki/Flood_fill

答案 4 :(得分:2)

Union-find也适用于此。实际上,您可以将问题表示为关于图形的问题:顶点是网格单元格,如果网格单元格具有相同的颜色,则两个顶点相邻。您正在尝试查找已连接的组件。

使用union-find数据结构的方式如下:首先创建一个union-find数据结构,其中包含与单元格一样多的元素。然后遍历单元格,并union两个相邻单元格,如果它们具有相同的颜色。最后,在每个单元格上运行find并存储响应。具有相同find的单元格位于相同的连续彩色区域。

答案 5 :(得分:0)

如果你想要更精细的颗粒控制,你可以考虑使用A*算法并使用启发式来包含类似颜色的瓷砖。

答案 6 :(得分:0)

您在扫描线中的各个区域进行迭代,从上到下从左到右。对于每个单元,您将创建一个单元列表,这些单元在单元之间共享为同一内存对象。对于每个单元格,将当前单元格添加到列表中(与其共享或创建)。然后,如果右侧或下方的单元格具有相同的颜色,则您将与该单元格共享该列表。如果该单元格已经有一个列表,则可以合并列表,并将列表中列出的每个单元格中对列表对象的引用替换为新的合并列表。

然后位于每个单元格中的是对包含该单元格的每个连续单元格的列表的引用。这适当地结合了每个单元之间的泛洪工作。而不是对每个单元重复它。由于您具有列表,所以用合并的数据替换数据只是在列表中进行迭代。它将是O(n * c),其中n是像元数,c是图形连续性的量度。完全分离的网格将是n次。一个完全连续的1色图,其中n为2 ^ 2。