c++ - 如何计算unordered_set c++中的冲突

标签 c++ hashset unordered-set

这个问题在这里已经有了答案:





How to identify whether or not std::unordered_map has experienced hash collisions?

(1 个回答)


去年关闭。




我想计算一些关于我的哈希函数的统计数据(比如最大/平均碰撞量)。我编写了虚拟散列函数(将所有键映射到 1)并等待查看等于键数量的最大/平均冲突数。但是我对不同的功能有相同的数字。有人可以解释一下吗?
代码:

#include <iostream>
#include <unordered_set>

struct DummyHash
{
    size_t operator()(int key) const
    {
        return static_cast<size_t>(1);
    }
};

int main()
{
    std::unordered_set<int, DummyHash> a;
    std::unordered_set<int> b;
    int c = 10000;

    for (int i = 0; i < c; i++)
    {
        a.insert(i);
    }
    std::cout << "a ended" << std::endl;

    for (int i = 0; i < c; i++)
    {
        b.insert(i);
    }

    std::cout << "b ended" << std::endl;

    std::cout << "a = " << a.max_load_factor() << ' ' << a.load_factor() << ' '
        << a.max_size() << ' ' << a.max_bucket_count() << ' ' << a.bucket_count() << '\n';
    std::cout << "b = " << b.max_load_factor() << ' ' << b.load_factor() << ' '
        << b.max_size() << ' ' << b.max_bucket_count() << ' ' << b.bucket_count() << '\n';
    return 0;
}

结果:
a ended
b ended
a = 1 0.659065 768614336404564650 768614336404564650 15173
b = 1 0.659065 1152921504606846975 1152921504606846975 15173

最佳答案

您使用的函数不提供碰撞计数,您可能想阅读有关 https://en.cppreference.com/w/cpp/container/unordered_set 的文档。

计算桶碰撞统计信息的一种方法是检查每个桶中的元素数量:

struct BucketStats {
    size_t occupied = 0;
    size_t total_collisions = 0;
    size_t max_collisions = 0;

    template<class... Args>
    BucketStats(std::unordered_set<Args...> const& c)
    {
        for(auto bucket = c.bucket_count(); bucket--;) {
            auto bucket_size = c.bucket_size(bucket);
            occupied += bucket_size > 0;
            if(bucket_size > 1) {
                auto collisions = bucket_size - 1;
                total_collisions += collisions;
                max_collisions = std::max(max_collisions, collisions);
            }
        }
    }

    double avg_collisions() const {
        return occupied ? static_cast<double>(total_collisions) / occupied : 0;
    }

    friend std::ostream& operator<<(std::ostream& s, BucketStats const& b) {
        return s
            << "used buckets: " << b.occupied
            << "; total collisions: " << b.total_collisions
            << "; max collisions in a bucket: " << b.max_collisions
            << "; avg collisions per bucket: " << b.avg_collisions()
            ;
    }
};

// ...

    std::cout << BucketStats(a) << '\n';
    std::cout << BucketStats(b) << '\n';

输出:
used buckets: 1; total collisions: 9999; max collisions in a bucket: 9999; avg collisions per bucket: 9999
used buckets: 10000; total collisions: 0; max collisions in a bucket: 0; avg collisions per bucket: 0

关于c++ - 如何计算unordered_set c++中的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60413490/

相关文章:

c++ - 模板函数查找

c++ - 使用 MPI 通过命令行传递参数

java - Java集合框架中的Hashtable、HashMap、HashSet、哈希表概念

c# - 这样的集合是否存在(Dictionary 和 HashSet 的功能)?

c++ - clear() 是否影响 std::unordered_set 的桶计数?

c++ - 如何将 Q 格式整数转换为 float (反之亦然)?

c++ - 为什么 std::variant 不能保存数组对象类型而 union 可以?

java - 在 for 循环中添加到 HashSet 时,如何删除重复项并用另一个对象替换它们?

c++ - O(1) 中 unordered_set 中的随机元素

c++ - C++ 中无序关联容器的哈希函数