mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-11 15:16:54 +08:00
Added support for adaptive beam search [skip ci]
This commit is contained in:
@@ -1282,6 +1282,7 @@ Thanks to:
|
|||||||
- [k-means++: The Advantage of Careful Seeding](https://theory.stanford.edu/~sergei/papers/kMeansPP-soda.pdf)
|
- [k-means++: The Advantage of Careful Seeding](https://theory.stanford.edu/~sergei/papers/kMeansPP-soda.pdf)
|
||||||
- [Concept Decompositions for Large Sparse Text Data using Clustering](https://www.cs.utexas.edu/users/inderjit/public_papers/concept_mlj.pdf)
|
- [Concept Decompositions for Large Sparse Text Data using Clustering](https://www.cs.utexas.edu/users/inderjit/public_papers/concept_mlj.pdf)
|
||||||
- [Efficient and Robust Approximate Nearest Neighbor Search using Hierarchical Navigable Small World Graphs](https://arxiv.org/ftp/arxiv/papers/1603/1603.09320.pdf)
|
- [Efficient and Robust Approximate Nearest Neighbor Search using Hierarchical Navigable Small World Graphs](https://arxiv.org/ftp/arxiv/papers/1603/1603.09320.pdf)
|
||||||
|
- [Distance Adaptive Beam Search for Provably Accurate Graph-Based Nearest Neighbor Search](https://arxiv.org/pdf/2505.15636)
|
||||||
|
|
||||||
## History
|
## History
|
||||||
|
|
||||||
|
|||||||
@@ -829,6 +829,7 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in
|
|||||||
HnswUnvisited *unvisited = palloc(lm * sizeof(HnswUnvisited));
|
HnswUnvisited *unvisited = palloc(lm * sizeof(HnswUnvisited));
|
||||||
int unvisitedLength;
|
int unvisitedLength;
|
||||||
bool inMemory = index == NULL;
|
bool inMemory = index == NULL;
|
||||||
|
double lambda = 0.12;
|
||||||
|
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
{
|
{
|
||||||
@@ -884,7 +885,7 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in
|
|||||||
HnswSearchCandidate *f = HnswGetSearchCandidate(w_node, pairingheap_first(W));
|
HnswSearchCandidate *f = HnswGetSearchCandidate(w_node, pairingheap_first(W));
|
||||||
HnswElement cElement;
|
HnswElement cElement;
|
||||||
|
|
||||||
if (c->distance > f->distance)
|
if (c->distance > f->distance * (1 + lambda))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
cElement = HnswPtrAccess(base, c->element);
|
cElement = HnswPtrAccess(base, c->element);
|
||||||
@@ -904,8 +905,10 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in
|
|||||||
HnswSearchCandidate *e;
|
HnswSearchCandidate *e;
|
||||||
double eDistance;
|
double eDistance;
|
||||||
bool alwaysAdd = wlen < ef;
|
bool alwaysAdd = wlen < ef;
|
||||||
|
double fDistance;
|
||||||
|
|
||||||
f = HnswGetSearchCandidate(w_node, pairingheap_first(W));
|
f = HnswGetSearchCandidate(w_node, pairingheap_first(W));
|
||||||
|
fDistance = f->distance * (1 + lambda);
|
||||||
|
|
||||||
if (inMemory)
|
if (inMemory)
|
||||||
{
|
{
|
||||||
@@ -920,13 +923,13 @@ HnswSearchLayer(char *base, HnswQuery * q, List *ep, int ef, int lc, Relation in
|
|||||||
|
|
||||||
/* Avoid any allocations if not adding */
|
/* Avoid any allocations if not adding */
|
||||||
eElement = NULL;
|
eElement = NULL;
|
||||||
HnswLoadElementImpl(blkno, offno, &eDistance, q, index, support, inserting, alwaysAdd || discarded != NULL ? NULL : &f->distance, &eElement);
|
HnswLoadElementImpl(blkno, offno, &eDistance, q, index, support, inserting, alwaysAdd || discarded != NULL ? NULL : &fDistance, &eElement);
|
||||||
|
|
||||||
if (eElement == NULL)
|
if (eElement == NULL)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eElement == NULL || !(eDistance < f->distance || alwaysAdd))
|
if (eElement == NULL || !(eDistance < fDistance || alwaysAdd))
|
||||||
{
|
{
|
||||||
if (discarded != NULL)
|
if (discarded != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user