用于处理的大数据集,需要维护原始数据集

时间:2013-06-03 16:42:34

标签: c++ image-processing visual-studio-2005 large-data

这是我的问题定义:我有一个七百万个索引的数组,每个都包含一个标签。因此,为简单起见,这是我正在处理的一个示例数组:[1 2 3 3 3 5 2 1 7]。

我需要浏览这个数组,每次遇到标签时,都要将标签的位置输入到“set”中,其他所有标签都是相同的。由于数组太大,我想在任何给定点只访问特定标签的位置,所以我想说,我只想访问3的位置并处理这些位置并将它们更改为5,但我想做更多不仅仅是一个操作而且不仅如此,我想分别在所有标签上进行操作。在我的例子中的一个小数组中,坚持使用数组似乎微不足道。然而,如果有一个七百万点的数组,那么完成对所述标签的搜索然后对它们进行操作要花费更多的时间。

为了消除混淆,使用我的示例,我希望示例数组能够提供以下内容:

  • 1映射到包含0和7
  • 的集合
  • 2映射到包含1和6
  • 的集合
  • 3映射到包含2,3和4的集合
  • 5映射到包含5
  • 的集合

最初,我在原始阵列上进行了处理,只是在阵列上进行操作。这需要大约约30秒来确定每个标签的相应索引的数量(因此我能够确定1的大小是2,大小6是2,大小3是3等等。但是,它没有使用这种方法产生所述标签的位置。因此,在我的剩余处理过程中增加了时间来找到每个标签的位置,尽管通过添加终止点来加速,一旦找到所引用标签的所有索引,停止搜索。

下一步,我使用了map<int,set<int>>,但这最终导致时间增加到约100秒,但是后来处理的时间减少了,但还不足以证明时间的大幅增加。

我还没有实现它,但作为一个额外的步骤,我计划尝试初始化一组数组,索引对应于标签并尝试使用此方法。

我也尝试过hash_maps也无济于事。 Visual Studio 2005中的STL中不包含Unordered_sets和unordered_maps,因此我没有使用这两种结构实现上述功能。

要点: 我已经预处理了数组,因此我知道最大标签,并且所有标签都是连续的(最小标签和最大标签之间没有间隙)。但是,它们随机分散在原始数组中。这可以证明在设置大小数据结构的初始化中是有用的。 与标签对应的索引的顺序并不重要。其给定数据结构中的标签顺序也不重要。

编辑: 对于背景,数组对应于二进制图像,我实现了二进制顺序标记,以输出与UINT16的二进制图像大小相同的数组,并标记所有二进制blob。我现在要做的是尽可能有效地获得构成每个斑点的点的地图。

2 个答案:

答案 0 :(得分:1)

为什么要为这项任务使用这种复杂的数据结构?只需创建一个矢量矢量来存储每个标签的所有位置,就是这样。而且,您还可以通过预处理每个标签所需的空间来避免烦人的矢量内存分配。这样的事情:

vector <int> count(N);
for(size_t i = 0; i < N; ++i)
    ++count[dataArray[i]];
vector < vector <int> > labels(N);
vector <int> last(N);
for(size_t i = 0; i < N; ++i)
    labels[i].resize(count[i]);
for(size_t i = 0; i < N; ++i) {
    labels[dataArray[i]][last[dataArray[i]]] = i;
    ++last[dataArray[i]];
}

它将在O(N)时间内工作,对于你的七百万个整数看起来像1秒。

答案 1 :(得分:0)

我不一定会使用通用映射(或哈希表)。

我最初的直觉是,我创建了第二个数组“位置”七百万(或任何N)位置,第三个数组“last_position_for_index”对应于范围[min-label,max-label]。请注意,这几乎肯定会比任何类型的地图占用更少的存储空间。

将last_position_for_index的所有条目初始化为某个保留值,然后您可以通过类似(未经测试)的方式遍历数组:

for (std::size_t k = 0; k<N; ++k) {
  IndexType index = indices[k];
  positions[k] = last_position_for_index[index-min_label];
  last_position_for_index[index-min_label] = k;
}