如果你不熟悉universal hashing,它主要是试图保证少量的碰撞(相反,使用普通的旧模),使用一些相当简单的数学涉及随机性。问题是,它并没有为我工作:通用哈希执行比模哈希差,有什么不对?
size_t hash_modulo(const int value) {
return (size_t) (value % TABLE_SIZE);
}
// prime 491 is used because its > 128, which is the size of the hash table
size_t hash_universal(const int value) {
const size_t a = (size_t) (rand() % 491 + 1);
const size_t b = (size_t) (rand() % 491);
//printf("a: %zu, b:%zu\n", a, b);
return ((a * value + b) % 491) % TABLE_SIZE;
}
我试模第一哈希和确定的最长链长(链长是指一个散列桶的大小):
size_t get_max_chain_length(int input[TABLE_SIZE], size_t (*hash_function)(const int)) {
HashTable *hash_table = hash_table_create(hash_function);
if (!hash_table) {
return 0;
}
for (size_t i = 0; i < TABLE_SIZE; ++i) {
hash_table_add(hash_table, input[i]);
}
size_t maximum_chain_length = 0;
for (int j = 0; j < TABLE_SIZE; ++j) {
const size_t length = length_of_(hash_table->rows[j]);
maximum_chain_length = (length > maximum_chain_length) ? length : maximum_chain_length;
}
//hash_table_print(hash_table);
hash_table_destroy(hash_table);
return maximum_chain_length;
}
我挑一个这些输入导致了一个真正的大链(id est一个使用普通模的方式执行不好),并且抛出这个反对通用散列。通用哈希使用随机性,所以我可以采取不变的输入,并仍然得到不同的结果。
问题来了。我尝试了100个随机输入数组,每个大小为128,并计算平均最长链和最长链,但两种算法执行类似。
你可以在我的repo检查我的主。
我的问题是:结果是预期的吗?通用哈希表现不是更好的输入已使用模数执行差吗?或者我只是搞砸了我的实现(更可能)。
非常感谢!
等待,您为每个单独的哈希访问重新计算'a'和'b'?这有什么意义?在这种尝试中, – melpomene
是'a'和'b'应该是'静态'? – WhozCraig
@melpomene:如果它们是静态的,那么函数总是会将相同的输入散列到同一个桶中? – AdHominem