加权哈希合并

时间:2016-07-04 09:36:49

标签: c++ algorithm hash

这是如何组合两个哈希的一个微小变化,我希望结果哈希更多地受到其中一个输入的影响。

对于大致对称的情况,我们有诸如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之比的函数。

这将允许我改进不平衡树的树哈希算法。覆盖树的更简单方法是here,基本上广度优先遍历将每个散列(节点)推送到累积值。这样做的问题是,要混合到组合哈希中的最后一个节点对结果的影响要大于第一个节点。

如果有合理的加权散列组合,那么我可以根据每个散列的节点数来偏置组合,并希望提高散列函数的公平性。

到目前为止,我已经提出:

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;
 }       

虽然数字复杂性相当缺乏,所以我希望社区能够回想起/发明一个更好的解决方案。

高级目标是在(大小或)散列值不同时使树之间的相等性测试短路,因为它们通常仅在一个或两个叶子中不同,并且没有好的方法来估计哪个。 / p>

1 个答案:

答案 0 :(得分:0)

哈希不会那样工作。当您正确组合哈希值时, 哈希值的更改将保证更改组合哈希值,事实上,通过更改 哈希值,您可以完全确定哈希值合并散列。

最常用的混音是:

h = h1*P2 + h2*P1

其中P1和P2是不同的奇素数(或1)。这将根据单词大小执行mod 2 ^ 32或mod 2 ^ 64,但在任何一种情况下,您都可以通过选择hh1h2任意值设为import React from 'react'; import CSSModules from 'react-css-modules'; import styles from './ListItem.css' @CSSModules(styles) export class ListItem extends React.Component { render() { return ( <li className="panel" styleName="list-item"> <h3 className="uppercase m-t-0 m-b-0 relative" styleName="title"> ... </h3> </li>); } } ,无论我们混合了多少其他哈希,这都不会消失。