Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 特定数组的哈希_Algorithm_Sorting_Hash - Fatal编程技术网

Algorithm 特定数组的哈希

Algorithm 特定数组的哈希,algorithm,sorting,hash,Algorithm,Sorting,Hash,我有一个非常特别的问题,我想有效地解决 几何图形由V体积定义,从0到V-1编号。 每个体积由不同的曲面限定,从0到N-1编号) 请注意,曲面在卷中仅出现一次。 此外,一个曲面最多包含两个几何体的体积 问题是: 我对相同的基础几何体有两种不同的描述,我想找出几何体A中的哪个体积对应于几何体B中的哪个体积。换句话说,我有相同的N个曲面,但V个体积的定义不同 这是一个几何体B,可以对应于上面的几何体a: Volume | Surfaces

我有一个非常特别的问题,我想有效地解决

几何图形由V体积定义,从0到V-1编号。 每个体积由不同的曲面限定,从0到N-1编号)

请注意,曲面在卷中仅出现一次。 此外,一个曲面最多包含两个几何体的体积

问题是: 我对相同的基础几何体有两种不同的描述,我想找出几何体A中的哪个体积对应于几何体B中的哪个体积。换句话说,我有相同的N个曲面,但V个体积的定义不同

这是一个几何体B,可以对应于上面的几何体a:

                             Volume | Surfaces
                            --------------------
Geometry B (V=2, N=7):      0      | [1 5 4 2]
                            1      | [3 6 5 0 2] 
                            2      | [0 1 3 6 4]
给定几何体A和B,我希望能够尽可能高效地将几何体A的每个体积绑定到几何体B中相应的体积

A   0  1  2
B   1  0  2
解决方案草案: 按照升序或降序对每个曲面数组进行排序,而不是按照曲面的字典顺序对每个卷进行排序。通过这种方式,问题很容易得到有力的解决

更好的解决方案: 为每个数组计算一个快速、唯一的哈希,然后在此哈希之后对卷进行排序。散列不应取决于数组中曲面的顺序

为什么我认为散列可以是一个好的解决方案? 获取散列(体积)=最小值([曲面])

此哈希最多已经有1个冲突,因为曲面只能出现在2个卷中


现在,如果我取hash(Volume)=min([Surfaces])+max([Surfaces])*N,我仍然最多有一次碰撞,但是当有很多体积和曲面时,概率变得非常小。

如前所述,您的解决方案是您想要的很好的近似值。但是,如果要寻找完美的哈希函数,可以使用以下方法:

假设p_i是第i个素数,p_0=2,p_1=3,p_2=5,p_3=7,p_4=11,p_5=13,p_6=17,p_7=19。。。。我们可以从一个数组中定义一个散列函数在x_0,x_1,…,x_k上,使得h(x_0,…,x_k)=p_{x_0}p_{x_1}。。。p_{x_k}。同样,对于重复数,我们可以将重复数作为p_{x_i}的幂。这意味着,例如,如果x_i重复3次,p_{x_i}in
h
的幂将是p_{x_i}^3。如果x_i的重复次数是a_i,我们将有h(x_0,…,x_k)=p_{x_0}^{a_0}p_{x_1}^{a_1}。。。p{x{u k}^{a{u k}

因此,对于几何体A,我们有:

                    Volume |      Surfaces     | Hash
                    ----------------------------------
  geometry A           0   | [0, 3, 5, 6, 2]   | 2 * 7 * 13 * 17 * 5 = 15470 
                       1   | [5, 4, 2, 1]      | 13 * 11 * 5 * 3 = 2145
                       2   | [4, 0, 1, 3, 6]   | 11 * 2 * 3 * 7 * 17 = 7854

几何体B的方法与此类似。由于此函数为每个数组返回唯一值(与顺序无关),因此可以使用对应哈希值排列曲面。如果
N
的值不大,可以使用预计算的素数值列表

我发现了一个非常好的哈希函数,它几乎不应该有冲突:

V: [S_0 S_1 S_2 S_3...S_N-1]

u64 hash(V) = 0;
for i in {0..N-1} :
    hash(V) = hash(V) ^ (1<<(S_i & 63))
end
V:[S_0 S_1 S_2 S_3…S_N-1]
u64散列(V)=0;
对于{0..N-1}中的i:

hash(V)=hash(V)^(1“更好的解决方案”似乎是可行的。您是否需要帮助?您将很难想出“唯一的”hash。任何哈希方案都有发生冲突的机会。但是,您可以降低冲突的概率。如果曲面数较少(小于32768),则,例如,您可以在32位数字的低位和高位对最小值和最大值进行编码。您的哈希在数学上非常漂亮,它确实提供了一个唯一的哈希。但是,只有10个素数,它已经是32位了,并且它不需要20个素数就可以溢出64位…有了溢出,我想会有很多冲突。实际上,这个散列函数的问题是它没有利用数字不重复的事实。我将在下面的答案中描述一个更好的散列函数。@yakoudbz第二个问题太简单了。答案已经更新了。唯一的问题是类型,而不是问题中的问题。无论如何,它不是所有问题中的问题像python这样的语言:)是的,我可能应该提到潜在的关注点是效率。我不想使用大的数字(即使在python中,也总是很慢:)。不管怎样,我还是投了赞成票
V: [S_0 S_1 S_2 S_3...S_N-1]

u64 hash(V) = 0;
for i in {0..N-1} :
    hash(V) = hash(V) ^ (1<<(S_i & 63))
end