Как найти неидентичные элементы из нескольких векторов?

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

Например, заданные множества a, b, c, d как:

a <- (1,3,5); 
b <- (3,6,8); 
c <- (2,3,4); 
d <- (2,4,6)

Я могу найти такие множества, как (1, 8, 4, 6) или (3, 6, 2, 4)..... на самом деле, мне нужно только выяснить один такой набор, чтобы доказать существование.

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

Есть ли более умные способы? Спасибо!

Ответы

Ответ 1

Вы можете переформулировать свою проблему как совпадение в двудольном графе:

  • node левой стороны - ваши наборы,
  • node правой части - это целое число, входящее в набор.

Существует край между "набором" node и "integer" node, если набор содержит заданное целое число. Затем вы пытаетесь найти соответствие в этом двудольном графе: каждый набор будет связан с одним целым числом, и целое число не будет использоваться дважды. Время работы простого алгоритма для нахождения такого соответствия - O (| V || E |), здесь | V | меньше (m + 1) k и | E | равна mk. Итак, у вас есть решение в O (m ^ 2 k ^ 2). См. Соответствие в двухсторонних графиках.

Алгоритм двухстороннего сопоставления:

Алгоритм работает на ориентированных графах. В начале все ребра ориентированы слева направо. Два узла будут сопоставляться, если граница между ними ориентирована справа налево, поэтому в начале совпадение пуст. Цель алгоритма - найти "пути расширения" (или чередующиеся пути), то есть пути, которые увеличивают размер соответствия.

Путь расширения - это путь в ориентированном графе, начинающийся с непревзойденного левого node и заканчивающийся с непревзойденным правом node. Когда у вас есть путь увеличения, вам просто нужно перевернуть все грани вдоль пути до одного приращения размера соответствия. (Размер совпадения будет увеличен, потому что у вас есть еще одно ребро, не принадлежащее к совпадению. Это называется чередующимся путем, потому что путь чередуется между ребрами, не принадлежащими сопоставлению слева направо, и ребрами, принадлежащими сопоставлению, справа налево.)

Вот как вы находите путь расширения:

  • все узлы отмечены как невидимые,
  • вы выбираете невидимый и непревзойденный левый node,
  • Вы делаете глубину первого поиска, пока не найдете непревзойденный правый node (тогда у вас есть путь увеличения). Если вы не можете найти непревзойденное право node, вы перейдете к 2.

Если вы не можете найти путь расширения, то оптимальное совпадение.

Поиск пути дополнений имеет сложность O (| E |), и вы делаете это не более min (k, m) раз, так как размер наилучшего соответствия ограничен k и m. Таким образом, для вашей проблемы сложность будет равна O (mk min (m, k)).

Вы также можете увидеть эту ссылку, раздел 1., для более полного объяснения с доказательствами.