For AI agents: the complete documentation index is available at https://shijin.space/llms.txt, the full documentation bundle is available at https://shijin.space/llms-full.txt, and this page is available as Markdown at https://shijin.space/knowledge/angular-lsh-and-multiple-tables/index.md.

20 角度 LSH 与多表搜索

整理日期:2026-10-16。
适用范围:随机超平面角度 LSH 的候选生成、多表覆盖、参数选择,以及与两向量筛法的衔接。
前置笔记:15 高斯启发式与随机球面模型、18 Nguyen–Vidick、ListSieve 与 GaussSieve、19 筛法中的近邻搜索与分桶。

沿用第 19 篇的记号:当前维数为 s≥2s\ge2,非零向量池为 D={x1,…,xN}D=\{x_1,\ldots,x_N\}。本篇先研究固定数据库 DD 与固定非零查询向量 x∉Dx\notin D,并假设它们与随机哈希函数的选择独立。

核心思路是:用多个随机超平面的符号组成桶键,再用多张独立的表提高近邻命中率。桶只负责产生候选,是否能够约化仍由真实长度决定。

1. 随机超平面为什么对角度敏感

对非零向量 x,yx,y,记其夹角为

θ(x,y)=arccos⁡⟨x,y⟩∥x∥∥y∥∈[0,π].\theta(x,y)=\arccos\frac{\langle x,y\rangle}{\|x\|\|y\|}\in[0,\pi].

从单位球面均匀采样法向量 aa,定义一位哈希

ha(x)=1{⟨a,x⟩≥0}.h_a(x)=\mathbf 1\{\langle a,x\rangle\ge0\}.

超平面 a⊥a^\perp 把空间分成两侧,同侧向量取得相同的位。

在包含 x,yx,y 的二维平面内,随机分界线将两者分开的概率为 θ/π\theta/\pi,所以

p(θ)=Pr⁡[ha(x)=ha(y)]=1−θπ.\boxed{ p(\theta)=\Pr[h_a(x)=h_a(y)] =1-\frac{\theta}{\pi}. }

这是 Charikar 的随机超平面构造。本篇按 Laarhoven,CRYPTO 2015,ePrint 2014/744 的 23 页版,§2.5,式 (2)–(4),PDF 第 6 页 核对。

因此,夹角越小,同键概率越大。例如,60∘60^\circ 时为 2/32/3,90∘90^\circ 时为 1/21/2。

该公式对任意预先固定的非零向量对成立,不要求数据库方向均匀。哈希值只依赖方向,计算符号时不必显式归一化;原向量的长度仍须保留。

2. 多位组合与多表放大

设每张表使用 k≥1k\ge1 位,共建立 t≥1t\ge1 张表。所有法向量 aℓ,ra_{\ell,r} 相互独立,定义第 ℓ\ell 张表的键

gℓ(x)=(haℓ,1(x),…,haℓ,k(x))∈{0,1}k.g_\ell(x) = \bigl(h_{a_{\ell,1}}(x),\ldots,h_{a_{\ell,k}}(x)\bigr) \in\{0,1\}^k.

数据库中的向量 yy 存入桶 Tℓ[gℓ(y)]T_\ell[g_\ell(y)]。

同一张表要求全部 kk 位相同。 固定夹角为 θ\theta 的向量对,其单表碰撞概率为

qk(θ)=p(θ)k.q_k(\theta)=p(\theta)^k.

多表搜索只要求至少一张表命中。 查询每张表的同键桶后,覆盖概率为

Pk,t(θ)=1−(1−p(θ)k)t.\boxed{ P_{k,t}(\theta) =1-\left(1-p(\theta)^k\right)^t. }

这分别是 AND 组合与 OR 放大的作用。多表索引的基本构造也可参见 Har-Peled–Indyk–Motwani,Theory of Computing 2012,§3.2,PDF 第 17–18 页。

两个参数的作用不同:

  • 增大 kk:近点和远点都更难碰撞,但远点的概率下降得更快,候选更少。
  • 增大 tt:提高覆盖率,同时增加建表、查询和索引存储成本。

若某个固定目标的单表命中率为 q∈(0,1)q\in(0,1),希望漏检概率不超过 δ\delta,则

t≥ln⁡δln⁡(1−q)≈ln⁡(1/δ)q,q≪1.t\ge \frac{\ln\delta}{\ln(1-q)} \approx\frac{\ln(1/\delta)}{q}, \qquad q\ll1.

这是对一个固定目标的要求。它既不表示命中次数等于不同候选数,也不直接保证全部有效对都被覆盖。

3. 筛法为什么要查询正负两个方向

两向量约化需要同时考虑 x−yx-y 与 x+yx+y。若只查 gℓ(x)g_\ell(x),就偏向寻找与 xx 同向的伙伴,容易遗漏接近 −x-x 的伙伴。

一种直接设计是:每条数据库向量在每张表中只存一次;查询时读取

