Алгоритм для нахождения изоморфного множества подстановок

У меня есть массив множеств перестановок, и я хочу удалить изоморфные перестановки.

У нас есть S множества перестановок, где каждый набор содержит подстановки K, и каждая перестановка представляется как и массив элементов N. Я сохраняю его как массив int pset[S][K][N], где S, K и N фиксированы, а N больше K.

Два набора перестановок A и B являются изоморфными, если существует перестановка P, которая преобразует элементы из A в B (например, если A является элементом множества A, то P(a) является элементом множества B). В этом случае мы можем сказать, что P делает A и B изоморфным.

Мой текущий алгоритм:

  • Выберем все пары s1 = pset[i] и s2 = pset[j], такие, что i < j
  • Каждый элемент из выбранных множеств (s1 и s2) числится от 1 до K. Это означает, что каждый элемент может быть представлен как s1[i] или s2[i], где 0 < i < K+1
  • Для каждой подстановки T элементов K мы делаем следующее:
    • Найдите перестановку R, такую, что R(s1[1]) = s2[1]
    • Проверьте, является ли R перестановка, которая делает изоляцию s1 и T(s2), где T(s2) является перестановкой элементов (перестановок) множества s2, поэтому в основном мы просто проверяем, если R(s1[i]) = s2[T[i]], где 0 < i < K+1
    • Если нет, то переходим к следующей перестановке T.

Эти алгоритмы работают очень медленно: O(S^2) для первого шага, O(K!), чтобы перебрать каждую перестановку T, O(N^2), чтобы найти R и O(K*N), чтобы проверить, что R является перестановкой, которая делает s1 и s2 изоморфной - так что это O(S^2 * K! * N^2).

Вопрос: Можем ли мы сделать это быстрее?

Ответы

Ответ 1

Для этого есть очень простое решение: транспонирование.

Если два множества изоморфны, это означает, что существует взаимно однозначное отображение, где множество всех чисел в индексе i в наборе S1 равно множеству всех чисел в некотором индексе k в наборе S2. Моя гипотеза состоит в том, что никакие два неизоморфных множества не обладают этим свойством.

(1) Пример Жана Логейта:

0: [[1,2,3],[3,2,1]]
1: [[2,3,1],[1,3,2]]
2: [[1,2,3],[2,3,1]]
3: [[3,2,1],[1,2,3]]

Perform ONE pass:

Transpose, O(n):
0: [[1,3],[2,2],[3,1]]

Sort both in and between groups, O(something log something):
0: [[1,3],[1,3],[2,2]]

Hash:
"131322" -> 0

...
"121233" -> 1
"121323" -> 2
"131322" -> already hashed.

0 and 3 are isomorphic.

(2) встречный пример vsoftco в своем комментарии к Жану Логейту:

A = [ [0, 1, 2], [2, 0, 1] ]
B = [ [1, 0, 2], [0, 2, 1] ]

"010212" -> A
"010212" -> already hashed.

A and B are isomorphic.

Вы можете превратить каждый набор в транспонированную сортированную строку или хеш или любой другой сжатый объект для сравнения по линейному времени. Заметим, что этот алгоритм рассматривает все три набора A, B и C как изоморфные, даже если один p преобразует A в B, а другой p преобразует A в C. Ясно, что в этом случае существует p для преобразования любого из этих трех множеств в другое, поскольку все, что мы делаем, перемещает каждый i в одном наборе в конкретный k в другой. Если, как вы заявили, ваша цель - "удалить изоморфные перестановки", вы все равно получите список удаляемых наборов.

Пояснение:

Предположим, что наряду с нашим отсортированным хешем мы сохранили запись о том, из какой перестановки вышла каждая из i. Пример противодействия vsoftco:

010212  // hash for A and B
100110  // origin permutation, set A
100110  // origin permutation, set B

Чтобы подтвердить изоморфизм, нам нужно показать, что i, сгруппированные по каждому индексу из первого набора, переместились в некоторый индекс во втором наборе, причем этот индекс не имеет значения. Сортировка групп i не отменяет решение, а служит для подтверждения перемещения/перестановки между наборами.

Теперь по определению каждое число в хеше и каждое число в каждой группе в хеше представлено в перестановке начала ровно один раз для каждого набора. Однако мы решили упорядочить числа в каждой группе i в хэше, мы гарантируем, что каждое число в этой группе представляет собой другую перестановку в множестве; и в тот момент, когда мы теоретически присваиваем это число, мы гарантируем, что он "зарезервирован" только для этой перестановки и индекса. Для данного числа, скажем 2, в двух хэшах нам гарантируется, что он исходит из одного индекса и перестановки в наборе A, а во втором хеш соответствует один индекс и перестановка в наборе B. Это все, что нам действительно нужно показать, - что число в одном индексе для каждой перестановки в одном наборе (группа различных i 's) попадает в один индекс только в другом наборе (группа различных k') с). Какая перестановка и индекс, к которому принадлежит номер, не имеют значения.

