【问题标题】:Implementing a set cover data structure实现一个集合覆盖数据结构
【发布时间】:2013-10-03 12:21:40
【问题描述】:

我想实现一个代表抽象数据类型"cover of a set"的数据结构。集合的元素由整数索引表示,子集也是如此。每个元素uint64_t e 被分配到至少一个但可能是多个子集uint64_t s。这可以通过将子集索引存储在std::vector 中来实现。任何元素将被分配到的子集的数量通常远小于元素的总数。

性能(时间和内存)很重要,那么您会推荐哪种实现方式?

  1. std::vector<std::vector<uint64_t>>
  2. std::vector<std::unordered_set<uint64_t>>
  3. std::vector<std::set<uint64_t>>
  4. 还有什么?

常用操作包括:

  • 将元素分配给子集
  • 从子集中删除一个元素(并可能将其移动到另一个)
  • 检查元素是否是特定子集的成员
  • 获取元素所属的所有子集
  • 对特定子集的所有元素进行高效迭代会很好,但我认为这与其他目标相冲突

【问题讨论】:

  • 性能取决于您要对此数据结构执行的操作。请提供有关您的用例的更多信息。
  • @nosid 增加频繁操作。

标签: c++ data-structures c++11 set


【解决方案1】:

您可以尝试阅读 Matt Austern 的论文Segmented Iterators and Hierarchial Algorithms。他讨论了如何有效地处理container<container<T>> 形式的分层数据结构。需要解决的一个问题是迭代,就好像你有一个平面container<T>。为此,标准库算法需要专门用于所谓的分段迭代器

分段迭代器是一种两级数据结构,除了执行顶级迭代之外,还包含一个局部迭代器以更深一层。因为这些局部迭代器本身也可以是分段迭代器,这允许任意嵌套的数据结构(例如树和图)。

离散集的集覆盖可以构造为std::vector<std::set<T>>。将 STL 算法应用于这样的容器要么很麻烦,要么需要分段迭代器和分层算法。不幸的是,标准库和 Boost 都没有真正实现这一点,所以你有一些工作要做。

【讨论】:

    【解决方案2】:

    最快的是一对数据结构:

    std::vector< std::unordered_set<X> > set_to_elements;
    std::unordered_map< X, std::unordered_set<std::size_t> > element_to_sets;
    

    两人保持一致。 boost 多索引容器可能能够更有效地执行此双向操作。

    将元素分配给子集

    set_to_elements[subset].insert(element);
    element_to_sets[element].insert( subset );
    

    从子集中删除一个元素(并可能将其移动到另一个)

    set_to_elements[subset].erase(element);
    element_to_sets[element].erase( subset );
    

    检查一个元素是否是特定子集的成员

    return set_to_elements[subset].find(element) != set_to_elements[subset].end();
    

    或 返回 element_to_sets[element].find(subset) != element_to_sets[element].end(); 获取元素所属的所有子集

    return element_to_sets[element];
    

    对特定子集的所有元素进行有效迭代会很好,但我认为这与其他目标冲突

    return set_to_elements[subset];
    

    所有操作都是常数时间和线性内存。内存和时间要求大约是只需要上述最后两个之一的紧凑型的两倍。

    缓存[] 操作结果的微优化应该在实际代码中完成,如果它实际上是性能敏感的。将迭代器从一个容器存储到另一个容器,以使操作 #1 和 #2 更快,是可选的,并且可能会使它们更快一点,但我不会打扰。

    【讨论】:

      猜你喜欢
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2015-05-22
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多