Как мне найти k-ближайшие значения в n-мерном пространстве?

Я читал о kd-деревьях, но они неэффективны, когда размерность пространства высока. У меня есть база данных значений, и я хочу найти значения, которые находятся в пределах определенного расстояния Хемминга запроса. Например, база данных представляет собой список 32-битных чисел, и я хочу найти все числа, которые отличаются от значения запроса менее чем на 3 бита.

Я где-то слышал о деревьях MultiVariate Partition, но не смог найти хорошую ссылку. Я знаю, что min-Hash дает хорошее приближение, лучше как, но я хотел бы получить точный ответ.

1 ответ

Расстояние Хемминга тесно связано с расстоянием Левенштейна и аналогично алгоритмам, используемым для исправления орфографии.

Метод, который работает, - это поиск по веткам и привязкам в дереве. Требуется время, которое экспоненциально по расстоянию, для ближнего расстояния, до того, чтобы быть линейным по размеру словаря.

Если словарь состоит из двоичных слов, хранящихся в двоичном коде, со строгим расстоянием Хэмминга, вот простой псевдокод:

walk(trie, word, i, hit, budget){
  if (budget < 0 || i > word.length) return;
  if (trie==NULL){
    if (i==word.length) print hit;
    return;
  }
  hit[i] = 0;
  walk(trie.subtrie[0], word, i+1, hit, (word[i]==0 ? budget : budget-1));
  hit[i] = 1;
  walk(trie.subtrie[1], word, i+1, hit, (word[i]==1 ? budget : budget-1));
}

main(){
  for (int budget = 0; ; budget++){
    walk(trie, word, 0, hit, budget);
    /* quit if enough hits have been printed */
  }
}

Идея состоит в том, что вы проходите всю последовательность операций, отслеживая расстояние между текущим узлом преобразования и исходным словом. Вы сокращаете поиск, имея бюджет, сколько расстояния вы будете терпеть. Это работает, потому что расстояние никогда не может уменьшаться, когда вы углубляетесь в дерево.

Затем вы делаете это многократно с бюджетами, начинающимися с нуля и постепенно увеличивающимися, пока не распечатаете нужные результаты. Поскольку каждая прогулка охватывает намного меньше узлов, чем последующая прогулка, не повредит, что вы делаете несколько прогулок. Если k исправлено, вы можете просто начать с этого как ваш бюджет.

Другие вопросы по тегам