Tℓ[gℓ(x)]和Tℓ[gℓ(−x)].T_\ell[g_\ell(x)] \quad\text{和}\quad T_\ell[g_\ell(-x)].

在连续随机模型中,固定非零向量落在超平面上的概率为零,因而几乎必然有

gℓ(−x)=gℓ(x)‾,g_\ell(-x)=\overline{g_\ell(x)},

其中横线表示逐位取反。

对固定的 x,yx,y,记 θ=θ(x,y)\theta=\theta(x,y)。由于 k≥1k\ge1,这两个键不同;yy 在同一张表中不能同时落入两个查询桶。因此双向单表命中率是两个互斥事件的概率之和:

qk±(θ)=(1−θπ)k+(θπ)k.\boxed{ q_k^\pm(\theta) = \left(1-\frac{\theta}{\pi}\right)^k + \left(\frac{\theta}{\pi}\right)^k. }

相应的多表覆盖概率为

Pk,t±(θ)=1−(1−qk±(θ))t.P_{k,t}^\pm(\theta) = 1-\left(1-q_k^\pm(\theta)\right)^t.

以上双向公式由两个查询键直接推得。同一表内的两次查桶不能当作两次独立随机试验,也不能一般地把单向概率乘以 22。

一个简单检查是:k=1k=1 时,q1±(θ)=1q_1^\pm(\theta)=1。此时正负查询恰好读取一张表的全部两个桶,等于扫描整个数据库,没有过滤作用。

4. 固定数据库上的候选查询

下面的流程完整读取所有指定桶,并按向量编号去重。查询过程中不改变 xx 或 DD,也不提前停止。

BuildIndex(D, k, t):
    对每张表 ℓ = 1, ..., t:
        独立采样 k 个随机超平面,确定键函数 g_ℓ
        T_ℓ ← 空的桶字典

        对每条向量 x_j ∈ D:
            将编号 j 加入 T_ℓ[g_ℓ(x_j)]

    返回所有键函数和哈希表

QueryCandidates(x):
    Seen ← 空集合

    对每张表 ℓ = 1, ..., t:
        key ← g_ℓ(x)

        对 b ∈ {key, 逐位取反(key)}:
            对编号 j ∈ T_ℓ[b]:       # 不存在的桶视为空
                如果 j 不在 Seen 中:
                    将 j 加入 Seen
                    输出 j

输出编号后,再按外层算法的约化规则检查。

例如,若任务是用 y=xjy=x_j 缩短指定的 xx,可以令

