Hash 为几个整数生成哈希和

Hash 为几个整数生成哈希和,hash,Hash,我面临着有几个整数的问题,我必须使用它们生成一个整数。比如说 Int 1: 14 Int 2: 4 Int 3: 8 Int 4: 4 Hash Sum: 43 我对值有一些限制,和属性可以有的最大值是30,所有值的相加总是30。这些属性总是积极的 关键是我想要为相似的整数生成相同的哈希和,例如,如果我有整数14,4,10,2,那么我想要生成相同的哈希和,在上述43的情况下。当然,如果整数是非常不同的(4,4,2,20),那么我应该有一个不同的散列和。它也需要快速 理想情况下,我希望哈希和的

我面临着有几个整数的问题,我必须使用它们生成一个整数。比如说

Int 1: 14
Int 2: 4
Int 3: 8
Int 4: 4

Hash Sum: 43
我对值有一些限制,和属性可以有的最大值是30,所有值的相加总是30。这些属性总是积极的

关键是我想要为相似的整数生成相同的哈希和,例如,如果我有整数14,4,10,2,那么我想要生成相同的哈希和,在上述43的情况下。当然,如果整数是非常不同的(4,4,2,20),那么我应该有一个不同的散列和。它也需要快速

理想情况下,我希望哈希和的输出介于0和512之间,并且应该均匀分布。根据我的限制,我可以有5公里左右的不同可能性,所以我希望每桶10公里左右

我相信有很多算法可以做到这一点,但我找不到一种方法在谷歌上搜索这个东西。任何人都可以发布一个算法来做这件事吗

更多信息

所有这些整数都是函数的属性。我想将函数的值存储在一个表中,但是我没有足够的内存来存储所有不同的选项。这就是为什么我想在相似属性之间进行泛化


为什么10,5,15与5,10,15完全不同,因为如果你在3d中想象这一点,那么这两个点是完全不同的点

更多信息2

一些答案试图使用哈希来解决这个问题。但我认为这并不复杂。感谢其中一条评论,我意识到这是一个聚类算法问题。如果我们只有3个属性,我们想象3d中的问题,我只需要将空间分成块

事实上,这可以用这种类型的规则来解决

if (att[0] < 5 && att[1] < 5 && att[2] < 5 && att[3] < 5)
     Block = 21


if ( (5 < att[0] < 10) &&  (5 < att[1] < 10) &&  (5 < att[2] < 10) &&  (5 < att[3] < 10))
     Block = 45
if(att[0]<5&&att[1]<5&&att[2]<5&&att[3]<5)
块=21
如果((5

问题是,我需要一种快速而通用的方法来生成那些如果我无法写出所有的可能性。

您需要定义“相似”的含义。哈希通常被设计为从唯一的输入创建唯一的结果


一种方法是对输入进行规范化,然后根据结果生成散列。

给定输入a、b、c和d,每个输入的值范围为0到30(5位),下面将生成一个0到255(8位)的数字

通过以下方式进行测试:

for (int a = 0; a <= 30; a++)
    for (int b = 0; b <= 30; b++)
        for (int c = 0; c <= 30; c++)
            for (int d = 0; d <= 30; d++) {
                int bucket = ((a & 0x18) << 3) |
                             ((b & 0x18) << 1) |
                             ((c & 0x18) >> 1) |
                             ((d & 0x18) >> 3);
                printf("%d, %d, %d, %d -> %d\n",
                         a,  b,  c,  d,   bucket);
            }

for(int a=0;a您想要一个散列函数,它取决于输入的顺序,并且类似的数字集将生成相同的散列?也就是说,您想要50 5 10和5 5 10 50生成不同的值,但是您想要52 7 4 12生成与50 5 5 10相同的散列?一种简单的方法是:

long hash = 13;
for (int i = 0; i < array.length; i++) {
    hash = hash * 37 + array[i] / 5;
}

编辑:考虑到您对这个答案的评论,我上面的尝试似乎可以很好地满足您的需求。它既不理想,也不完美。如果您需要高性能,您需要做一些研究和实验

总之,顺序很重要,因此5 10 20不同于20 10 5。此外,理想情况下,您可以将每个“向量”分别存储在哈希表中,但为了处理空间限制,您希望将一些值组存储在一个表项中


理想的散列函数将返回一个根据表大小均匀分布在可能值上的数字。正确执行此操作取决于表的预期大小以及输入向量值的数量和预期最大值。如果可以将负值作为“坐标”值,这可能会影响计算哈希值的方式。如果给定输入值的范围和选择的哈希函数,最大哈希值小于哈希表大小,则需要更改哈希函数以生成更大的哈希值。

简单解决方案:

将整数转换为以逗号分隔的字符串,并使用通用哈希算法(md5、sha等)对结果字符串进行哈希运算

如果你真的想自己动手,我会这样做:

  • 生成大素数P
  • 生成随机数0

要生成散列,请计算:sum(a[i]*x[i])mod p

生成相同的散列和称为冲突,这对散列来说是一件坏事。这会降低它的用处

如果您希望相似的值给出相同的输出,则可以将输入除以您希望它们计数的接近程度。如果顺序不同,请对每个数字使用不同的除数。以下函数完成了您所描述的操作:

int SqueezedSum( int a, int b, int c, int d )
{
    return (a/11) + (b/7) + (c/5) + (d/3);
}

这不是散列,但与您描述的一样。

您可能希望尝试使用来描述作为散列值设置的每个数字

编辑: 由于您没有描述为什么不运行函数本身,我猜它运行时间很长。因为您没有描述参数集的宽度

如果期望每个值,则数据库中的完整查找表可能会更快

如果您希望使用相同的参数重复调用,并且总体变化很小,那么您可以考虑这样做:仅第一次运行一个参数集是昂贵的,并且每个额外的请求都很快,内存使用量更少。

您希望查看。在“标准”哈希中,您希望

  • 短钥匙
  • 反向电阻
  • 抗碰撞

  • 用几何散列法,你可以用几乎相反的东西代替数字3;即闭合初始值给出闭合散列值。

    另一种查看我的问题的方法是使用多维缩放(MS)。在MS中,我们从项目矩阵开始,我们想要的是为每个项目分配一个位置
    long hash = 13;
    for (int i = 0; i < array.length; i++) {
        hash = hash * 37 + array[i] / 5;
    }
    
        hash = hash * 37 + array[i] / 5;
    
        hash += array[i] / 5;
    
    int SqueezedSum( int a, int b, int c, int d )
    {
        return (a/11) + (b/7) + (c/5) + (d/3);
    }