Помните, что любое множество S2, изоморфное множеству S1, может быть получено из S1 с использованием одной функции перестановки или различных комбинаций различных функций перестановок, применяемых к членам S1. То, что на самом деле представляет сортировка или переупорядочение наших чисел и групп, - это перестановка, которую мы выбираем как решение изоморфизма, а не фактическое присвоение того числа, из которого пришел индекс и перестановка. Здесь снова встречный пример vsoftco, на этот раз мы добавим начальные индексы наших хэшей:

110022 // origin index set A
001122 // origin index set B

Поэтому наш permutation, решение для изоморфизма:

enter image description here

Или, чтобы:

enter image description here

(Обратите внимание, что в примере Жана Лойарта существует более одного решения изоморфизма.)

Ответ 2

Вы можете сортировать и сравнивать:

// 1 - sort each set of permutation
for i = 0 to S-1
    sort(pset[i])
// 2 - sort the array of permutations itself
sort(pset)
// 3 - compare
for i = 1 to S-1 {
    if(areEqual(pset[i], pset[i-1]))
        // pset[i] and pset[i-1] are isomorphic
}

Конкретный пример:

0: [[1,2,3],[3,2,1]]
1: [[2,3,1],[1,3,2]]
2: [[1,2,3],[2,3,1]]
3: [[3,2,1],[1,2,3]]

После 1:

0: [[1,2,3],[3,2,1]]
1: [[1,3,2],[2,3,1]] // order changed
2: [[1,2,3],[2,3,1]]
3: [[1,2,3],[3,2,1]] // order changed

После 2:

2: [[1,2,3],[2,3,1]]
0: [[1,2,3],[3,2,1]]
3: [[1,2,3],[3,2,1]] 
1: [[1,3,2],[2,3,1]]

После 3:

(2, 0) not isomorphic 
(0, 3) isomorphic
(3, 1) not isomorphic

Как насчет сложности?

  • 1 O(S * (K * N) * log(K * N))
  • 2 O(S * K * N * log(S * K * N))
  • 3 O(S * K * N)

Таким образом, общая сложность O(S * K * N log(S * K * N))

Ответ 3

Возьмите a0 в A. Затем найдите его обратным (быстрым, O(N)), назовите его a0inv. Затем выберите i в B и определите P_i = b_i * ainv и убедитесь, что P_i * a генерирует B при изменении A над A. Сделайте это для каждого i в B. Если вы не найдете никакого i, для которого выполняется соотношение, то множества не изоморфны. Если вы найдете такой i, то множества изоморфны. Время выполнения O(K^2) для каждой пары проверяемых наборов, и вам нужно будет проверить набор O(S^2), поэтому вы получите O(S^2 * K^2 * N).

PS: Я предположил, что под "отображением А в В" вы подразумеваете отображение под композицией перестановок, поэтому P(a) на самом деле является перестановкой P, состоящей из перестановки A, и я использовал тот факт, что если P является перестановкой, то должно существовать a i, для которого Pa = b_i для некоторого A.

EDIT Я решил отменить свой ответ, поскольку я не уверен, что предыдущий (@Jean Logeart) на основе поиска правильный. Если да, я с удовольствием удалю мое, потому что он работает хуже, но я думаю, что у меня есть контрпример, см. Комментарии ниже ответа Жана.

Ответ 4

Предположим, что два элемента s1, s2\in S изоморфны. Тогда, если p1 и p2 являются перестановками, то s1 изоморфно s2, если p1 (s1) изоморфно p2 (s2), где pi (si) - множество подстановок, полученных применением pi к каждому элементу из si.

Для каждого я из 1... s и j в 1... k, выберем j-й элемент si и найдем перестановку, которая изменит ее на единицу. Примените его ко всем элементам si. Перемешиваем каждую из k перестановок на число, получая k чисел, для любого выбора я и j по стоимости nk.

Сравнение хешированных множеств для двух разных значений я и j равно k ^ 2 < пк. Таким образом, вы можете найти набор совпадений кандидатов по цене s ^ 2 k ^ 3 n. Если фактическое количество совпадений невелико, общая сложность намного ниже того, что вы указали в своем вопросе.

Ответ 5

Чтобы проверить, являются ли два набора S₁ и S₂ изоморфными, вы можете сделать гораздо более короткий поиск.

Если они изоморфны, то существует перестановка t, которая отображает каждый элемент S₁ в элемент S₂; для поиска t вы можете просто выбрать любой фиксированный элемент p S₁ и рассмотреть перестановки

 t₁ = (1/p) q₁
 t₂ = (1/p) q₂
 t₃ = (1/p) q₃
 ...

для всех элементов q S₂. Ибо, если существует допустимый t, то он должен отображать элемент p в элемент S₂, поэтому только перестановки отображения p к элементу S₂ являются возможными кандидатами.

Кроме того, если у вас есть кандидат t, чтобы проверить, равны ли два набора перестановок S₁t и S₂, вы можете использовать хэш, вычисленный как x -или хэш-кода для каждого элемента, выполняя полную проверку всех перестановок, только если хеш соответствует.