w=x−σy,σ={1,⟨x,y⟩≥0,−1,⟨x,y⟩<0,w=x-\sigma y, \qquad \sigma= \begin{cases} 1,&\langle x,y\rangle\ge0,\\ -1,&\langle x,y\rangle<0, \end{cases}

并检查

0<∥w∥<∥x∥.0<\|w\|<\|x\|.

这与第 19 篇中“缩短两者的较长者”采用的判据不同。若外层算法使用目标半径、双向约化或其他接纳规则,应保留对应条件。

5. 重复访问、不同候选与实际成本

记 θj=θ(x,xj)\theta_j=\theta(x,x_j),并令

qj=qk±(θj).q_j=q_k^\pm(\theta_j).

对第 4 节的完整查询,定义:

  • CrawC_{\mathrm{raw}}:从各表读取的桶成员总数,包含跨表重复。
  • CuniqueC_{\mathrm{unique}}:去重后的不同候选编号数。

对随机索引取期望,有

E[Craw]=t∑j=1Nqj,E[Cunique]=∑j=1N[1−(1−qj)t].\boxed{ \mathbb E[C_{\mathrm{raw}}] =t\sum_{j=1}^{N}q_j, \qquad \mathbb E[C_{\mathrm{unique}}] =\sum_{j=1}^{N}\left[1-(1-q_j)^t\right]. }

第一式只用期望的线性性;第二式还使用同一向量对在不同表中的命中事件独立。不同数据库向量的命中事件不必相互独立。

若只统计能够约化 xx 的不同伙伴,则将第二式的求和范围限制到对应有效集合即可。不同伙伴数与实际接纳的新向量数仍需区分,见第 19 篇。

按直接计算 ss 维内积的实现:

Tbuild=O(sNkt).T_{\mathrm{build}}=O(sNkt).

若编号去重和桶访问采用期望常数时间的字典操作,且每个不同候选都做一次真实长度检查,则

Tquery=O ⁣(skt+Craw+sCunique).T_{\mathrm{query}} =O\!\left(skt+C_{\mathrm{raw}}+sC_{\mathrm{unique}}\right).

这里分别对应哈希计算、桶成员访问与候选检查。去重能减少重复内积计算,但已经读取的桶成员仍产生访问成本。

全部 tt 张表同时驻留时,共保存 NtNt 条成员引用。原向量坐标可以共享,不必复制 tt 份完整向量;此外还需存储超平面、非空桶的键、管理信息和去重集合。使用非空桶字典,也避免为每张表预分配全部 2k2^k 个桶。

这些计数与成本是对上述固定流程的直接分析。提前停止、批量处理或改变索引布局后,应按实际操作重新计数。

6. 常见的参数指数 ρ\rho 从哪里来

先考虑单向查询,采用一个简化模型:

  • 有一个希望找到的近点,与查询夹角至多为 θ1\theta_1。
  • 其余点都与查询相距至少 θ2\theta_2。
  • 0<θ1<θ2<π0<\theta_1<\theta_2<\pi,二者固定,不随 NN 改变。

令

p1=1−θ1π,p2=1−θ2π,p1>p2.p_1=1-\frac{\theta_1}{\pi}, \qquad p_2=1-\frac{\theta_2}{\pi}, \qquad p_1>p_2.

希望一张表中的远点候选数为常数量级,可以取

k=⌈ln⁡Nln⁡(1/p2)⌉,Np2k≤1.k= \left\lceil \frac{\ln N}{\ln(1/p_2)} \right\rceil, \qquad Np_2^k\le1.

另一方面,近点的单表命中率至少为 p1kp_1^k。为使固定近点的失败概率至多为常数 δ∈(0,1)\delta\in(0,1),取

t=⌈ln⁡(1/δ)p1k⌉t= \left\lceil \frac{\ln(1/\delta)}{p_1^k} \right\rceil

即可,因为 (1−p1k)t≤e−tp1k(1-p_1^k)^t\le e^{-tp_1^k}。

于是

ρ=ln⁡(1/p1)ln⁡(1/p2),t=Θ(Nρ).\boxed{ \rho= \frac{\ln(1/p_1)}{\ln(1/p_2)}, \qquad t=\Theta(N^\rho). }

在这个模型中,期望查询时间为 O~(sNρ)\widetilde O(sN^\rho),表中的成员引用数为 O(N1+ρ)O(N^{1+\rho});O~\widetilde O 在此省略关于 NN 的对数因子。预处理仍须付出建表成本。

这一近远分离模型与参数关系可对照 Becker–Ducas–Gama–Laarhoven,SODA 2016,§2 的 Lemma 2.3 及脚注 2,PDF 第 4 页。本节只分析上述简化输入与完整查桶流程。

取 θ1=π/3\theta_1=\pi/3、θ2=π/2\theta_2=\pi/2,得到

ρ=ln⁡(3/2)ln⁡2=log⁡2(3/2)≈0.585.\rho= \frac{\ln(3/2)}{\ln2} =\log_2(3/2) \approx0.585.

这个数描述特定近远阈值下的查询参数关系,不能直接当作筛法的时间指数。

实际筛法中,候选夹角分布在一个区间内。即使高维随机夹角集中在 90∘90^\circ 附近,也不能把所有候选都替换为 90∘90^\circ:若夹角为随机变量 Θ\Theta,单向单表平均碰撞率是

E[p(Θ)k],\mathbb E[p(\Theta)^k],

通常不等于 p(E[Θ])kp(\mathbb E[\Theta])^k。当数据库规模随维数指数增长时,非典型角度的贡献也可能影响总成本。

Laarhoven 在其 NV 型筛法的随机球面启发式、γ→1\gamma\to1 及优化参数下,得到时间估计 20.3366s+o(s)2^{0.3366s+o(s)};这需要进一步分析角度分布与筛法流程。参见 原文 §4.2、Theorem 1 与 Appendix A。该结果不是任意输入上的最坏情况保证。

7. 接入筛法时需要保留哪些条件

索引必须与向量状态一致。 数据库向量改变时,应移除旧键下的记录,再按新向量重新插入;若先将其移入待处理队列,则在重新接纳时建索引。查询向量改变后,也应重新计算键,旧候选集合不能视为对新方向的完整搜索结果。

HashSieve 的动态更新可对照 Laarhoven,§5.2、Algorithm 5,PDF 第 12 页。该节用角度约化说明理论动机,同时明确实际候选检查仍可采用真实范数条件。

固定索引上的重复查询没有增加独立机会。 当数据库、查询和表都不变时,再查一遍得到的仍是相同候选。多表覆盖公式来自独立采样的表,不能把相同查询的重复执行次数代入 tt。

动态过程的概率分析需要另行核对。 本篇固定向量对的概率公式是精确计算;当后续向量由已有索引的查询结果产生时,它们可能与索引相关,不能未经论证就反复套用固定且独立的输入模型。

因此,没有命中约化伙伴只表示本次搜索未找到;它不能认证池已两两约化,也不能认证已找到最短向量。

后续可以继续阅读球面 LSF,再进入 BGJ 多层分桶。届时仍保留本篇的分析顺序:先确定共同命中概率,再计算重复访问与不同有效对覆盖,最后计入建桶、更新和内存成本。

引用此笔记