Вычислительная разница между двумя большими наборами


14

У меня есть два больших наборов целых чисел A и . Каждый набор содержит около миллиона записей, и каждая запись представляет собой положительное целое число длиной не более 10 цифр. B

Каков наилучший алгоритм для вычисления и ? Другими словами, как я могу эффективно вычислить список записей , которых нет в и наоборот? Какова была бы лучшая структура данных для представления этих двух наборов, чтобы сделать эти операции эффективными?A∖BB∖AAB

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


Если вы хотите сохранить его по-другому, возможно, вы сможете добиться лучших результатов.
— Realz Slaw

Кроме того, если вы хотите получить результаты в виде неявной структуры данных; Вы можете просто создать такую ​​структуру, которая запрашивает два набора, чтобы ответить на каждый из его собственных запросов.
— Realz Slaw

1
@ user917279 Одна важная вещь: вы обычно можете компромиссировать время предварительной обработки / построения, время запроса и использование памяти друг с другом. Вы редактируете структуру редко, но часто запрашиваете? Наоборот? Память вызывает беспокойство или нет? На такие вопросы можно ответить с практической точки зрения и обосновать выбор «правильной» «теоретической» конструкции.
— Рафаэль

1
@ Рафаэль. Вы предлагаете сделать лучше, чем устойчивые наборы (с точки зрения сложности), используя больше памяти и / или тратя больше времени на подготовку. Мне просто любопытно, если вы думаете, что это возможно. Я не вижу таблицы поиска в качестве опции для входных наборов такого размера.
— смоссен

1
@ user917279 Если вы рассмотрите пример двух огромных наборов, которые идентичны, то любая структура данных, созданная с использованием хэширования, будет поддерживать проверку на равенство в O (1), так как равные структуры будут объединены при создании и, таким образом, будут использовать одну и ту же область памяти. Слитно-постоянные множества используют преимущества хэширования, когда две структуры почти равны. Сложность - лучшее, что я видел до сих пор для упорядоченных наборов.
— смоссен

Ответы:


9

Если вы хотите хранить наборы в специализированной структуре данных, вы можете получить некоторые интересные сложности.

Пусть I=O(min(|A|,|B|,|AΔB|))

Затем вы можете выполнять операции над множествами и A Δ B , каждая в O ( I ⋅ log | A | + | B |A∪B,A∩B,A∖BAΔBожидаемое время Таким образом, по существу, вы получаете минимальный размер двух наборов или размер симметричной разности, в зависимости от того, что меньше. Это лучше, чем линейное, если симметричная разница мала; то есть. если они имеют большое пересечение. Фактически, для двух требуемых операций разности множеств это практически чувствительно к выходу, поскольку вместе они составляют размер симметричной разности.О(я⋅журнал⁡|A|+|В|я)

См. Confluently Persistent Sets и Maps by Olle Liljenzin (2013) для получения дополнительной информации.


Трепа в газете - это упорядоченные деревья поиска. Я бы не считал их несортированными структурами данных.
— смоссен

@ Достаточно правдоподобно, я отредактировал это.
— Realz Slaw

6

Лучшее, что я знаю, это линейное сканирование, если наборы представлены в виде отсортированных связанных списков. Время работы .О(|A|+|В|)

AВО(|A|×|В|)

A∖ВAВ

difference(A, B):
    if len(B)=0:
        return A # return the leftover list
    if len(A)=0:
        return B # return the leftover list
    if A[0] < B[0]:
        return [A[0]] + difference(A[1:], B)
    elsif A[0] = B[0]:
        return difference(A[1:], B[1:])  # omit the common element
    else:
        return [B[0]] + difference(A, B[1:])

Я представлял это в псевдо-Python. Если вы не читаете Python, он A[0]является главой связанного списка A, A[1:]является остальной частью списка и +представляет собой объединение списков. По соображениям эффективности, если вы работаете в Python, вы, вероятно, не захотите реализовать его точно так же, как описано выше - например, может быть лучше использовать генераторы, чтобы избежать создания многих временных списков - но я хотел показать вам идеи в простейшей форме. Цель этого псевдокода - просто проиллюстрировать алгоритм, а не предложить конкретную реализацию.

AВAВ


фантастика, есть ли у нас другие варианты, если ограничение, что наборы должны быть сохранены как отсортированные списки, снято?
— user917279

2

Если A и B имеют одинаковый размер, непересекающиеся и чередующиеся (например, нечетные числа в A и четные числа в B), тогда парное сравнение элементов в линейном времени, вероятно, является оптимальным.

Если A и B содержат блоки элементов, которые находятся точно в одном из A или B или в обоих из них, можно вычислить разность множеств, объединение и пересечение за сублинейное время. Например, если A и B отличаются ровно одним элементом, то разницу можно вычислить в O (log n).

http://arxiv.org/abs/1301.3388


1
Он говорит, что наборы упорядочены, что может означать, что они хранятся в виде списков, деревьев поиска или чего-то еще. Если данные должны храниться в виде списков, совершенно неинтересно спрашивать «лучший алгоритм для вычисления AB», когда ни один алгоритм не может быть лучше, чем сканирование списков за линейное время (для которого он уже нашел алгоритм).
— смоссен

1
черт возьми, вы связали ту же бумагу, что и я (я, как и вы, скорее) ... назовите ваши ссылки в следующий раз: D
— Realz Slaw

@smossen фантастика, насколько я знаю (?), я представлял их в виде отсортированных списков, но смиренно приветствовал бы и другие предложения.
— user917279

2

NA-Вa∧б¯a,б


1010

1
Р., упускает суть. один longможет хранить 32 элемента или 1 byte, 8 элементов. Таким образом, 1М записи могут храниться только в ~ 125K RAM! хранилище может быть значительно более эффективным, чем другие представления, в зависимости от того, как реализована проблема ...
— vzn

Таким образом, вам понадобится более 12 МБ для наборов, которые интересует OP. Это уничтожает все кэши (в настоящее время) и будет ужасно для редких наборов. В частности, создание пустого набора доминирует над всеми другими операциями (для разреженных наборов). Кстати, Кнут решает эту проблему в TAoCP.
— Рафаэль

12MB? да? Плакат сказал, что у него есть только 2 комплекта. на постере не указывалось разреженности / плотности его набора. это указано в моем ответе. Вы предполагаете, что у него есть редкие наборы? Единого правильного ответа не существует, этот подход обозначен как альтернативный вариант, который может быть полезен в зависимости от обстоятельств. это не редкость в этом контексте ...
— vzn

10101061010б≈1,15граммВ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.