Лучшая структура данных для ближайшего соседа в 1 размере

У меня есть список (1-мерных) значений, и я хотел бы знать лучшую структуру данных / алгоритм для нахождения ближайшего к значению запроса, которое я имею. Большинство решений (все?) Я нашел для вопросов, вот для 2 или больше размеров. Кто-либо может предложить мне подход для моего случая?

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

9
задан Muhammad Alkarouri 18 July 2010 в 18:07
поделиться

5 ответов

Если вам нужно что-то быстрее, чем O(log(n)), что вы можете легко получить с помощью сортированного массива или дерева двоичного поиска, вы можете использовать дерево ван Эмде-Боаса. Деревья vEB дают вам O(log(log(log(n))) для поиска ближайшего элемента с каждой стороны.

9
ответ дан 4 December 2019 в 15:11
поделиться

Если время вставки не имеет значения, тогда двоичный поиск в отсортированном массиве - это самый простой способ добиться времени запроса O (log N). Каждый раз, когда добавляется элемент, сортируйте все. Для каждого запроса выполните двоичный поиск. Если совпадение найдено, верните его. В противном случае двоичный поиск должен вернуть индекс элемента, в который он должен был быть вставлен. Используйте этот индекс, чтобы проверить два соседних элемента и определить, какой из них ближе к точке запроса.

Я полагаю, что есть решения с временем O (1). Я постараюсь придумать такой, который не требует слишком большого использования памяти ...

2
ответ дан 4 December 2019 в 15:11
поделиться

Отсортируйте список и используйте двоичный поиск, чтобы найти элемент, который вы ищете, затем сравните своих левых и правых соседей. Вы можете использовать массив с доступом O (1).

Что-то вроде:

int nearest(int[] list, int element) {

    sort(list);
    int idx = binarySearch(element, list);

    // make sure you are accessing elements that exist
    min = (element - list[idx-1] <= list[idx+1] - element) ? idx-1 : idx+1;

    return list[min];
}

Это O (n log n), которое будет амортизировано, если вы собираетесь выполнить много поисков.

РЕДАКТИРОВАТЬ: Для этого вам нужно переместить сортировку из этого метода

1
ответ дан 4 December 2019 в 15:11
поделиться

Как вы уже упоминали, самым быстрым и простым способом должна быть сортировка данных с последующим поиском левого и правого соседа точки данных.

1
ответ дан 4 December 2019 в 15:11
поделиться

Использование OCaml's Set :

module S = Set.Make(struct type t = int let compare = compare end)

let nearest xs y =
  let a, yisin, b = S.split y xs in
  if yisin then y
  else
      let amax, bmin = S.max_elt a, S.min_elt b in
      if abs (amax - y) < abs (bmin - y) then amax else bmin

Кстати, вы можете оценить мой образец nth-ближайшего соседа из OCaml for Scientists и The F #. NET Journal статья Обход сети: n-е ближайшие соседи .

0
ответ дан 4 December 2019 в 15:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: