#hamming #search #search-index #index #hash-table

mih-rs

汉明空间中二进制码邻域搜索的多索引哈希(MIH)

6个版本

0.3.1 2021年12月25日
0.3.0 2021年12月25日
0.2.1 2021年8月5日
0.2.0 2021年7月26日
0.1.1 2020年6月20日

#10 in #hamming

MIT 许可证

53KB
962

mih-rs

Documentation Crates.io License: MIT

Rust实现的多索引哈希(MIH),用于在汉明空间中对二进制码进行邻域搜索,如论文所述

Norouzi, Punjani, and Fleet, Fast exact search in Hamming space with multi-index hashing, IEEE TPAMI, 36(6):1107– 1119, 2014.

根据基准测试结果,在1000万个64位码中,mih-rs在k = 1..100的情况下,比线性搜索快19−94倍。

特性

  • 两种邻域搜索类型: mih-rs提供了两种搜索操作

    • 范围搜索 找到与给定码的汉明距离在某个范围内的邻域码。
    • Top-K搜索 找到最接近给定码的前K个码。
  • 快速且内存高效实现: 数据结构基于稀疏哈希表构建,遵循原始实现

  • 参数自动设置: mih-rs会根据给定的数据库自动设置MIH的最佳参数(尽管你也可以手动设置)。

  • 序列化: mih-rs支持序列化和反序列化索引。

示例

use mih_rs::Index;

// Database of codes
let codes: Vec<u64> = vec![
    0b1111111111111111111111011111111111111111111111111011101111111111, // #zeros = 3
    0b1111111111111111111111111111111101111111111011111111111111111111, // #zeros = 2
    0b1111111011011101111111111111111101111111111111111111111111111111, // #zeros = 4
    0b1111111111111101111111111111111111111000111111111110001111111110, // #zeros = 8
    0b1101111111111111111111111111111111111111111111111111111111111111, // #zeros = 1
    0b1111111111111111101111111011111111111111111101001110111111111111, // #zeros = 6
    0b1111111111111111111111111111111111101111111111111111011111111111, // #zeros = 2
    0b1110110101011011011111111111111101111111111111111000011111111111, // #zeros = 11
];

// Query code
let qcode: u64 = 0b1111111111111111111111111111111111111111111111111111111111111111; // #zeros = 0

// Construct the index
let index = Index::new(codes).unwrap();

// Find the ids of neighbor codes whose Hamming distances are within 2
let mut searcher = index.range_searcher();
let answers = searcher.run(qcode, 2);
assert_eq!(answers, vec![1, 4, 6]);

// Find the ids of the top-4 nearest neighbor codes
let mut searcher = index.topk_searcher();
let answers = searcher.run(qcode, 4);
assert_eq!(answers, vec![4, 1, 6, 0]);

// Serialization/Deserialization
let mut data = vec![];
index.serialize_into(&mut data).unwrap();
let other = Index::<u64>::deserialize_from(&data[..]).unwrap();
assert_eq!(index, other);

二进制码类型

mih_rs::Index可以从类型为mih_rs::CodeInt的向量构建,该类型是一个支持popcount操作的原始整数特性。目前,此库为mih_rs::CodeInt定义了u8u16u32u64

基准测试

timeperf_topk.rs提供了在二进制码类型u32u64上对MIH和LinearSearch算法进行Top-K搜索的基准测试。

以下表格显示了在以下设置下每查询平均搜索时间(毫秒)的结果

  • 数据库:来自均匀分布的N个随机码。
  • 查询集:来自均匀分布的100个随机码。
  • 机器:2019年款四核英特尔酷睿i5 @2.4 GHz,16 GB RAM的MacBook Pro。
  • 库版本:v0.2.0

对于 u32 的结果

算法 N=10,000 N=100,000 N=1,000,000 N=10,000,000
MIH (K=1) 0.01 0.02 0.07 0.38
MIH (K=10) 0.04 0.08 0.30 1.06
MIH (K=100) 0.13 0.22 1.22 4.35
线性搜索 0.36 4.40 50.96 626.87

对于 u64 的结果

算法 N=10,000 N=100,000 N=1,000,000 N=10,000,000
MIH (K=1) 0.10 0.36 1.46 6.7
MIH (K=10) 0.20 0.76 3.72 14.8
MIH (K=100) 0.41 1.53 7.02 33.2
线性搜索 0.36 4.36 52.28 629.1

许可

此库是MIT许可下的免费软件。

依赖项

~285–400KB