-
Notifications
You must be signed in to change notification settings - Fork 0
Some notes regarding Permutation Groups
- Permutation Groups #
- Preliminaries ##
Multiplication of two permutations, say, \(\alpha\) and \(\beta\) are defined by function composition that is (\(\alpha\)\(\beta\))(x) = \(\alpha\)(\(\beta\) x)
Thus we can see that composition of two permutations is again a permutation.
- Some basic algorithms ##
- Algorithm 1 ###
- Some basic algorithms ##
- MULT(n, \(\alpha\), \(\beta\), \(\gamma\)) ####
1. *do* \(\pi_{0}\)[i] \(\Leftarrow\) \(\alpha\)[\(\beta\)[i]]
2. *for* i \(\Leftarrow\) 0 to n-1
1. *do* \(\gamma\)[i] \(\Leftarrow\) \(\pi_{0}\)[i]
Note that we use an auxiliary permutation here to prevent bugs arising because of modifications to the arrays \(\alpha\) & \(\beta\)
- Algorithm 2 ###
- INV(n, \(\alpha\),) ####
1. *do* \(\beta\)[\(\alpha\)[i]] \(\Leftarrow\) i
- Algorithm 3 ###
CYCLE_TO_ARRAY (n, C)
1. *for* i \(\Leftarrow\) 0 to n-1
1. *do* \(A\)[i]] \(\Leftarrow\) i
2. i \(\Leftarrow\) i 3. Set l to be the length of string C 4. *while* i < l:
1. if C[i] = "(" then: 1. i \(\Leftarrow\) i + 1 2. *if* C[i] \(\in\) {0, 1, ..., 9} then: 1. Get x starting at i 2. z \(\Leftarrow\) y 3. Increment i to the position after x 2. if C[i] = "," 1. i \(\Leftarrow\) i + 1 2. *if* C[i] \(\in\) {0, 1, ..., 9} then: 1. Get y starting at i 2. A[z] \(\leftarrow\) y 3. Increment i to the position after y 4. x \(\Leftarrow\) y 3. if C[i] = ")" 1. A[x] \(\Leftarrow\) z 2. i \(\Leftarrow\) i + 1
Similarly, we can construct an algorithm to convert an array to a cycle.
- Data structure to store a group ##
Now, suppose we store a group as a list of lexicographically arranged permutations then we can observe a few things.
1. The space complexity in the worst case is n! 2. Testing membership using binary search is O(\(n^2\) \(\log(n)\)) 3. Generating elements takes O(1) time
Alternatively, we can just store the generators. Enumeration of elements will then involve products in the generators of length one, length two and so on. We cross out duplicates as and when we need to.
- Algorithm 4 ###
- SIMPLE_GEN (n, \(\tau\)) ####
1. \(G \) \(\Leftarrow\) \(G \) \(\cup\) New 2. Last \(\Leftarrow\) New 3. New \(\Leftarrow\) \(\phi\) 4. *for each* g \(\in\) \(\tau\) 1. *for each* h \(\in\) Last 1. MULT (n, g, h, f) 2. if f \(\notin\) \(G \) then New \(\Leftarrow\) {f} \(\cup\) New
This algorithm is not very efficient though for generating members, although it is very useful for storing the members of a group.
- Schreier Sims algorithm ##
Write orb(0) = { \(x_{0,1}\) , \(x_{0,2}\) .., \(x_{0,n_{0}}\) } and for some i, choose some \(h_{0,i}\) \(\in\) \(G\) such that \(h_{0,i}\) = \(x_{0,i}\).
We now set \(U_{0}\) = {\(h_{0,1}\), \(h_{0,2}\) .., \(h_{0 ,n_{0}}\) }
- Theorem*: Let \(G\), \(U_{0}\) and \(G_{0}\) be defined as above. Then \(U_{0}\) is a left transversal of \(G_{0}\) in \(G\). A left transversal is a left coset representation of a group.
- Algorithm 5 ###
- RUN(n, G, USE()) ####
1. if DoneEarly then return 2. if l = n 1. then USE(n, g) 3. else 1. *for each* h \(\in\) \(U_{l}\) 1. MULT(n, g, h, \(f_{l}\) 2. RUN_BACKTRACK(n, l + 1, G, \(f_{l}\), USE())
3. main
1. RUN_BACKTRACK(0, G, I, USE())
Testing for representation is also simple once we have the transversals.
- Algorithm 6 ###
- TEST(n, g, G = [\(U_{1}\),]) ####
1. x \(\Leftarrow\) g[i] 2. if there exists an h \(\in\) \(U_{i}\) such that h(i) = x 1. INV(n, h, \(\pi_{2}\)) 2. MULT(n, \(\pi_{2}\), g, \(\pi_{3}\)) 3. for j \(\Leftarrow\) 0 to n-1 1. do g[j] \(\Leftarrow\) \(\pi_{3}\)[j] 3 else return i
2 return n
If i < n is returned then the following condition is observed:
(\(f^{-1}\)\(g\))(x) = x for all x < i and (\(f^{-1} g\))(i) = j but there is no h \(\in\) \(U_{i}\) such that h(i) = j
Now we just need to specify the algorithm required to generate the transversals.
- Algorithm 7 ###
- GEN(n, \(\tau\)) ####
1. i \(\Leftarrow\) TEST(n, g, G = [\(U_{1}\), \(U_{2}\) .., \(U_{n-1}\) ]) 2. if i = n then return 3. else \(U_{i}\) \(\Leftarrow\) \(U_{1}\) \(\cup\) {g} 4. *for* j \(\Leftarrow\) i to n - 1 1. *for each* h \(\in\) \(U_{j}\) 1. MULT(n, h, g, f) 2. ENTER(n, f, G = [\(U_{1}\), \(U_{2}\) .., \(U_{n-1}\)])
2. *for* i \(\Leftarrow\) 0 to n - 1
1. do \(U_{i}\) \(\Leftarrow\) {I}
3. *for each* \(\alpha\) \(\in\) \(\tau\)
1. do ENTER(n, \(\alpha\), G = [\(U_{1}\), \(U_{2}\) .., \(U_{n-1}\)])
4. return G = [\(U_{1}\),]