我有一组排列,我想删除同构排列。
We have
S
sets of permutations, where each set containK
permutations, and each permutation is represented as and array ofN
elements. I'm currently saving it as an arrayint pset[S][K][N]
, whereS
,K
andN
are fixed, and N is larger than K.Two sets of permutations,
A
andB
, are isomorphic, if there exists a permutationP
, that converts elements fromA
toB
(for example, ifa
is an element of setA
, thenP(a)
is an element of setB
). In this case we can say thatP
makesA
andB
isomorphic.
我目前的算法是:
- 我们选择所有对
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)
.
Question: Can we make it faster?
最佳答案
您可以排序和比较:
// 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))
关于c++ - 寻找同构排列集的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30175183/