【问题标题】:What is an effective and efficient hashcode algorithm for a histogram?什么是直方图有效且高效的哈希码算法?
【发布时间】:2015-05-28 01:55:21
【问题描述】:

我有一个直方图,它是一个向量/数字列表。获得这种直方图的哈希码的简单有效算法是什么?散列码只需要在散列值上分割图像,而不是比较图像。

此应用程序不关心安全性,因此加密功能会不必要地缓慢。

【问题讨论】:

  • 你的问题很模糊。您的直方图只是数字列表还是多维数组?将每个数字乘以素数并将其添加到允许溢出的运行总数中有什么问题?这是最基本的哈希方法。
  • 只是一个列表!这种方法会导致溢出并且哈希值为负!我想知道这是否效率低下! (新手)抱歉这个模糊的问题。非常混乱和不合时宜,直方图包含 16384 个 bin!

标签: image hash face-recognition lbph-algorithm


【解决方案1】:

散列列表的方法是将每个项目的散列组合起来。 Java implements the hash function list 像这样:

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

显着特性:

  1. 每个空列表的哈希码正好是1。
  2. 元素数量不同的列表的哈希码很可能不同。
  3. 具有相同数量元素的列表的哈希码更容易发生冲突。具有不同顺序的相同元素的列表会发生冲突;不幸的是,列表 [1,2] 和 [2,1] 的哈希码是相同的。
  4. 这是一个很大的缺点,但并没有您最初想象的那么大。哈希表实现了一个回退,它首先检查哈希码是否相等,然后是完全相等。如果排序的差异出现在列表的前面附近,则此后备检查很快。在最坏的情况下,它只需要进行与列表长度相等的比较次数。

总而言之,对于您的用例来说,这将是一个非常好的哈希函数,即使您使用每个直方图条目的数值作为其哈希码。哈希函数真正要避免的问题是可分割性,这意味着您希望哈希函数的输出落入哈希表的不同存储桶中。如果您想了解更多信息,Wikipedia article 涵盖了良好哈希函数的属性。

要为数字列表获得更好的哈希码,我们应该查看better hash code for an individual number,特别是this answer。

unsigned int hash(unsigned int[] list) {
    unsigned int hashCode = 0;
    for (int i = 1; i < list.length; i++) {
        hashCode = hashCode + list[i];
        hashCode = ((hashCode >> 16) ^ hashCode) * 0x45d9f3b;
        hashCode = ((hashCode >> 16) ^ hashCode) * 0x45d9f3b;
        hashCode = ((hashCode >> 16) ^ hashCode);
    }
    return hashCode;
}

我认为这是一个很好的改编,但我并不期待。

关于溢出的效率,除非您必须为它处理异常,否则这并不是一个主要的减速。在 Java 中,arithmetic will never throw an overflow exception 只是将其包装到最小值或最大值。只要您的哈希表实现支持它,使用负哈希码并没有真正的缺点。

【讨论】:

    【解决方案2】:

    我可能没有正确理解您的问题,但哈希图已经在 matlab 中,它们只是名称不同

    containers.maps

    【讨论】:

      猜你喜欢
      • 2018-06-23
      • 2017-02-20
      • 1970-01-01
      • 2011-06-26
      • 2010-11-16
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多