Постоянный Союз-Найти со случайным удалением - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть набор из полумиллиона предметов, хранящихся в базе данных, и мне нужны следующие операции:

  • union(x, y), как в Union-Find
  • findAll(x) поиск всех y таких, что find(x) == find(y)
  • ununion(x, y) возврат прежней операции объединения

Это практическая проблема, для которой известно следующее

  • Обычно разделы будут небольшими (менее 100 элементов), но нет никакой гарантии.
  • Скорость работы union не имеет большого значения.
  • findAll должен быть быстрым и должен быть реализован в SQL (без рекурсии / CONNECT BY).
  • Иногда мы обнаруживаем, что некоторые union были действительно неправильными и нужно отменить их,сохраняя все предыдущие и последующие union с.Эта операция достаточно редка, поэтому скорость не имеет значения.
  • Нет необходимости, чтобы findAll немедленно видел изменения, сделанные другими операциями.Некоторая постобработка была бы в порядке.

Классический алгоритм Union-Find требует сжатия пути (или варианта) для эффективности и не позволяет удалять ребра (даже без сжатия пути).Мне известно о Динамическое подключение , но оно выглядит неприменимым для моего варианта использования.

Я думаю, мы не можем его использовать, так как скорость findAllсамое важное.Вероятно, нам следует напрямую связать все узлы с корнем.

Что касается ununion, моя единственная идея - хранить все операции union отдельно, а на ununion удалить все ссылки из соответствующего раздела иповторить все связанные union s.

Звучит довольно грубо, как ...


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

1 Ответ

0 голосов
/ 16 декабря 2018

Я бы порекомендовал вам создать хеш-функцию для наборов и хранить ее с каждым x в базе данных в индексированном столбце.При построении union(x, y) вы можете вычислить новое значение хеша и сохранить его.На findAll использование этого индекса означает, что вы будете сравнивать только наборы с высокой вероятностью совпадения, что делает его достаточно быстрым.И в поиске нет ничего фантастического, так что вы можете разумно реализовать его в наивном SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...