加权哈希组合
Weighted hash combine
这是如何组合两个哈希值的一个小变化,因为我希望结果哈希值更多地受其中一个输入的影响。
对于大致对称的情况,我们有这样的算法:boost::hash_combine:template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
我正在寻找一个加权版本,也许界面会类似:
uint64_t weighted_hash_combine(uint64_t hashA, uint16 weightA, uint64_t hashB, uint16 weightB);
前提是输出哈希中某位受到输入哈希中某位变化影响的概率是weightA与weightB之比的函数。
这将允许我改进非平衡树的树哈希算法。这里介绍了对树进行散列的一种更简单的方法,本质上是广度优先遍历,将每个散列(节点)推入一个累积值。这样做的问题是,最后一个被混合到组合散列中的节点将比第一个节点对结果的影响更大。
如果有一个合理的加权哈希组合,那么我可以根据每个哈希的节点数量对组合进行偏倚,并希望提高哈希函数的公平性。
到目前为止,我想到了:
uint64_t weighted_hash_combine(uint64_t hashA, uint16 weightA, uint64_t hashB, uint16 weightB)
{
if (weightA > weightB)
{
return weighted_hash_combine(hashB,weightB,hashA,weightA);
}
uint64_t ratio = weightA / weightB;
uint64_t combined = hashA;
for (uint64_t i = 0; i < ratio; i++)
{
hash_combine(combined, hashB);
}
return combined;
}
这是相当缺乏数值复杂性,所以我希望社区可以回忆/发明一个更好的解决方案。
高级目标是在(size或)哈希值不同时缩短树之间的相等性测试,因为它们通常只在一个或两个叶子中不同,并且没有好的方法来估计哪个
哈希不是这样工作的。当您正确地组合哈希时,更改或哈希可以保证更改组合哈希,实际上,通过更改或哈希,您可以完全确定组合哈希的值。
最常用的组合是:
h = h1*P2 + h2*P1
其中P1和P2是不同的奇数素数(或1)。这将执行mod 2^32或mod 2^64取决于字的大小,但在这两种情况下,你可以通过选择h1
或h2
使h
成为任何你想要的值,无论我们像这样混合多少其他哈希值,这都不会消失。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 使用Qt C++计算类似Git的SHA1哈希
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- c++找不到具有相同哈希的无序集合元素
- 哈希文件递归并保存到矢量Cryptopp中
- 对 pair<pair<int,int>pair<int,int unordered_map进行哈希处理>>
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- boost::包含提升单元的元组的哈希值
- 使用 Key 对 C++ 中的哈希映射进行排序. 无法排序
- C++中的并发哈希表
- 哈希映射使用 nullptr c++ 初始化节点的动态数组
- 在具有开放寻址的哈希表中插入节点 [优化逻辑]
- 我在C++中使用提升哈希函数将 3 个双精度组合成一个面临冲突的哈希
- 如何组合加密哈希
- c++使用std::bitset组合哈希函数
- 加权哈希组合