算法 1: FilteredGreedySearch
目标:从包含过滤器的图中找到近似的最近邻节点。
输入:
- 图 G:节点之间存在连接关系的图。
- 初始节点集合 N:搜索从这些节点开始。
- 查询向量 q:用于寻找最近邻的目标向量。
- 搜索列表大小 L:控制搜索过程中的列表大小。
- 查询过滤条件 Fq:用于过滤节点的条件。
输出:
- 结果集 R:包含近似最近邻节点。
- 访问过的节点集合 V:包含所有在搜索过程中访问过的节点。
算法步骤:
-
初始化:
- 初始化集合 R(结果集)和 V(访问节点集)为空集。
-
将初始节点加入搜索列表:
- 遍历初始节点集合 N,如果节点的标签与查询过滤条件 Fq 有交集,则将该节点加入结果集 R。
-
搜索过程:
- 当 R∖V\=∅ 时,继续搜索:
- 从 R∖V 中选择距离查询向量 q 最近的节点 n∗。
- 将节点 n∗ 加入访问节点集合 V。
- 从节点 n∗ 的相邻节点中选择符合过滤条件的节点(标签与查询过滤条件 Fq 有交集,并且该节点不在访问集合 V 中),加入结果集 R。
- 如果结果集 R 的大小超过给定的搜索列表大小 L,则将 R 更新为距离查询向量 q 最近的 L 个节点。
- 当 R∖V\=∅ 时,继续搜索:
-
返回结果:
- 返回近似最近邻集合 R 以及访问过的节点集合 V。
总结:该算法是一个用于带有过滤条件的贪心搜索算法,首先从一组初始节点开始,逐步扩展符合过滤条件的节点,直到找到足够数量的近似最近邻节点。
算法 2: FindMedoid
目标:找到每个过滤条件的中心节点(Medoid),用于优化带有过滤器的图搜索。
输入:
- 数据集 D:包含所有数据点及其对应的过滤标签。
- 采样阈值 T:用于控制每个过滤条件对应起始节点的采样数量。
输出:
- 映射 M:将过滤器映射到对应的中心节点(即每个过滤条件的代表节点)。
算法步骤:
-
初始化:
- 初始化映射 M 为一个空映射,用于记录每个过滤条件对应的中心节点。
- 初始化 C 为零映射,用作计数器,统计每个节点被选为中心节点的次数。
-
遍历所有过滤条件:
- 遍历集合 F,即所有的过滤条件:
- 对于每个过滤条件 f,获取所有匹配该过滤条件的数据点集合 Df 的 ID。
- 从这些 ID 中随机采样 T 个数据点 ID,记为采样集合 Sf。
- 在采样集合 Sf 中选择使其在映射 C 中计数最少的数据点 n∗。
- 更新映射 M,将过滤条件 f 映射到节点 n∗,并将计数器中节点 n∗ 的计数增加 1。
- 遍历集合 F,即所有的过滤条件:
-
返回映射:
- 返回映射 M,该映射用于后续在带过滤条件的搜索中找到合适的起始节点。
选择图中每个筛选器(或称过滤器)起始节点的方法,确保满足两个关键条件:
-
与筛选器关联:对于包含单个筛选器 f 的查询,其起始点 s 必须与该筛选器关联。也就是说,起始点应该和它代表的筛选器有联系,确保该筛选器属于起始点的相关属性集合中。
-
均衡负载:集合 P 中的任何一个点都不应作为太多筛选器的起始点。这样做的目的是将不同筛选器的查询负载均衡地分布到多个点上,以便构建一个小且有界最大度数的图,能够满足所有的筛选器需求。如果单个点被用作过多标签的起始点,可能导致从起始点出发的某些标签的邻居节点数量不足,从而导致搜索效果不佳。
FilteredRobustPrune 算法详细解释
参数说明:
- Graph G: 输入的图结构,由点(节点)和边(连接)组成。
- Point p ∈ P: 图中的某个点 p,需要对其进行邻居修剪。
- Candidate set V: 候选集合 V,表示当前点 p 的潜在邻居。
- Distance threshold α ≥ 1: 距离阈值 α,用于决定哪些邻居应该被保留。通常 α 大于或等于 1。
- Max outdegree bound R: 最大的出度上界 R,即允许点 p 保留的最多邻居数。
算法步骤:
-
初始化候选集: 首先,移除当前点 ( p ) 本身,将点 ( p ) 加入一个新的候选集:
V ← V ∪ N o u t ( p ) ∖ { p } V \leftarrow V \cup N_{out}(p) \setminus \{p\} V←V∪Nout(p)∖{p}
同时,初始化 ( N_{out}§ ) 为空集,表示点 ( p ) 当前的出度邻居集合。 -
开始循环操作: 进入 while 循环,只要候选集 ( V ) 非空就继续执行:
while V ≠ ∅ \text{while}~ V \neq \emptyset while V=∅ -
选取最近的候选点: 在候选集 ( V ) 中,选择与点 ( p ) 距离最近的点 ( p^* ):
p ∗ ← arg min p ′ ∈ V d ( p , p ′ ) p^* \leftarrow \arg\min_{p' \in V} d(p, p') p∗←argp′∈Vmind(p,p′)
然后将点 ( p ∗ ) ( p^* ) (p∗) 加入 $( N_{out}§ $) 集合,表示它成为了点 ( p ) 的一个邻居。 -
检查邻居数上限: 如果当前的邻居集合 ( N_{out}§ ) 的大小已经达到了最大允许邻居数 ( R ),则终止算法:
if ∣ N o u t ( p ) ∣ = R then break \text{if } |N_{out}(p)| = R \text{ then break} if ∣Nout(p)∣=R then break -
过滤候选点: 对当前候选集中的每一个点 ( p’ \in V ),进行以下两步操作:
-
检查覆盖集交集: 如果点 ( p’ ) 的特征集与点 ( p^* ) 的特征集没有交集,则跳过该点:
if F p ′ ∩ F p ∗ = ∅ then continue \text{if } F_{p'} \cap F_{p^*} = \emptyset \text{ then continue} if Fp′∩Fp∗=∅ then continue -
距离筛选: 如果点 ( p’ ) 与点 ( p^* ) 之间的距离乘以距离阈值 ( \alpha ) 小于等于点 ( p ) 与 ( p’ ) 之间的距离,则移除点 ( p’ ):
if α ⋅ d ( p ∗ , p ′ ) ≤ d ( p , p ′ ) then remove p ′ from V \text{if } \alpha \cdot d(p^*, p') \leq d(p, p') \text{ then remove } p' \text{ from } V if α⋅d(p∗,p′)≤d(p,p′) then remove p′ from V
-
-
重复步骤:返回到 while 循环的起点,继续从候选集 ( V ) 中选择下一个最近的点并进行筛选。
结果:
- 该算法最终会在点 ( p ) 的邻居中保留最多 ( R ) 个点,这些点是在满足距离阈值 α \alpha α和特征覆盖集交集的前提下筛选出来的。
作用
该算法的主要目的是对图中的邻居节点进行筛选和修剪,以确保每个节点的出度不超过指定的上限 ( R ),同时在保持距离和特征覆盖上的合理性。
详细解释:Filtered Vamana Indexing Algorithm
该算法用于在近似最近邻(ANN)问题中生成一个图索引结构。索引结构是一个稀疏的有向图,通过控制节点的出度来优化最近邻搜索的效率。以下是该算法的详细解释,包括每个步骤的作用以及参数的含义。
输入参数
- P P P:点集,包含 n n n 个点,每个点 x i x_i xi 具有坐标信息 x i x_i xi。
- α α α:修剪时的阈值,影响节点的出度控制(影响候选邻居的保留策略,越大则图更稠密)。
- L L L:搜索深度,用于贪心搜索过程中,控制在搜索阶段探查的节点数量。
- R R R:图中每个节点的最大出度,控制最终生成的图的稀疏性,即每个节点最多有 R R R 个出度。
输出
- G G G:有向图,顶点为点集中的点,边表示点之间的近邻关系。该图每个节点的出度最多为 R R R。
算法步骤
1. 初始化(步骤1-5)
-
Step 1: 初始化图 G G G 为一个空图。此图将用于存储点与点之间的近邻关系。
-
Step 2: 找到数据集 P P P 的“中位点”(Medoid),记为 s s s。中位点在一定程度上是点集的中心点,可以用于快速搜索。
-
Step 3: 对于每个过滤标签 f ∈ F f \in F f∈F,确定初始节点 s t ( f ) st(f) st(f)。每个过滤标签可能代表数据集中的一个特定子集或维度子空间,该子空间有助于更高效地进行贪心搜索。
-
Step 4: 将点集的索引进行随机排列,生成一个随机排列 σ \sigma σ。通过随机排列,避免因数据顺序带来的偏差,使得图的生成过程更均匀。
-
Step 5: 为点集中的每个点分配一个过滤标签集 F x F_x Fx。该标签集可以是基于点特征或者聚类结果的分组,用于后续的贪心搜索和修剪过程。
2. 遍历点集 P P P(步骤6-14)
进入主循环,遍历每个点。对于每个点 i ∈ [ n ] i \in [n] i∈[n],按照随机排列 σ ( i ) \sigma(i) σ(i) 的顺序依次处理每个点,执行以下步骤:
2.1 搜索近邻(步骤7-9)
-
Step 7: 根据标签集 F σ ( i ) F_{\sigma(i)} Fσ(i) 找到与当前点 σ ( i ) \sigma(i) σ(i) 相关的子集 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i)。这些点作为贪心搜索的起始点。通常, S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i) 包含满足特定过滤条件的点集。
-
Step 8: 调用
FilteredGreedySearch
算法在集合 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i) 中执行贪心搜索,以寻找当前点 σ ( i ) \sigma(i) σ(i) 的候选近邻集 V F σ ( i ) \mathcal{V}_{F_{\sigma(i)}} VFσ(i)。贪心搜索使用起始点 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i),以 x σ ( i ) x_{\sigma(i)} xσ(i) 作为搜索目标,搜索深度为 L L L。- L L L:表示搜索的深度,即在贪心搜索过程中,允许探查的点的数量。如果 L L L 较大,搜索将更广泛,但效率降低;如果 L L L 较小,搜索可能会遗漏一些潜在的近邻。
-
Step 9: 更新当前点的候选近邻集 V \mathcal{V} V,即将新的候选集 V F σ ( i ) \mathcal{V}_{F_{\sigma(i)}} VFσ(i) 合并到 V \mathcal{V} V 中。
2.2 修剪邻居集合(步骤10)
-
Step 10: 调用
FilteredRobustPrune
对当前点 σ ( i ) \sigma(i) σ(i) 进行修剪,保留那些更相关的近邻,删除不必要的远邻。参数 α \alpha α 和 R R R 用于控制修剪过程:-
R R R:表示每个节点的最大出度,如果当前点的候选邻居集超过 R R R,需要对邻居进行修剪,确保图的稀疏性。
-
α α α:修剪时的阈值,影响候选邻居的保留策略,决定是否保留某些边。如果 α α α 较大,则更多的远邻会被保留,生成的图会较为稠密;如果 α α α 较小,图会更加稀疏。
-
2.3 更新邻居关系(步骤11-14)
-
Step 11-12: 对每个已经确定的近邻 j ∈ N o u t ( σ ( i ) ) j \in N_{out}(\sigma(i)) j∈Nout(σ(i)),更新邻居集 N o u t ( j ) N_{out}(j) Nout(j),即将节点 σ ( i ) \sigma(i) σ(i) 加入到 j j j 的邻居集中。
-
Step 13-14: 如果某个近邻 j j j 的邻居数超过了最大限制 R R R,则再次调用
FilteredRobustPrune
对该节点进行修剪,确保其邻居数不超过 R R R。
参数说明
- P P P:点集,包含 n n n 个点,每个点 x i x_i xi 表示其坐标。
- α α α:修剪的阈值,用于决定哪些候选邻居需要被裁剪。 α α α 越大,图的稠密度越高,近邻关系越强; α α α 越小,图越稀疏。
-
L
L
L:搜索深度,用于
FilteredGreedySearch
,决定搜索过程中探查的点的数量。 L L L 越大,搜索范围越广,找到的近邻越多,但效率下降。 - R R R:图中每个节点的最大出度,用于控制图的稀疏性。 R R R 越小,图越稀疏; R R R 越大,图越稠密,搜索结果更准确但效率降低。
算法总结
-
该算法的核心是通过随机遍历点集,并结合贪心搜索和修剪策略,生成一个稀疏有向图,图中的每个节点表示一个数据点,边表示近邻关系。贪心搜索负责找到潜在的近邻,而修剪则确保图的稀疏性,控制每个节点的最大出度。
-
参数 α α α、 L L L 和 R R R 的选择对图的结构和搜索性能影响很大。 α α α 控制图的稠密性, L L L 控制搜索的广度,而 R R R 控制每个节点的最大出度。
详细解释:Filtered Vamana Indexing Algorithm
该算法用于在近似最近邻(ANN)问题中生成一个图索引结构。索引结构是一个稀疏的有向图,通过控制节点的出度来优化最近邻搜索的效率。以下是该算法的详细解释,包括每个步骤的作用以及参数的含义。
输入参数
- P P P:点集,包含 n n n 个点,每个点 x i x_i xi 具有坐标信息 x i x_i xi。
- α α α:修剪时的阈值,影响节点的出度控制(影响候选邻居的保留策略,越大则图更稠密)。
- L L L:搜索深度,用于贪心搜索过程中,控制在搜索阶段探查的节点数量。
- R R R:图中每个节点的最大出度,控制最终生成的图的稀疏性,即每个节点最多有 R R R 个出度。
输出
- G G G:有向图,顶点为点集中的点,边表示点之间的近邻关系。该图每个节点的出度最多为 R R R。
算法步骤
1. 初始化(步骤1-5)
-
Step 1: 初始化图 G G G 为一个空图。此图将用于存储点与点之间的近邻关系。
-
Step 2: 找到数据集 P P P 的“中位点”(Medoid),记为 s s s。中位点在一定程度上是点集的中心点,可以用于快速搜索。
-
Step 3: 对于每个过滤标签 f ∈ F f \in F f∈F,确定初始节点 s t ( f ) st(f) st(f)。每个过滤标签可能代表数据集中的一个特定子集或维度子空间,该子空间有助于更高效地进行贪心搜索。
-
Step 4: 将点集的索引进行随机排列,生成一个随机排列 σ \sigma σ。通过随机排列,避免因数据顺序带来的偏差,使得图的生成过程更均匀。
-
Step 5: 为点集中的每个点分配一个过滤标签集 F x F_x Fx。该标签集可以是基于点特征或者聚类结果的分组,用于后续的贪心搜索和修剪过程。
2. 遍历点集 P P P(步骤6-14)
进入主循环,遍历每个点。对于每个点 i ∈ [ n ] i \in [n] i∈[n],按照随机排列 σ ( i ) \sigma(i) σ(i) 的顺序依次处理每个点,执行以下步骤:
2.1 搜索近邻(步骤7-9)
-
Step 7: 根据标签集 F σ ( i ) F_{\sigma(i)} Fσ(i) 找到与当前点 σ ( i ) \sigma(i) σ(i) 相关的子集 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i)。这些点作为贪心搜索的起始点。通常, S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i) 包含满足特定过滤条件的点集。
-
Step 8: 调用
FilteredGreedySearch
算法在集合 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i) 中执行贪心搜索,以寻找当前点 σ ( i ) \sigma(i) σ(i) 的候选近邻集 V F σ ( i ) \mathcal{V}_{F_{\sigma(i)}} VFσ(i)。贪心搜索使用起始点 S F σ ( i ) S_{F_{\sigma(i)}} SFσ(i),以 x σ ( i ) x_{\sigma(i)} xσ(i) 作为搜索目标,搜索深度为 L L L。- L L L:表示搜索的深度,即在贪心搜索过程中,允许探查的点的数量。如果 L L L 较大,搜索将更广泛,但效率降低;如果 L L L 较小,搜索可能会遗漏一些潜在的近邻。
-
Step 9: 更新当前点的候选近邻集 V \mathcal{V} V,即将新的候选集 V F σ ( i ) \mathcal{V}_{F_{\sigma(i)}} VFσ(i) 合并到 V \mathcal{V} V 中。
2.2 修剪邻居集合(步骤10)
-
Step 10: 调用
FilteredRobustPrune
对当前点 σ ( i ) \sigma(i) σ(i) 进行修剪,保留那些更相关的近邻,删除不必要的远邻。参数 α \alpha α 和 R R R 用于控制修剪过程:-
R R R:表示每个节点的最大出度,如果当前点的候选邻居集超过 R R R,需要对邻居进行修剪,确保图的稀疏性。
-
α α α:修剪时的阈值,影响候选邻居的保留策略,决定是否保留某些边。如果 α α α 较大,则更多的远邻会被保留,生成的图会较为稠密;如果 α α α 较小,图会更加稀疏。
-
2.3 更新邻居关系(步骤11-14)
-
Step 11-12: 对每个已经确定的近邻 j ∈ N o u t ( σ ( i ) ) j \in N_{out}(\sigma(i)) j∈Nout(σ(i)),更新邻居集 N o u t ( j ) N_{out}(j) Nout(j),即将节点 σ ( i ) \sigma(i) σ(i) 加入到 j j j 的邻居集中。
-
Step 13-14: 如果某个近邻 j j j 的邻居数超过了最大限制 R R R,则再次调用
FilteredRobustPrune
对该节点进行修剪,确保其邻居数不超过 R R R。
参数说明
- P P P:点集,包含 n n n 个点,每个点 x i x_i xi 表示其坐标。
- α α α:修剪的阈值,用于决定哪些候选邻居需要被裁剪。 α α α 越大,图的稠密度越高,近邻关系越强; α α α 越小,图越稀疏。
-
L
L
L:搜索深度,用于
FilteredGreedySearch
,决定搜索过程中探查的点的数量。 L L L 越大,搜索范围越广,找到的近邻越多,但效率下降。 - R R R:图中每个节点的最大出度,用于控制图的稀疏性。 R R R 越小,图越稀疏; R R R 越大,图越稠密,搜索结果更准确但效率降低。
算法总结
-
该算法的核心是通过随机遍历点集,并结合贪心搜索和修剪策略,生成一个稀疏有向图,图中的每个节点表示一个数据点,边表示近邻关系。贪心搜索负责找到潜在的近邻,而修剪则确保图的稀疏性,控制每个节点的最大出度。
-
参数 α α α、 L L L 和 R R R 的选择对图的结构和搜索性能影响很大。 α α α 控制图的稠密性, L L L 控制搜索的广度,而 R R R 控制每个节点的最大出度。
StitchedVamana Indexing Algorithm
算法简介
StitchedVamana Indexing Algorithm 是一种用于构建基于数据点的图结构的算法,主要用于加速近邻搜索。该算法通过构建多个局部图并将它们融合在一起,以得到一个全局的稀疏图,从而实现高效的索引和搜索。
输入与输出
-
输入:
- 数据集 P P P:包含 n n n 个数据点的集合,数据点 x i x_i xi 表示第 i i i 个数据点的坐标。
- 标签集 F F F:用于划分数据集中不同类别的标签集合。
- 参数 α , R small , R small , R stitched \alpha, R_{\text{small}}, R_{\text{small}}, R_{\text{stitched}} α,Rsmall,Rsmall,Rstitched:控制算法的参数,详见下文。
-
输出:
- 有向图 G G G,顶点集合为 P P P,且每个顶点的出度小于等于 R stitched R_{\text{stitched}} Rstitched。
算法步骤
-
初始化:
- 初始化一个空图 G = ( V , E ) G = (V, E) G=(V,E)。
- 对于每一个数据点 x ∈ P x \in P x∈P,定义其标签集为 F x F_x Fx,并将每个标签 f ∈ F f \in F f∈F 对应的点集合记作 P f ⊆ P P_f \subseteq P Pf⊆P。
-
构建局部图:
- 遍历所有标签 f ∈ F f \in F f∈F。
- 对每个标签对应的数据集 P f P_f Pf,使用 Vamana 算法构建局部图 G f G_f Gf,图构建的参数为 α , R small , R small \alpha, R_{\text{small}}, R_{\text{small}} α,Rsmall,Rsmall。
- 其中,Vamana 算法是一种用于构建近邻图的算法,通过指定每个节点的连接数(出度),实现稀疏图的构建。
-
融合局部图:
- 对于每个构建完成的局部图中的顶点 v ∈ V v \in V v∈V,进行进一步融合。
- 使用
FilteredRobustPrune(v, N_{\text{out}}(v), \alpha, R_{\text{stitched}})
函数对顶点 v v v 的出边进行修剪,确保图 G G G 的整体结构满足出度限制。
过滤和修剪规则
在算法的最后部分,通过三元组修剪的方式进一步优化边集合。具体规则如下:
-
对于任意三个顶点 a , b , c a, b, c a,b,c 和常数 α ≥ 1 \alpha \geq 1 α≥1,如果满足以下条件,边 ( a , c ) (a, c) (a,c) 可以被修剪:
- 边 ( a , b ) (a, b) (a,b) 存在。
- 向量
x
b
x_b
xb 到
x
c
x_c
xc 的距离显著小于
x
a
x_a
xa 到
x
c
x_c
xc 的距离,即
∥ x b − x c ∥ < 1 α ∥ x a − x c ∥ \| x_b - x_c \| < \frac{1}{\alpha} \| x_a - x_c \| ∥xb−xc∥<α1∥xa−xc∥ - F b F_b Fb 包含 F a F_a Fa 和 F c F_c Fc 的所有公共标签,即 F a ∩ F c ⊆ F b F_a \cap F_c \subseteq F_b Fa∩Fc⊆Fb。
-
最后,添加反向边:对于每个点 y ∈ N out ( x ) y \in N_{\text{out}}(x) y∈Nout(x),如果其出度大于 R R R,再次对点 y y y 运行
FilteredRobustPrune
过程。
算法参数详解
- P P P:包含所有数据点的集合。
- F F F:标签集合,用于划分数据点所属的不同类别。
- α \alpha α:控制边的修剪规则中的距离比例,通常用于定义节点间的“紧密”程度。
- R small R_{\text{small}} Rsmall:用于构建局部图的最大出度。
- R stitched R_{\text{stitched}} Rstitched:最终全局图的最大出度。
算法直观理解
该算法通过先划分数据集,构建多个局部稀疏图,然后通过修剪和融合的步骤将这些局部图合并为一个全局的图。这个过程旨在提高图的质量,减少图的密度,并保留必要的边,使得整体搜索性能更高效。
- 局部构图:通过 Vamana 算法对每个标签的子集进行独立构图,确保每个子图的稀疏性。
- 融合修剪:在融合过程中通过特定规则进行边的修剪,以去掉冗余的边,最终得到的图更加紧凑,适合近邻搜索的任务。
这种方式能够在多类数据分布的情况下,有效地构建出一张稀疏且高效的图结构。