如何有效地存储等价(来自连通分量标记算法)?

时间:2012-01-15 20:32:24

标签: c++ performance algorithm data-structures

我想存储来自Connected-component labeling algorithm的等价物。它基本上是从一个值(一个标签的ID)到多个值(来自与前者相同的标签的ID)制作一种地图。

我已经做过类似的事情,但效果不好:

std::map<unsigned short, std::list<unsigned int>> equivalences;
for(int i = 0; i < MAX_NUMBER_OF_LABELS; ++i )
{
    std::list<unsigned int> temp;
    temp.push_back(i);
    // note that a label is equivalent to itself
    equivalences.insert( std::pair< int, std::list<unsigned int>>(i, temp) );
}

然后我通过以下方式添加适当的等价物:

equivalences.at( i ).push_back( equivalent_labels_int );

这种方法的主要缺点是我必须预先声明map的大小(它必须足够大),然后对于大尺寸(例如9999),初始化时间大约是2.5秒。

任何人都有更好的主意吗?

2 个答案:

答案 0 :(得分:3)

我认为Disjoint set forests是您正在寻找的东西。 以下是此数据结构的a better description

答案 1 :(得分:3)

您无需在C ++(或大多数语言)中预先调整map的大小。 map可以通过添加新元素来动态增长,因此如果找到新密钥,您始终可以将其添加到地图中。例如:

equivalences[i].push_back(equivalent_labels_int);

这是有效的,因为map的方括号运算符(operator[])会自动使用给定键向map添加新的键/值对,如果有的话,则为默认值尚不存在。

此外,我建议不要使用list作为存储连接blob序列的容器。当你不需要随机访问并经常删除序列中间的元素时,list很好,我认为你实际上并没有在这里做。相反,我建议使用vectordeque,因为这些结构更节省空间并且具有更好的局部性。

最后,根据您的特定需求,您可能希望完全切换数据结构。如果您的算法通过从某个起点运行深度优先搜索然后存储它遇到的所有结果来工作,那么您现在拥有的方法可能非常好。但是,如果您的算法通过查找相似的点对然后将它们包含的blob合并在一起来工作,那么您可能对disjoint-set forest data structure感兴趣,{{3}}具有简单的实现但性能非常好。也就是说,使用这种结构会使您无法检查连接到给定点的点,但效率的提升非常显着。

希望这有帮助!